feat(plan): allow skills to be enabled in plan mode (#18817)

Co-authored-by: Jerop Kipruto <jerop@google.com>
This commit is contained in:
Adib234
2026-02-11 12:59:03 -05:00
committed by GitHub
parent b19b026f30
commit 84ce53aafa
4 changed files with 67 additions and 2 deletions

View File

@@ -30,6 +30,7 @@ implementation strategy.
- [The Planning Workflow](#the-planning-workflow)
- [Exiting Plan Mode](#exiting-plan-mode)
- [Tool Restrictions](#tool-restrictions)
- [Customizing Planning with Skills](#customizing-planning-with-skills)
- [Customizing Policies](#customizing-policies)
## Starting in Plan Mode
@@ -98,6 +99,28 @@ These are the only allowed tools:
`postgres_read_schema`) are allowed.
- **Planning (Write):** [`write_file`] and [`replace`] ONLY allowed for `.md`
files in the `~/.gemini/tmp/<project>/plans/` directory.
- **Skills:** [`activate_skill`] (allows loading specialized instructions and
resources in a read-only manner)
### Customizing Planning with Skills
You can leverage [Agent Skills](./skills.md) to customize how Gemini CLI
approaches planning for specific types of tasks. When a skill is activated
during Plan Mode, its specialized instructions and procedural workflows will
guide the research and design phases.
For example:
- A **"Database Migration"** skill could ensure the plan includes data safety
checks and rollback strategies.
- A **"Security Audit"** skill could prompt the agent to look for specific
vulnerabilities during codebase exploration.
- A **"Frontend Design"** skill could guide the agent to use specific UI
components and accessibility standards in its proposal.
To use a skill in Plan Mode, you can explicitly ask the agent to "use the
[skill-name] skill to plan..." or the agent may autonomously activate it based
on the task description.
### Customizing Policies
@@ -154,5 +177,6 @@ Guide].
[`google_web_search`]: /docs/tools/web-search.md
[`replace`]: /docs/tools/file-system.md#6-replace-edit
[MCP tools]: /docs/tools/mcp-server.md
[`activate_skill`]: /docs/cli/skills.md
[experimental research sub-agents]: /docs/core/subagents.md
[Policy Engine Guide]: /docs/core/policy-engine.md

View File

@@ -31,12 +31,12 @@
decision = "deny"
priority = 60
modes = ["plan"]
deny_message = "You are in Plan Mode - adjust your prompt to only use read and search tools."
deny_message = "You are in Plan Mode with access to read-only tools. Execution of scripts (including those from skills) is blocked."
# Explicitly Allow Read-Only Tools in Plan mode.
[[rule]]
toolName = ["glob", "grep_search", "list_directory", "read_file", "google_web_search"]
toolName = ["glob", "grep_search", "list_directory", "read_file", "google_web_search", "activate_skill"]
decision = "allow"
priority = 70
modes = ["plan"]

View File

@@ -2086,4 +2086,44 @@ describe('PolicyEngine', () => {
expect(result.decision).toBe(PolicyDecision.ALLOW);
});
});
describe('Plan Mode', () => {
it('should allow activate_skill but deny shell commands in Plan Mode', async () => {
const rules: PolicyRule[] = [
{
decision: PolicyDecision.DENY,
priority: 60,
modes: [ApprovalMode.PLAN],
denyMessage:
'You are in Plan Mode with access to read-only tools. Execution of scripts (including those from skills) is blocked.',
},
{
toolName: 'activate_skill',
decision: PolicyDecision.ALLOW,
priority: 70,
modes: [ApprovalMode.PLAN],
},
];
engine = new PolicyEngine({
rules,
approvalMode: ApprovalMode.PLAN,
});
const skillResult = await engine.check(
{ name: 'activate_skill', args: { name: 'test' } },
undefined,
);
expect(skillResult.decision).toBe(PolicyDecision.ALLOW);
const shellResult = await engine.check(
{ name: 'run_shell_command', args: { command: 'ls' } },
undefined,
);
expect(shellResult.decision).toBe(PolicyDecision.DENY);
expect(shellResult.rule?.denyMessage).toContain(
'Execution of scripts (including those from skills) is blocked',
);
});
});
});

View File

@@ -108,6 +108,7 @@ export const PLAN_MODE_TOOLS = [
LS_TOOL_NAME,
WEB_SEARCH_TOOL_NAME,
ASK_USER_TOOL_NAME,
ACTIVATE_SKILL_TOOL_NAME,
EXIT_PLAN_MODE_TOOL_NAME,
] as const;