mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-10 22:21:22 -07:00
feat(plan): allow skills to be enabled in plan mode (#18817)
Co-authored-by: Jerop Kipruto <jerop@google.com>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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',
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user