Commit graph

40 commits

Author SHA1 Message Date
顾盼
2710bdec0d
feat(cli): Phase 2 — slash command multi-mode expansion, ACP fixes, and UX improvements (#3377)
* refactor(cli): replace slash command whitelist with capability-based filtering (Phase 1)

## Summary

Replace the hardcoded ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE whitelist with a
unified, capability-based command metadata model. This is Phase 1 of the slash
command architecture refactor described in docs/design/slash-command/.

## Key changes

### New types (types.ts)
- Add ExecutionMode ('interactive' | 'non_interactive' | 'acp')
- Add CommandSource ('builtin-command' | 'bundled-skill' | 'skill-dir-command' |
  'plugin-command' | 'mcp-prompt')
- Add CommandType ('prompt' | 'local' | 'local-jsx')
- Extend SlashCommand interface with: source, sourceLabel, commandType,
  supportedModes, userInvocable, modelInvocable, argumentHint, whenToUse,
  examples (all optional, backward-compatible)

### New module (commandUtils.ts + commandUtils.test.ts)
- getEffectiveSupportedModes(): 3-priority inference
  (explicit supportedModes > commandType > CommandKind fallback)
- filterCommandsForMode(): replaces filterCommandsForNonInteractive()
- 18 unit tests

### Whitelist removal (nonInteractiveCliCommands.ts)
- Remove ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE constant
- Remove filterCommandsForNonInteractive() function
- Replace with CommandService.getCommandsForMode(mode)

### CommandService enhancements (CommandService.ts)
- Add getCommandsForMode(mode: ExecutionMode): filters by mode, excludes hidden
- Add getModelInvocableCommands(): reserved for Phase 3 model tool-call use

### Built-in command annotations (41 files)
Annotate every built-in command with commandType:
- commandType='local' + supportedModes all-modes: btw, bug, compress, context,
  init, summary (replaces the 6-command whitelist)
- commandType='local' interactive-only: export, memory, plan, insight
- commandType='local-jsx' interactive-only: all remaining ~31 commands

### Loader metadata injection (4 files)
Each loader stamps source/sourceLabel/commandType/modelInvocable on every
command it emits:
- BuiltinCommandLoader: source='builtin-command', modelInvocable=false
- BundledSkillLoader: source='bundled-skill', commandType='prompt',
  modelInvocable=true
- command-factory (FileCommandLoader): source per extension/user origin,
  commandType='prompt', modelInvocable=!extensionName
- McpPromptLoader: source='mcp-prompt', commandType='prompt', modelInvocable=true

### Bug fix
MCP_PROMPT commands were incorrectly excluded from non-interactive/ACP modes by
the old whitelist logic. commandType='prompt' now correctly allows them in all
modes.

### Session.ts / nonInteractiveHelpers.ts
- ACP session calls getAvailableCommands with explicit 'acp' mode
- Remove allowedBuiltinCommandNames parameter from buildSystemMessage() —
  capability filtering is now self-contained in CommandService

* fix test ci

* feat(cli): Phase 2 slash command expansion + ACP fixes + UX improvements

Phase 2.1 - Command mode expansion:
- Extend 13 built-in commands to support non_interactive/acp modes
- A class: export, plan, statusline - supportedModes only
- A+ class: language, copy, restore - add non-interactive branches
- A' class: model, approvalMode - handle dialog paths in non-interactive
- B class: about, stats, insight, docs, clear - full non-interactive branches
- context: format output as readable Markdown instead of raw JSON
- export: use HTML as default format when no subcommand given

Phase 2.2 - SkillTool integration:
- SkillTool now consumes CommandService.getModelInvocableCommands()

Phase 2.3 - Mid-input slash ghost text:
- Replace mid-input dropdown completion with inline ghost text
- Match Claude Code behavior: gray dimmed completion hint in input box
- Tab accepts the ghost text completion
- Add findMidInputSlashCommand() and getBestSlashCommandMatch() utilities

ACP session bug fixes:
- Fix executionMode undefined in interactive mode (slashCommandProcessor)
- Fix slash command output not visible in Zed (use emitAgentMessage)
- Fix newline rendering in Zed (Markdown hard line-break)
- Fix history replay merging consecutive user messages (recordSlashCommand)
- Fix /clear not clearing model context (dynamic chat reference)

* feat: inline complete only for modelInvocable

* fix memory command

* fix: pass 'non_interactive' mode explicitly to getAvailableCommands

- Fix critical bug in nonInteractiveHelpers.ts: loadSlashCommandNames was
  calling getAvailableCommands without specifying mode, causing it to default
  to 'acp' instead of 'non_interactive'. Commands with supportedModes that
  include 'non_interactive' but not 'acp' would be silently excluded.
- Apply the same fix in systemController.ts for the same reason.
- Update test mock to delegate filtering to production filterCommandsForMode()
  instead of duplicating the logic inline, preventing divergence.

Fixes review comments by wenshao and tanzhenxin on PR #3283.

* fix: resolve TypeScript type error in nonInteractiveHelpers.test.ts

* fix test ci

* fix mcp prompt in skill manager

* revert pr#3345

* fix test ci

* feat(cli): adapt /insight for non_interactive mode with message return

- non_interactive: run generateStaticInsight() synchronously with no-op
  progress callback, return { type: 'message' } with output path
- acp: keep existing stream_messages path with progress streaming
- interactive: unchanged

Add tests for non_interactive success and error paths.

Update phase2-technical-design.md and roadmap.md to reflect the
three-way mode split and clarify that MCP prompts do not need
modelInvocable (they are called via native MCP tool call mechanism).

* fix(cli): ghost text only shown when cursor is at end of slash token

Use strict equality (!==) instead of > in findMidInputSlashCommand so that
ghost text is only computed and Tab-accepted when the cursor sits exactly at
the trailing edge of the partial command token.

Previously, with the cursor inside an already-typed token (e.g. /re|view),
the ghost text suffix would still be shown and pressing Tab would insert it
at the cursor position, producing a duplicated tail. Using strict equality
makes ghost text disappear as soon as the cursor moves inside the token.

Add unit tests for findMidInputSlashCommand covering cursor-at-end,
cursor-inside-token, cursor-past-token, start-of-line, and
no-space-before-slash cases.

* fix(cli): support /model <model-id> in non-interactive and ACP modes

Previously, /model <model-id> (without --fast) fell through to the
non-interactive branch that only returned the current model info and
incorrectly told users to use --fast. Now:

- /model <model-id>  → sets the main model via settings + config.setModel()
- /model             → shows current model with correct usage hint
- /model --fast <id> → unchanged (sets fast model)

Fixes the inconsistency flagged in PR review: the help text said to use
'/model <model-id>' but the command returned a dialog action which is
unsupported in non-interactive mode.

* fix(cli): declare supportedModes on doctorCommand to enable non-interactive and ACP

The command's action already had non-interactive handling (returns a JSON
message with check results), but without supportedModes declared the
BUILT_IN fallback restricted it to interactive-only so it was never
registered in non_interactive or acp sessions.

