From 84ce53aafab4374fb3cd24de49f10624fa56cbad Mon Sep 17 00:00:00 2001 From: Adib234 <30782825+Adib234@users.noreply.github.com> Date: Wed, 11 Feb 2026 12:59:03 -0500 Subject: [PATCH] feat(plan): allow skills to be enabled in plan mode (#18817) Co-authored-by: Jerop Kipruto --- docs/cli/plan-mode.md | 24 +++++++++++ packages/core/src/policy/policies/plan.toml | 4 +- .../core/src/policy/policy-engine.test.ts | 40 +++++++++++++++++++ packages/core/src/tools/tool-names.ts | 1 + 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/docs/cli/plan-mode.md b/docs/cli/plan-mode.md index 105e5aa5e7..0fe46698c9 100644 --- a/docs/cli/plan-mode.md +++ b/docs/cli/plan-mode.md @@ -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//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 diff --git a/packages/core/src/policy/policies/plan.toml b/packages/core/src/policy/policies/plan.toml index 12aa94d893..656c100845 100644 --- a/packages/core/src/policy/policies/plan.toml +++ b/packages/core/src/policy/policies/plan.toml @@ -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"] diff --git a/packages/core/src/policy/policy-engine.test.ts b/packages/core/src/policy/policy-engine.test.ts index 6c59161af4..59b0fd8106 100644 --- a/packages/core/src/policy/policy-engine.test.ts +++ b/packages/core/src/policy/policy-engine.test.ts @@ -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', + ); + }); + }); }); diff --git a/packages/core/src/tools/tool-names.ts b/packages/core/src/tools/tool-names.ts index 70e882ebe1..f837edbe29 100644 --- a/packages/core/src/tools/tool-names.ts +++ b/packages/core/src/tools/tool-names.ts @@ -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;