feat(cli): add --prompt-interactive option#23
Conversation
There was a problem hiding this comment.
Pull request overview
Ports the Python kimi-cli feature to TypeScript kimi-code by adding a new CLI mode that sends an initial prompt and then stays in the interactive TUI session for follow-up conversation.
Changes:
- Add
-P/--prompt-interactive <prompt>CLI option, including validation rules and conflict handling. - Plumb
promptInteractivethroughrunShellinto the TUI asinitialCommand, and submit it after startup completes. - Update English/Chinese CLI reference docs, add tests, and publish a minor changeset.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/zh/reference/kimi-command.md | Document --prompt-interactive usage and flag compatibility rules (ZH). |
| docs/en/reference/kimi-command.md | Document --prompt-interactive usage and flag compatibility rules (EN). |
| apps/kimi-code/test/tui/kimi-tui-startup.test.ts | Adds assertions around initialCommand being stored in the TUI instance. |
| apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts | Updates startup input fixtures to include promptInteractive. |
| apps/kimi-code/test/tui/activity-pane.test.ts | Updates startup input fixtures to include promptInteractive. |
| apps/kimi-code/test/cli/run-shell.test.ts | Verifies promptInteractive is forwarded as initialCommand into KimiTUIStartupInput. |
| apps/kimi-code/test/cli/run-prompt.test.ts | Updates prompt runner fixtures to include promptInteractive. |
| apps/kimi-code/test/cli/options.test.ts | Adds parsing/validation tests for -P/--prompt-interactive. |
| apps/kimi-code/test/cli/main.test.ts | Updates default options fixture to include promptInteractive. |
| apps/kimi-code/src/tui/kimi-tui.ts | Introduces initialCommand on startup input and submits it after startup. |
| apps/kimi-code/src/main.ts | Extends migrate/default CLI options to include promptInteractive. |
| apps/kimi-code/src/cli/run-shell.ts | Passes promptInteractive into the TUI as initialCommand. |
| apps/kimi-code/src/cli/options.ts | Extends CLIOptions + adds validation for promptInteractive conflicts/empties. |
| apps/kimi-code/src/cli/commands.ts | Registers the new -P/--prompt-interactive Commander option. |
| .changeset/add-prompt-interactive.md | Declares a minor release for the new CLI option. |
Comments suppressed due to low confidence (1)
apps/kimi-code/src/tui/kimi-tui.ts:748
submitInitialCommand()dispatches input unconditionally afterfinishStartup(). In the OAuth login-required path (enterLoginRequiredStartupState()setsstartupStatetoreadybut leavesmodelempty andsessionundefined), this will immediately show the "LLM not set" error and effectively drop the initial prompt. Consider deferring the initial command until a session/model is available (e.g., after login/model activation), or gating this onthis.session+appState.modelbeing set.
// Sends the initial command from --prompt-interactive after startup completes.
private submitInitialCommand(): void {
if (!this.initialCommand || this.initialCommand.trim().length === 0) return;
this.handleUserInput(this.initialCommand);
}
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
| const shouldReplayHistory = await this.initMainTui(); | ||
| await this.finishStartup(shouldReplayHistory); | ||
| await this.submitInitialCommand(); | ||
| } catch (error) { |
| @@ -724,6 +730,7 @@ | |||
| this.startEventLoop(); | |||
| try { | |||
| await this.finishStartup(shouldReplayHistory); | |||
| await this.submitInitialCommand(); | |||
| } catch (error) { | |||
| // The pi-tui loop is running and startEventLoop() installed focus/theme | |||
| // tracking; tear all of it down so a finishStartup failure does not | |||
| @@ -734,6 +741,12 @@ | |||
| } | |||
| } | |||
|
|
|||
| // Sends the initial command from --prompt-interactive after startup completes. | |||
| private submitInitialCommand(): void { | |||
| if (!this.initialCommand || this.initialCommand.trim().length === 0) return; | |||
| this.handleUserInput(this.initialCommand); | |||
| } | |||
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b62cfb951a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| // Sends the initial command from --prompt-interactive after startup completes. | ||
| private submitInitialCommand(): void { | ||
| if (!this.initialCommand || this.initialCommand.trim().length === 0) return; | ||
| this.handleUserInput(this.initialCommand); |
There was a problem hiding this comment.
Defer initial command until session initialization succeeds
When startup falls back to the OAuth login-required state, this.session is still undefined and state.appState.model is empty; calling handleUserInput here immediately drops --prompt-interactive with an LLM not set error instead of sending it after login. This means kimi -P "..." silently loses the initial prompt for first-run/expired-auth users, which breaks the advertised “prompt then interact” behavior in that environment.
Useful? React with 👍 / 👎.
fc869e4 to
b25bb41
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b25bb416b7
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| if (!this.initialCommand || this.initialCommand.trim().length === 0) return; | ||
| this.handleUserInput(this.initialCommand); |
There was a problem hiding this comment.
Defer initial prompt until a usable session exists
Re-verified on this commit: start() now invokes submitInitialCommand() immediately after finishStartup(), but init() can enter the OAuth-login-required fallback (enterLoginRequiredStartupState) with no session and an empty model. In that state, routing --prompt-interactive through handleUserInput() causes sendNormalUserInput() to emit LLM_NOT_SET_MESSAGE and drop the prompt instead of sending it after login, so first-run/expired-auth users lose their initial command.
Useful? React with 👍 / 👎.
a976c0b to
b934ca1
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b934ca1f26
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| void this.fetchSessions(); | ||
| this.refreshSessionTitle(); | ||
| void this.refreshSkillCommands(this.session); | ||
| this.submitInitialCommand(); |
There was a problem hiding this comment.
Send interactive startup prompt only once
The --prompt-interactive text is kept for the entire TUI lifetime, and this new call replays it whenever login recreates a session (for example, -P "..." at startup, then /logout, then /login). That causes the original startup instruction to run again unexpectedly and can duplicate actions/tool side effects long after startup. Treat the initial prompt as one-shot by clearing/marking it consumed after the first successful dispatch.
Useful? React with 👍 / 👎.
Add -P/--prompt-interactive CLI flag that sends an initial prompt to the agent then keeps the interactive session open for follow-up conversation, ported from the Python kimi-cli. - validate mutually exclusive with --prompt, reject empty values, and block bare --session (picker) to prevent losing the initial command - inject initial command inside finishStartup after the TUI is ready - pre-fill the editor with the initial command text when the session or model is not yet available at startup, instead of showing an error - allow combining with --yolo, --plan, --continue, and --session <id> - update CLI reference docs in both English and Chinese
b934ca1 to
581b691
Compare
Signed-off-by: happy wang <shuizhongyueming@gmail.com>
🦋 Changeset detectedLatest commit: da67468 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
Thank you for your interest in contributing to Kimi Code. For new features, please create an issue or discuss it in an existing issue. We are not currently accepting pull requests for new features. |
Related Issue
This feature was originally requested in kimi-cli#2240 and implemented in the Python
kimi-cli. This PR ports it to the TypeScriptkimi-code.Description
Add
--prompt-interactive(-P) CLI option that sends an initial prompt to the agent then keeps the interactive session open for follow-up conversation.kimi(no args)kimi -p "hello"kimi -P "hello"Changes
-P/--prompt-interactiveflag, validate mutually exclusive with--prompt, reject empty values, block bare--session(picker) to avoid losing the initial commandsubmitInitialCommand()after startup completes, reusing the existinghandleUserInput()pipeline--yolo,--plan,--continue, and concrete--session <id>Checklist
gen-changesetsskillgen-docsskillpnpm lint && pnpm typecheck && pnpm testlocally (838 tests passed, 2 pre-existing lint warnings unrelated to this change)