* feat(skills): add SkillCommandLoader for user/project/extension skills as slash commands

- New SkillCommandLoader loads user, project, and extension level SKILL.md
  files as slash commands (previously only bundled skills were slash-invocable)
- Extension skills follow plugin-command rules: modelInvocable only when
  description or whenToUse is present
- User/project skills are always modelInvocable (matching bundled behavior)
- skill-manager now injects extensionName when loading extension-level skills
- Add when_to_use and disable-model-invocation frontmatter support to SKILL.md
  and .md command files (SkillConfig, markdown-command-parser, command-factory,
  BundledSkillLoader, FileCommandLoader)
- SkillTool filters out skills with disableModelInvocation and includes
  whenToUse in the skill description shown to the model
- 16 unit tests for SkillCommandLoader covering all cases

* docs: update phase2 design doc to reflect final decisions on plan/statusline/copy/restore

These four commands are intentionally kept as interactive-only by design:
- /plan and /statusline: tightly coupled with interactive multi-turn UI
- /copy and /restore: clipboard and snapshot restore are inherently interactive

Update design doc classification table, section 4.2, 4.3, 5.2, 5.3,
file change summary, test requirements, behavior analysis table,
and implementation batch descriptions to reflect this decision.

* feat(cli): re-implement slashCommands.disabled denylist based on current refactored code

Adapts the feature originally introduced in pr#3445 to the current
CommandService / Phase-2 refactored code.

Sources (merged, de-duplicated, case-insensitive):
  - settings key slashCommands.disabled (string[], UNION merge)
  - --disabled-slash-commands CLI flag (comma-separated or repeated)
  - QWEN_DISABLED_SLASH_COMMANDS environment variable

Enforcement points:
  - CommandService.create() accepts optional disabledNames: ReadonlySet<string>
    and removes matching commands post-rename, so disabled commands never appear
    in autocomplete, mid-input ghost text, or model-invocable commands list.
  - slashCommandProcessor (interactive TUI) passes the denylist to
    CommandService.create so disabled commands are absent from dropdown/ghost text.
  - nonInteractiveCliCommands.handleSlashCommand() keeps allCommands unfiltered
    to distinguish disabled vs unknown; disabled commands return unsupported with
    a "disabled by the current configuration" reason (not no_command).
  - getAvailableCommands() (ACP) passes the denylist to CommandService.create.

Config plumbing:
  - core/Config: ConfigParameters.disabledSlashCommands + getDisabledSlashCommands()
  - cli/config: CliArgs.disabledSlashCommands + yargs option + loadCliConfig merge
  - settingsSchema: slashCommands.disabled (MergeStrategy.UNION)
  - settings.schema.json: regenerated

Tests: 28 pass (CommandService x4, nonInteractiveCliCommands x3 new cases)

* feat(cli): complete slashCommands.disabled coverage from pr#3445

Fill in the three items that were missing from the initial re-implementation:

- packages/cli/src/config/settings.test.ts: add UNION-merge test for
  slashCommands.disabled across user and workspace scopes
- packages/cli/src/nonInteractiveCli.test.ts: add getDisabledSlashCommands
  mock to the shared mockConfig fixture
- docs/users/configuration/settings.md: add slashCommands section (table +
  example + note) and --disabled-slash-commands row in the CLI args table

* fix(cli): match disabled slash commands by alias as well as primary name

The denylist previously only checked cmd.name (the primary/canonical name),
so disabling a command by its alias (e.g. 'about' for the 'status' command)
had no effect. Fix both CommandService.create() and the isDisabled() helper
in nonInteractiveCliCommands.ts to also check altNames.

Also improve the user-facing error message to show the token the user actually
typed (e.g. /about) instead of always showing the primary name (/status).
2026-04-22 19:12:44 +08:00
顾盼
a82d766727
refactor(cli): replace slash command whitelist with capability-based filtering (Phase 1) (#3283)
* refactor(cli): replace slash command whitelist with capability-based filtering (Phase 1)

## Summary

Replace the hardcoded ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE whitelist with a
unified, capability-based command metadata model. This is Phase 1 of the slash
command architecture refactor described in docs/design/slash-command/.

## Key changes

### New types (types.ts)
- Add ExecutionMode ('interactive' | 'non_interactive' | 'acp')
- Add CommandSource ('builtin-command' | 'bundled-skill' | 'skill-dir-command' |
  'plugin-command' | 'mcp-prompt')
- Add CommandType ('prompt' | 'local' | 'local-jsx')
- Extend SlashCommand interface with: source, sourceLabel, commandType,
  supportedModes, userInvocable, modelInvocable, argumentHint, whenToUse,
  examples (all optional, backward-compatible)

### New module (commandUtils.ts + commandUtils.test.ts)
- getEffectiveSupportedModes(): 3-priority inference
  (explicit supportedModes > commandType > CommandKind fallback)
- filterCommandsForMode(): replaces filterCommandsForNonInteractive()
- 18 unit tests

### Whitelist removal (nonInteractiveCliCommands.ts)
- Remove ALLOWED_BUILTIN_COMMANDS_NON_INTERACTIVE constant
- Remove filterCommandsForNonInteractive() function
- Replace with CommandService.getCommandsForMode(mode)

### CommandService enhancements (CommandService.ts)
- Add getCommandsForMode(mode: ExecutionMode): filters by mode, excludes hidden
- Add getModelInvocableCommands(): reserved for Phase 3 model tool-call use

### Built-in command annotations (41 files)
Annotate every built-in command with commandType:
- commandType='local' + supportedModes all-modes: btw, bug, compress, context,
  init, summary (replaces the 6-command whitelist)
- commandType='local' interactive-only: export, memory, plan, insight
- commandType='local-jsx' interactive-only: all remaining ~31 commands

### Loader metadata injection (4 files)
Each loader stamps source/sourceLabel/commandType/modelInvocable on every
command it emits:
- BuiltinCommandLoader: source='builtin-command', modelInvocable=false
- BundledSkillLoader: source='bundled-skill', commandType='prompt',
  modelInvocable=true
- command-factory (FileCommandLoader): source per extension/user origin,
  commandType='prompt', modelInvocable=!extensionName
- McpPromptLoader: source='mcp-prompt', commandType='prompt', modelInvocable=true

### Bug fix
MCP_PROMPT commands were incorrectly excluded from non-interactive/ACP modes by
the old whitelist logic. commandType='prompt' now correctly allows them in all
modes.

### Session.ts / nonInteractiveHelpers.ts
- ACP session calls getAvailableCommands with explicit 'acp' mode
- Remove allowedBuiltinCommandNames parameter from buildSystemMessage() —
  capability filtering is now self-contained in CommandService

* fix test ci

* fix memory command

* fix: pass 'non_interactive' mode explicitly to getAvailableCommands

- Fix critical bug in nonInteractiveHelpers.ts: loadSlashCommandNames was
  calling getAvailableCommands without specifying mode, causing it to default
  to 'acp' instead of 'non_interactive'. Commands with supportedModes that
  include 'non_interactive' but not 'acp' would be silently excluded.
- Apply the same fix in systemController.ts for the same reason.
- Update test mock to delegate filtering to production filterCommandsForMode()
  instead of duplicating the logic inline, preventing divergence.

Fixes review comments by wenshao and tanzhenxin on PR #3283.

* fix: resolve TypeScript type error in nonInteractiveHelpers.test.ts

* fix test ci
2026-04-20 14:34:43 +08:00
tanzhenxin
bfc3bbfa9c update user messages 2026-01-07 17:25:27 +08:00
刘伟光
34d8dbf9b2 feat: 兼容宿主机在不同ide上的instal提示 2025-12-19 11:07:33 +08:00
刘伟光
b3b2bc6ad5 feat: 兼容宿主机在不同ide上的instal提示 2025-12-19 10:39:05 +08:00
刘伟光
6ca54beba2 feat: Optimize the issue where an error message indicating unfriendliness occurs after executing the ideinstall command in the sandbox environment 2025-12-17 13:38:38 +08:00
pomelo
48b77541c3
feat(i18n): Add Internationalization Support for UI and LLM Output (#1058) 2025-11-21 15:44:37 +08:00
tanzhenxin
eb95c131be
Sync upstream Gemini-CLI v0.8.2 (#838) 2025-10-23 09:27:04 +08:00
mingholy.lmh
14ea33063f Merge tag 'v0.3.0' into chore/sync-gemini-cli-v0.3.0 2025-09-11 16:26:56 +08:00
tanzhenxin
2572faf726
# 🚀 Sync Gemini CLI v0.2.1 - Major Feature Update (#483)
Some checks are pending
Qwen Code CI / Lint (GitHub Actions) (push) Waiting to run
Qwen Code CI / Lint (Javascript) (push) Waiting to run
Qwen Code CI / Lint (Shell) (push) Waiting to run
Qwen Code CI / Lint (YAML) (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
2025-09-01 14:48:55 +08:00
Gal Zahavi
f22263c9e8
refactor: refactor settings to a nested structure (#7244) 2025-08-28 01:39:45 +00:00
Mingholy
347e606366
fix: ambiguous literals (#461)
Some checks are pending
Qwen Code CI / Lint (GitHub Actions) (push) Waiting to run
Qwen Code CI / Lint (Javascript) (push) Waiting to run
Qwen Code CI / Lint (Shell) (push) Waiting to run
Qwen Code CI / Lint (YAML) (push) Waiting to run
Qwen Code CI / Lint (push) Blocked by required conditions
Qwen Code CI / Test (push) Blocked by required conditions
Qwen Code CI / Post Coverage Comment (push) Blocked by required conditions
Qwen Code CI / CodeQL (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:docker (push) Waiting to run
E2E Tests / E2E Test (Linux) - sandbox:none (push) Waiting to run
E2E Tests / E2E Test - macOS (push) Waiting to run
2025-08-27 15:23:21 +08:00
Pascal Birchler
0f031a7f89
Explict imports & exports with type modifier (#3774) 2025-08-25 22:04:53 +00:00
Shreya Keshive
776627c855
refactor(ide): Improve IDE detection discovery (#6765) 2025-08-25 18:39:57 +00:00
Shreya Keshive
0e9b06d5c2
feat(ide): improve IDE installation UX and feedback (#6677) 2025-08-20 21:11:31 +00:00
mingholy.lmh
c546d86d44 Merge tag 'v0.1.21' of github.com:google-gemini/gemini-cli into chore/sync-gemini-cli-v0.1.21 2025-08-20 22:24:50 +08:00
tanzhenxin
2fcacb70b9 chore: fix ide installer 2025-08-20 11:25:11 +08:00
Shreya Keshive
9588aa6ef9
feat: Show /ide subcommands based on connection status instead of ideMode boolean (#6496) 2025-08-19 17:24:58 +00:00
Shreya Keshive
0215811c4c
Revert "Show /ide enable & /ide disable commands based on connection status" (#6486) 2025-08-18 16:42:45 +00:00
tanzhenxin
7dbc240847 chore: sync gemini-cli v0.1.19 2025-08-18 19:55:46 +08:00
Shreya Keshive
a84f749310
Show /ide enable & /ide disable commands based on connection status (#6248)
Co-authored-by: matt korwel <matt.korwel@gmail.com>
2025-08-15 00:22:32 +00:00
christine betts
d6403c67ee
[ide-mode] Suggest the extension name in the installation messages (#6182) 2025-08-14 14:57:36 +00:00
tanzhenxin
bc92da04e9 Merge tag 'v0.1.18' of https://github.com/google-gemini/gemini-cli into chore/sync-gemini-cli-v0.1.18 2025-08-13 15:11:10 +08:00
Shreya Keshive
3a87712c1a
Launch VS Code IDE Integration (#6063) 2025-08-12 21:08:07 +00:00
christine betts
74fd0841d0
[ide-mode] Update installation logic and nudge (#6068) 2025-08-12 20:08:47 +00:00
Shreya Keshive
b0b12af2ce
Additional IDE integration polishes (#5985) 2025-08-11 16:27:45 +00:00
Shreya Keshive
9ac62565a0
Fix excessive console logging + remove unnecessary try catch (#5860) 2025-08-08 21:48:02 +00:00
Shreya Keshive
344ee29f77
Use slash command instead of context drawer to display open files in editor to reduce flickering in the UI (#5858) 2025-08-08 21:26:11 +00:00
Shreya Keshive
268627469b
Refactor IDE client state management, improve user-facing error messages, and add logging of connection events (#5591)
Co-authored-by: matt korwel <matt.korwel@gmail.com>
2025-08-05 22:52:58 +00:00
Yiheng Xu
cd375fefe5 sync gemini-cli 0.1.17
Co-Authored-By: Qwen-Coder <qwen-coder@alibabacloud.com>
2025-08-05 17:09:19 +08:00
Shreya Keshive
2180dd13dc
Improve user-facing error messages for IDE mode (#5522) 2025-08-04 21:06:17 +00:00
Shreya Keshive
0895e29c1b Improve user-facing error messages for IDE mode (#5522) 2025-08-04 21:06:17 +00:00
奕桁
b69b2ce376 Merge tag 'v0.1.15' into feature/yiheng/sync-gemini-cli-0.1.15 2025-08-01 23:06:11 +08:00
christine betts
325bb89137
Add toggleable IDE mode setting (#5146) 2025-07-30 22:36:24 +00:00
christine betts
aad8893322 Add toggleable IDE mode setting (#5146) 2025-07-30 22:36:24 +00:00
christine betts
7bc8766542
Introduce IDE mode installer (#4877) 2025-07-30 21:26:31 +00:00
christine betts
3e1b2dc33a Introduce IDE mode installer (#4877) 2025-07-30 21:26:31 +00:00
christine betts
1b8ba5ca6b
[ide-mode] Create an IDE manager class to handle connecting to and exposing methods from the IDE server (#4797) 2025-07-25 17:46:55 +00:00
Abhi
2a95c8287e
prefactor(commands): Command Service Prefactor for Extensible Commands (#4511) 2025-07-20 20:57:34 +00:00
Shreya Keshive
ab9eb9377f
Add /ide status & /ide install commands to manage IDE integration (#4265) 2025-07-16 22:36:14 +00:00