kimi-plugin-cc 2.0.8 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +27 -0
  4. package/README.md +5 -5
  5. package/agents/kimi-ask.md +5 -1
  6. package/agents/kimi-challenge.md +4 -2
  7. package/agents/kimi-pursue.md +3 -1
  8. package/agents/kimi-rescue.md +5 -1
  9. package/agents/kimi-review.md +4 -2
  10. package/agents/kimi-swarm-write.md +3 -1
  11. package/agents/kimi-swarm.md +3 -1
  12. package/commands/ask.md +5 -3
  13. package/commands/challenge.md +5 -3
  14. package/commands/pursue.md +5 -1
  15. package/commands/rescue.md +5 -3
  16. package/commands/review.md +5 -3
  17. package/commands/swarm.md +5 -1
  18. package/dist/cli-client.js +42 -10
  19. package/dist/commands/ask.js +14 -7
  20. package/dist/commands/cli-helpers.js +66 -4
  21. package/dist/commands/pursue.js +7 -3
  22. package/dist/commands/rescue.js +16 -10
  23. package/dist/commands/result.js +5 -1
  24. package/dist/commands/review-gate.js +21 -14
  25. package/dist/commands/review.js +9 -5
  26. package/dist/commands/status.js +2 -2
  27. package/dist/commands/swarm.js +10 -4
  28. package/dist/help.js +1 -1
  29. package/dist/hook-escape.js +71 -0
  30. package/dist/hooks/approval-policy.js +17 -27
  31. package/dist/hooks/config-safety.js +15 -7
  32. package/dist/job-store.js +52 -7
  33. package/dist/kimi-engine.js +2 -0
  34. package/dist/kimi-errors.js +1 -1
  35. package/dist/kimi-timeouts.js +6 -10
  36. package/dist/kimi-version-probe.js +2 -2
  37. package/dist/parsing.js +59 -53
  38. package/dist/session-recovery.js +203 -0
  39. package/dist/vendor/smol-toml/date.js +50 -21
  40. package/dist/vendor/smol-toml/error.js +6 -2
  41. package/dist/vendor/smol-toml/extract.js +259 -66
  42. package/dist/vendor/smol-toml/parse.js +64 -48
  43. package/dist/vendor/smol-toml/primitive.js +107 -135
  44. package/dist/vendor/smol-toml/struct.js +106 -134
  45. package/dist/vendor/smol-toml/util.js +22 -78
  46. package/dist/version.js +1 -1
  47. package/docs/models.md +10 -0
  48. package/docs/registry-releases.md +24 -1
  49. package/docs/safety.md +59 -2
  50. package/package.json +1 -1
  51. package/plugins/kimi-codex/.codex-plugin/plugin.json +1 -1
  52. package/plugins/kimi-codex/dist/cli-client.js +42 -10
  53. package/plugins/kimi-codex/dist/commands/ask.js +14 -7
  54. package/plugins/kimi-codex/dist/commands/cli-helpers.js +66 -4
  55. package/plugins/kimi-codex/dist/commands/pursue.js +7 -3
  56. package/plugins/kimi-codex/dist/commands/rescue.js +16 -10
  57. package/plugins/kimi-codex/dist/commands/result.js +5 -1
  58. package/plugins/kimi-codex/dist/commands/review-gate.js +21 -14
  59. package/plugins/kimi-codex/dist/commands/review.js +9 -5
  60. package/plugins/kimi-codex/dist/commands/status.js +2 -2
  61. package/plugins/kimi-codex/dist/commands/swarm.js +10 -4
  62. package/plugins/kimi-codex/dist/help.js +1 -1
  63. package/plugins/kimi-codex/dist/hook-escape.js +71 -0
  64. package/plugins/kimi-codex/dist/hooks/approval-policy.js +17 -27
  65. package/plugins/kimi-codex/dist/hooks/config-safety.js +15 -7
  66. package/plugins/kimi-codex/dist/job-store.js +52 -7
  67. package/plugins/kimi-codex/dist/kimi-engine.js +2 -0
  68. package/plugins/kimi-codex/dist/kimi-errors.js +1 -1
  69. package/plugins/kimi-codex/dist/kimi-timeouts.js +6 -10
  70. package/plugins/kimi-codex/dist/kimi-version-probe.js +2 -2
  71. package/plugins/kimi-codex/dist/parsing.js +59 -53
  72. package/plugins/kimi-codex/dist/session-recovery.js +203 -0
  73. package/plugins/kimi-codex/dist/vendor/smol-toml/date.js +50 -21
  74. package/plugins/kimi-codex/dist/vendor/smol-toml/error.js +6 -2
  75. package/plugins/kimi-codex/dist/vendor/smol-toml/extract.js +259 -66
  76. package/plugins/kimi-codex/dist/vendor/smol-toml/parse.js +64 -48
  77. package/plugins/kimi-codex/dist/vendor/smol-toml/primitive.js +107 -135
  78. package/plugins/kimi-codex/dist/vendor/smol-toml/struct.js +106 -134
  79. package/plugins/kimi-codex/dist/vendor/smol-toml/util.js +22 -78
  80. package/plugins/kimi-codex/dist/version.js +1 -1
  81. package/plugins/kimi-codex/skills/kimi-ask/SKILL.md +4 -2
  82. package/plugins/kimi-codex/skills/kimi-challenge/SKILL.md +4 -2
  83. package/plugins/kimi-codex/skills/kimi-pursue/SKILL.md +3 -1
  84. package/plugins/kimi-codex/skills/kimi-rescue/SKILL.md +4 -2
  85. package/plugins/kimi-codex/skills/kimi-review/SKILL.md +4 -2
  86. package/plugins/kimi-codex/skills/kimi-setup/SKILL.md +2 -0
  87. package/plugins/kimi-codex/skills/kimi-swarm/SKILL.md +3 -1
  88. package/plugins/kimi-codex/skills/kimi-swarm-write/SKILL.md +3 -1
@@ -5,7 +5,7 @@
5
5
  },
6
6
  "metadata": {
7
7
  "description": "Kimi for Claude Code: code questions, reviews, fixes, and parallel tasks through the local Kimi Code CLI.",
8
- "version": "2.0.8"
8
+ "version": "2.2.1"
9
9
  },
10
10
  "plugins": [
11
11
  {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "kimi",
3
3
  "description": "Claude Code plugin that delegates read-only review, challenge, free-form ask, and write-capable rescue work to the local kimi-code CLI. Includes an opt-in stop-time review gate and a PreToolUse hook that enforces per-command safety.",
4
- "version": "2.0.8",
4
+ "version": "2.2.1",
5
5
  "homepage": "https://github.com/linxule/kimi-plugin-cc",
6
6
  "repository": "https://github.com/linxule/kimi-plugin-cc",
7
7
  "license": "Apache-2.0",
package/CHANGELOG.md CHANGED
@@ -2,6 +2,33 @@
2
2
 
3
3
  > **Post-1.0 release history (v1.0.1 -> present) lives in [ROADMAP-TO-GA.md § Post-GA audit log](./ROADMAP-TO-GA.md#post-ga-audit-log)** and the "Version" / "Upstream compat" lines of [AGENTS.md](./AGENTS.md). Docs-only kimi-code compat checkups that don't bump the plugin version (e.g. the 0.14.2 / 0.14.3 patches) are recorded there, not here. Notable releases are summarized below; the GA entry and full pre-GA detail follow.
4
4
 
5
+ ## 2.2.1 — 2026-10-15
6
+
7
+ - Request per-run thinking effort with `--thinking <effort>` through the upstream environment binding; persist requested effort and replay it in detached workers without changing saved defaults. The review gate requests `off` by default; provider/model no-op cases remain explicit.
8
+ - Add the hook-escape monitor as detection evidence: replay the pure PreToolUse policy on every streamed tool call and record, for each policy-denied call, whether the model received the managed hook's denial (byte-exact or with upstream's repeat-breaker decoration). Findings (`mismatch`, `unresolved`) are logged, persisted on the job (`hook_escapes`), shown in `status`/`result --json`, printed as a stderr notice and carried in timeout details; the run is never stopped and the job never fails on them, because upstream's pre-hook rejections, coexisting hooks and the repeat breaker produce the same text as a drifted hook. Proven live on CLI 2.2.0 with a deliberately broken hook command (`Write` executed; finding `mismatch`, excerpt `Wrote 7 bytes to ESCAPE.txt`).
9
+ - CLI 2.2.0 remains the certified maximum, unchanged; hook policy decisions, preflight closures, engine selection and teardown are unchanged.
10
+
11
+ ## 2.2.0 — 2026-10-15
12
+
13
+ - Port the vendored parser to unmodified smol-toml 1.9.1 JavaScript, closing
14
+ GHSA-r4xh-jqrq-34v2; adapt the config assignment walker and retain EOF-comment
15
+ protection with linear-scaling and shipped-mirror regressions.
16
+ - Recover native-v2 timeout session IDs only from exactly one bounded, matching
17
+ session-store candidate: created between spawn and settlement in the job's cwd,
18
+ and whose main journal opens with a user message carrying the job's exact prompt
19
+ (`prompt_digest`), so attribution is proof, not proximity. Persist
20
+ announced/recovered provenance in `kimi_session_id_source`, report recovery
21
+ refusals in error details (`session_recovery`), skip recovery when no
22
+ `system.version` marker was observed, and retain the existing lineage and raw
23
+ journal plan-taint checks on every resume.
24
+ - Expose `budget_source` in status and JSON results, and print inherited ask/rescue
25
+ budgets with their parent job at launch. Historical non-null budgets remain unknown.
26
+ - Allow 30 seconds for installed-state spawn-heavy tests; refresh install examples
27
+ and preserve the settled result's abort flag in timeout details.
28
+ - Permit deliberate plugin/CLI version-number alignment without treating the number
29
+ as compatibility evidence. CLI 2.2.0 remains the certified maximum, unchanged;
30
+ the certification table, hook policy, preflight closures and teardown remain unchanged.
31
+
5
32
  ## 2.0.8 — 2026-10-14
6
33
 
7
34
  - Certify exact Kimi Code CLI 2.2.0 (`472192c3`) for all eight native-v2 operations under the
package/README.md CHANGED
@@ -40,7 +40,7 @@ You need:
40
40
  - macOS or Linux
41
41
  - Claude Code or Codex with plugin support
42
42
  - Node.js 22.5 or newer
43
- - Kimi Code CLI 2.1.1, the recommended version for plugin 2.0.7
43
+ - Kimi Code CLI 2.2.0 (2.1.1 also certified), the recommended version for plugin 2.2.0
44
44
 
45
45
  Windows is not currently supported. Check your versions in a terminal:
46
46
 
@@ -108,7 +108,7 @@ needed to use the package. Kimi Code CLI and Node are still prerequisites.
108
108
  For an explicitly versioned local Claude Code plugin:
109
109
 
110
110
  ```sh
111
- npm install --prefix ~/.local/share/kimi-plugin-cc kimi-plugin-cc@2.0.7
111
+ npm install --prefix ~/.local/share/kimi-plugin-cc kimi-plugin-cc@2.2.1
112
112
  claude --plugin-dir ~/.local/share/kimi-plugin-cc/node_modules/kimi-plugin-cc
113
113
  ```
114
114
 
@@ -249,7 +249,7 @@ Contributors need Bun to run `bun run check`. The detailed engineering documents
249
249
  - macOS 或 Linux
250
250
  - 支持插件的 Claude Code 或 Codex
251
251
  - Node.js 22.5 或更高版本
252
- - Kimi Code CLI 2.1.1,这是插件 2.0.7 的推荐版本
252
+ - Kimi Code CLI 2.2.0(2.1.1 亦已认证),这是插件 2.2.0 的推荐版本
253
253
 
254
254
  目前不支持 Windows。在终端检查版本:
255
255
 
@@ -433,7 +433,7 @@ Il vous faut :
433
433
  - macOS ou Linux
434
434
  - une version de Claude Code ou de Codex prenant en charge les plugins
435
435
  - Node.js 22.5 ou une version ultérieure
436
- - Kimi Code CLI 2.1.1, la version recommandée pour le plugin 2.0.7
436
+ - Kimi Code CLI 2.2.0 (2.1.1 également certifiée), la version recommandée pour le plugin 2.2.0
437
437
 
438
438
  Windows n'est pas pris en charge actuellement. Vérifiez les versions dans un terminal :
439
439
 
@@ -617,7 +617,7 @@ Les contributeurs ont besoin de Bun pour exécuter `bun run check`. La documenta
617
617
  - macOS または Linux
618
618
  - プラグインに対応した Claude Code または Codex
619
619
  - Node.js 22.5 以降
620
- - Kimi Code CLI 2.1.1(プラグイン 2.0.7 の推奨バージョン)
620
+ - Kimi Code CLI 2.2.0(2.1.1 も認証済み。プラグイン 2.2.0 の推奨バージョン)
621
621
 
622
622
  現在、Windows には対応していません。ターミナルでバージョンを確認します。
623
623
 
@@ -39,7 +39,7 @@ For subscription auth, guide native Kimi `/login`; for API keys or other provide
39
39
 
40
40
  When invoked:
41
41
 
42
- - preserve `--budget <dur>` (default 30m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it.
42
+ - preserve `--budget <dur>` (default 30m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it. Inherited budgets are printed to stderr at launch; status and `result --json` expose `budget_source` (`explicit`, `inherited`, or `default`; old non-null budgets report `unknown`).
43
43
 
44
44
  - decide whether the task belongs to free-form ask rather than diff review (kimi-review / kimi-challenge) or implementation (kimi-rescue)
45
45
  - preserve the user's question text and flags exactly — rephrasing a free-form prompt loses the user's framing; pass `--background` / `--wait` when the user supplies them
@@ -83,3 +83,7 @@ The refusal carries structured context. It appears on the error output as a
83
83
  file. Surface the refusal and its reason to the user and stop.
84
84
 
85
85
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
86
+
87
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`.
88
+
89
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
@@ -39,13 +39,13 @@ For subscription auth, guide native Kimi `/login`; for API keys or other provide
39
39
 
40
40
  When invoked:
41
41
 
42
- - preserve `--budget <dur>` (default 30m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. Cancellation does not capture partial output.
42
+ - preserve `--budget <dur>` (default 30m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output.
43
43
 
44
44
  - decide whether the task belongs to adversarial challenge review rather than ordinary defect review (see kimi-review)
45
45
  - preserve any focus text the user supplies after the flags — the user's framing is what steers the challenge
46
46
  - call the shared companion runtime with one Bash invocation after any model-discovery step: `${CLAUDE_PLUGIN_ROOT}/scripts/companion.sh task challenge <args>`
47
47
  - if the companion reports `CHALLENGE_HOOK_NOT_INSTALLED`, surface the refusal and tell the user to run `/kimi:setup`; do not reach for `KIMI_PLUGIN_CC_SKIP_HOOK_CHECK`
48
- - the companion accepts a **strict allowlist** of flags: `--base <ref>`, `-m`/`--model <name>`, `--budget <dur>`. Everything else is trailing focus text — adversarial framing, not a content channel. Reasoning behavior follows the selected model and Kimi configuration; the parser hard-rejects `--thinking`/`--no-thinking`
48
+ - the companion accepts a **strict allowlist** of flags: `--thinking <off|low|medium|high>` (requested per run), `--base <ref>`, `-m`/`--model <name>`, `--budget <dur>`. Everything else is trailing focus text — adversarial framing, not a content channel. Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`
49
49
  - do not invent flags (`--file`, `--context`, `--path`, etc.). The runtime hard-fails with `INVALID_ARGS` on unknown flag-shaped tokens. If you need to attach file content or extended context, switch to `kimi-ask` or paste a brief summary into the focus text — challenge's payload is the git diff, not arbitrary file content
50
50
  - do not pass `--background` or `--wait` to the companion — the runtime rejects both with `INVALID_FLAGS` for review and challenge
51
51
  - if the user wants fire-and-forget behavior on a broad challenge, detach the Bash call itself with `run_in_background: true` instead of reaching for a companion flag; after launching, tell the user to check `/kimi:status` for progress
@@ -82,3 +82,5 @@ The refusal carries structured context. It appears on the error output as a
82
82
  file. Surface the refusal and its reason to the user and stop.
83
83
 
84
84
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
85
+
86
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
@@ -47,7 +47,7 @@ When invoked:
47
47
  - decide whether the task is genuinely AUTONOMOUS multi-turn pursuit rather than a single bounded delegated task (kimi-rescue) or read-only work (kimi-ask / kimi-review / kimi-swarm); when in doubt, prefer kimi-rescue — pursue is only for explicit hands-off autonomy
48
48
  - preserve the user's objective and explicit constraints with minimal reframing
49
49
  - call the shared companion runtime with one Bash invocation after any model-discovery step: `${CLAUDE_PLUGIN_ROOT}/scripts/companion.sh task pursue <args>`
50
- - the companion accepts a **strict allowlist** of flags: `--budget <duration>` (HARD wall-clock ceiling; e.g. `30m`, `1h`, `90s`; bare number = minutes; default 45m — the ONLY guaranteed bound on an autonomous run), `--turns <N>` (SOFT hint injected into the objective so Kimi calls `SetGoalBudget` itself; advisory, NOT enforced headless), and `-m`/`--model <name>`. Everything else is trailing objective text. Reasoning behavior follows the selected model and Kimi configuration; the parser hard-rejects `--thinking`/`--no-thinking`
50
+ - the companion accepts a **strict allowlist** of flags: `--thinking <off|low|medium|high>` (requested per run), `--budget <duration>` (HARD wall-clock ceiling; e.g. `30m`, `1h`, `90s`; bare number = minutes; default 45m — the ONLY guaranteed bound on an autonomous run), `--turns <N>` (SOFT hint injected into the objective so Kimi calls `SetGoalBudget` itself; advisory, NOT enforced headless), and `-m`/`--model <name>`. Everything else is trailing objective text. Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`
51
51
  - do not invent flags. The runtime hard-fails with `INVALID_ARGS` on unknown flag-shaped tokens — pass `--` before flag-shaped objective text to forward it as objective text rather than a flag
52
52
  - **this is the plugin's highest blast radius: write-capable AND autonomous.** Only dispatch on explicit user intent for hands-off multi-turn pursuit. Writes are confined to the workspace by the rescue allowlist, and the index-0 PreToolUse hook fires on EVERY continuation turn — proven by a real-binary smoke that runs goal mode under a read-only label and asserts zero files land across the whole multi-turn run (no continuation turn slips past the hook; pursue itself writes via the rescue allowlist). pursue cannot mutate git state (the main thread owns branch/commit). The autonomy is bounded ONLY by `--budget`, so always pass an explicit one sized to the task and keep it WELL UNDER the 45m default unless the user named a larger window — a model-launched, possibly unwatched write loop should get the smallest budget that can plausibly finish, and never more than the user asked for; never try to remove it
53
53
  - pursue is foreground-only **at the runtime level** — `--background`, `--wait`, `--fresh`, and `--resume` are rejected with `INVALID_ARGS` (`--resume` intentionally: goal mode's `goalId` differs from the resume `sessionId`). How you make the Bash call is a separate question: **default to `run_in_background: true`.** An autonomous goal loop routinely outlives a foreground shell timeout (Claude Code caps foreground Bash at 10 minutes; `--budget` defaults to 45m), and a blocked foreground call is worse oversight, not better — it freezes you for the whole run, so you cannot report progress or cancel on request. What bounds this surface is the managed PreToolUse hook, the workspace allowlist, the no-git-mutation rule, and the mandatory finite `--budget` — none of which depend on anyone watching. Keep `--budget` finite and never remove it: it is the sole hard bound on the loop
@@ -89,3 +89,5 @@ The refusal carries structured context. It appears on the error output as a
89
89
  file. Surface the refusal and its reason to the user and stop.
90
90
 
91
91
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
92
+
93
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
@@ -44,7 +44,7 @@ For subscription auth, guide native Kimi `/login`; for API keys or other provide
44
44
 
45
45
  When invoked:
46
46
 
47
- - preserve `--budget <dur>` (default 45m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it.
47
+ - preserve `--budget <dur>` (default 45m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it. Inherited budgets are printed to stderr at launch; status and `result --json` expose `budget_source` (`explicit`, `inherited`, or `default`; old non-null budgets report `unknown`).
48
48
 
49
49
  - decide whether the task belongs to rescue rather than read-only review or ask
50
50
  - preserve the user's task text and explicit constraints with minimal reframing
@@ -86,3 +86,7 @@ The refusal carries structured context. It appears on the error output as a
86
86
  file. Surface the refusal and its reason to the user and stop.
87
87
 
88
88
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
89
+
90
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`.
91
+
92
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
@@ -39,13 +39,13 @@ For subscription auth, guide native Kimi `/login`; for API keys or other provide
39
39
 
40
40
  When invoked:
41
41
 
42
- - preserve `--budget <dur>` (default 30m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. Cancellation does not capture partial output.
42
+ - preserve `--budget <dur>` (default 30m; `30m`, `1h`, `90s`, or bare minutes, maximum 24h). Backgrounding does not extend this budget. A timed-out job remains failed and its artifact holds partial assistant output labeled NOT a final answer; read it with `result <jobId>` or `result <jobId> --json`. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output.
43
43
 
44
44
  - decide whether the task belongs to a diff review rather than a free-form ask or a write-capable rescue
45
45
  - preserve the user's scope hints (`--base <ref>`, focus text) with minimal reframing
46
46
  - call the shared companion runtime with one Bash invocation after any model-discovery step: `${CLAUDE_PLUGIN_ROOT}/scripts/companion.sh review <args>`
47
47
  - if the companion reports `REVIEW_HOOK_NOT_INSTALLED`, surface the refusal and tell the user to run `/kimi:setup`; do not reach for `KIMI_PLUGIN_CC_SKIP_HOOK_CHECK`
48
- - the companion accepts a **strict allowlist** of flags: `--base <ref>`, `-m`/`--model <name>`, `--budget <dur>`. Everything else is trailing focus text — a short scope hint, not a content channel. Reasoning behavior follows the selected model and Kimi configuration; the parser hard-rejects `--thinking`/`--no-thinking`
48
+ - the companion accepts a **strict allowlist** of flags: `--thinking <off|low|medium|high>` (requested per run), `--base <ref>`, `-m`/`--model <name>`, `--budget <dur>`. Everything else is trailing focus text — a short scope hint, not a content channel. Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`
49
49
  - do not invent flags (`--file`, `--context`, `--path`, etc.). The runtime hard-fails with `INVALID_ARGS` on unknown flag-shaped tokens. If you need to attach file content or extended context, switch to `kimi-ask` or paste a brief summary into the focus text — review's payload is the git diff, not arbitrary file content
50
50
  - do not pass `--background` or `--wait` to the companion — the runtime rejects both with `INVALID_FLAGS` for review and challenge
51
51
  - if the user wants fire-and-forget behavior on a long review (multi-file diff, unclear scope), detach the Bash call itself with `run_in_background: true` instead of reaching for a companion flag; after launching, tell the user to check `/kimi:status` for progress
@@ -82,3 +82,5 @@ The refusal carries structured context. It appears on the error output as a
82
82
  file. Surface the refusal and its reason to the user and stop.
83
83
 
84
84
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
85
+
86
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
@@ -47,7 +47,7 @@ When invoked:
47
47
  - confirm BOTH signals are present before dispatching: (1) MANY disjoint WRITE targets and (2) an explicit request to fan the edits out in parallel. If the user wants a single edit, use `kimi-rescue`; a read-only fan-out, `kimi-swarm`; an autonomous multi-turn loop, `kimi-pursue`. When in doubt, prefer `kimi-rescue` — do not shard one task into a swarm
48
48
  - preserve the user's objective and the disjoint target list with minimal reframing; partition into NON-overlapping targets (the subagents edit in one shared worktree, so overlapping targets can clobber each other)
49
49
  - call the shared companion runtime with one Bash invocation after any model-discovery step: `${CLAUDE_PLUGIN_ROOT}/scripts/companion.sh task swarm --write <args>` (the `--write` flag is REQUIRED — this agent is the write path)
50
- - the companion accepts a **strict allowlist** of flags: `--budget <duration>` (HARD wall-clock ceiling; e.g. `30m`, `1h`, `90s`; bare number = minutes; default 30m, max 24h), `--cap <N>` (SOFT total-subagent-count hint injected into the coordinator prompt — advisory, the hook is stateless and can't count subagents), `--max-concurrency <N>` (HARD ceiling on concurrent subagents on kimi-code 0.18.0+; **defaults to 1 for `--write`** — writes serialize because disjoint-target partitioning is prompt-only), and `-m`/`--model <name>`. Everything else is trailing objective text. Reasoning behavior follows the selected model and Kimi configuration; the parser hard-rejects `--thinking`/`--no-thinking`
50
+ - the companion accepts a **strict allowlist** of flags: `--thinking <off|low|medium|high>` (requested per run), `--budget <duration>` (HARD wall-clock ceiling; e.g. `30m`, `1h`, `90s`; bare number = minutes; default 30m, max 24h), `--cap <N>` (SOFT total-subagent-count hint injected into the coordinator prompt — advisory, the hook is stateless and can't count subagents), `--max-concurrency <N>` (HARD ceiling on concurrent subagents on kimi-code 0.18.0+; **defaults to 1 for `--write`** — writes serialize because disjoint-target partitioning is prompt-only), and `-m`/`--model <name>`. Everything else is trailing objective text. Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`
51
51
  - do not invent flags. The runtime hard-fails with `INVALID_ARGS` on unknown flag-shaped tokens — pass `--` before flag-shaped objective text to forward it as objective text rather than a flag
52
52
  - **this is write-capable, but the blast radius is bounded by construction — and PATCH-ONLY is the load-bearing safety property.** Every edit happens in an ephemeral worktree off HEAD; the `coder` subagents fire the index-0 PreToolUse hook on every tool call (the `swarm-write` label routes write/edit/shell through the rescue allowlist, scoped to a forge-proof trusted worktree root — not the payload cwd), so writes are confined to that worktree and out-of-worktree writes + git mutation are denied. The result is a `.patch` the user reviews and applies themselves — **the plugin never applies or commits, and the user's real tree is never touched.** Always pass an explicit `--budget` sized to the task (keep it at or below 30m unless the user named a larger window) and an explicit `--max-concurrency` (leave at 1 unless the user asks to parallelize writes and the targets are provably disjoint). Never try to remove these bounds
53
53
  - swarm-write **bases the worktree on HEAD: uncommitted changes are NOT included.** If the user has a dirty tree the runtime warns; surface that and suggest committing or stashing first if the swarm needs those changes
@@ -90,3 +90,5 @@ The refusal carries structured context. It appears on the error output as a
90
90
  file. Surface the refusal and its reason to the user and stop.
91
91
 
92
92
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
93
+
94
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
@@ -42,7 +42,7 @@ When invoked:
42
42
  - decide whether the task is a BROAD read-only fan-out rather than a single-diff review (kimi-review), free-form ask (kimi-ask), or implementation (kimi-rescue); for one working-tree or branch diff, use kimi-review instead
43
43
  - preserve the user's review scope as the trailing focus text — what to review across the workspace — with minimal reframing
44
44
  - call the shared companion runtime with one Bash invocation after any model-discovery step: `${CLAUDE_PLUGIN_ROOT}/scripts/companion.sh task swarm <args>`
45
- - the companion accepts a **strict allowlist** of flags: `--budget <duration>` (HARD wall-clock ceiling; e.g. `30m`, `1h`, `90s`; bare number = minutes; default 30m), `--cap <N>` (SOFT total-subagent-count hint injected into the coordinator prompt — advisory, the hook is stateless and can't count subagents), `--max-concurrency <N>` (HARD ceiling on how many subagents run AT ONCE, on kimi-code 0.18.0+; **defaults to 4** when omitted, older binaries ignore it), and `-m`/`--model <name>`. Everything else is trailing focus text. Reasoning behavior follows the selected model and Kimi configuration; the parser hard-rejects `--thinking`/`--no-thinking`
45
+ - the companion accepts a **strict allowlist** of flags: `--thinking <off|low|medium|high>` (requested per run), `--budget <duration>` (HARD wall-clock ceiling; e.g. `30m`, `1h`, `90s`; bare number = minutes; default 30m), `--cap <N>` (SOFT total-subagent-count hint injected into the coordinator prompt — advisory, the hook is stateless and can't count subagents), `--max-concurrency <N>` (HARD ceiling on how many subagents run AT ONCE, on kimi-code 0.18.0+; **defaults to 4** when omitted, older binaries ignore it), and `-m`/`--model <name>`. Everything else is trailing focus text. Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). `--no-thinking` is rejected; use `--thinking off`
46
46
  - do not invent flags. The runtime hard-fails with `INVALID_ARGS` on unknown flag-shaped tokens — pass `--` before flag-shaped objective text to forward it as scope text rather than a flag
47
47
  - **cost is the only real risk, and it is bounded by construction.** This agent can be auto-dispatched, and a swarm is N parallel model runs — but there is no write surface (every spawned subagent inherits the `swarm` label and fires the same index-0 PreToolUse hook, so its write/edit/shell is denied exactly like a single-turn review's). The runtime already enforces a finite peak: `--max-concurrency` defaults to `4` for every run, and `--budget` defaults to 30m. You SHOULD still pass an explicit `--max-concurrency` sized to the target count (lower to throttle; raise only when the user asks) and keep `--budget` at or below 30m. Never attempt to remove these bounds
48
48
  - swarm is **foreground-only** — do not pass `--background`, `--wait`, `--fresh`, or `--resume` (the parser rejects them with `INVALID_ARGS`). Default to foreground so the run stays watchable. Detach the Bash call with `run_in_background: true` ONLY when the user explicitly asks for fire-and-forget, and only with a finite `--max-concurrency` and a reduced `--budget` (a backgrounded fan-out has no human watching it to Ctrl+C); after launching, tell the user to check `/kimi:status` for progress
@@ -81,3 +81,5 @@ The refusal carries structured context. It appears on the error output as a
81
81
  file. Surface the refusal and its reason to the user and stop.
82
82
 
83
83
  Retry at most once. If the retry refuses again, surface both failures rather than looping.
84
+
85
+ A `hook_escapes` array in `result <jobId> --json` (or a `safety hook notice` on stderr) is detection evidence, not a failure: a policy-denied tool call came back as something other than the managed hook's denial — an upstream pre-hook rejection, another hook blocking first, or hook drift. Mention it to the user with the excerpt and suggest `/kimi:setup --check`; never treat the job as failed or retry on its own.
package/commands/ask.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Ask Kimi a read-only question in free-form prose mode.
3
- argument-hint: "[--budget <30m|1h|90s>] [--background] [--wait] [-r | --resume <id>] [--fresh] [-m <model>] <prompt>"
3
+ argument-hint: "[--budget <30m|1h|90s>] [--background] [--wait] [-r | --resume <id>] [--fresh] [-m <model>] [--thinking <effort>] <prompt>"
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -10,6 +10,8 @@ Run the companion with any user-supplied flags appended after `ask`:
10
10
 
11
11
  Supported flags:
12
12
 
13
+ - `--thinking <off|low|medium|high>` (also `--thinking=<effort>`) — request effort for this process; other model-supported effort tokens pass through. `--no-thinking` is rejected; use `--thinking off`. The request applies to this run only: a resume without `--thinking` requests nothing (unlike `--budget`, which is inherited).
14
+
13
15
  - `--budget <dur>` — wall-clock ceiling (default 30m; `30m`, `1h`, `90s`, or bare minutes; maximum 24h)
14
16
 
15
17
  - `--background` — spawn as a background job and return `{job_id}` immediately
@@ -19,9 +21,9 @@ Supported flags:
19
21
  - `--fresh` — force a new ask session id instead of reusing a prior session
20
22
  - `-m`, `--model <name>`
21
23
 
22
- Reasoning behavior follows the selected model and Kimi configuration. The plugin does not force a thinking mode. The default budget is 30m; use `--budget` to change it. Backgrounding does not extend the runtime budget.
24
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). The default budget is 30m; use `--budget` to change it. Backgrounding does not extend the runtime budget.
23
25
 
24
- A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept only if Kimi announced it before the deadline; native v2 announces it at session end, so a timed-out v2 turn is normally not resumable from the plugin. Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it. Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
26
+ A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it. Inherited budgets are printed to stderr at launch; status and `result --json` expose `budget_source` (`explicit`, `inherited`, or `default`; old non-null budgets report `unknown`). Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
25
27
 
26
28
  Return the companion stdout verbatim.
27
29
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Run a read-only Kimi challenge review that challenges assumptions and surfaces safer alternatives.
3
- argument-hint: "[--budget <30m|1h|90s>] [--base <ref>] [-m <model>] [extra prose]"
3
+ argument-hint: "[--budget <30m|1h|90s>] [--base <ref>] [-m <model>] [--thinking <effort>] [extra prose]"
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -10,15 +10,17 @@ Run the companion with any user-supplied flags appended after `task challenge`:
10
10
 
11
11
  Supported flags:
12
12
 
13
+ - `--thinking <off|low|medium|high>` (also `--thinking=<effort>`) — request effort for this process; other model-supported effort tokens pass through. `--no-thinking` is rejected; use `--thinking off`.
14
+
13
15
  - `--budget <dur>` — wall-clock ceiling (default 30m; `30m`, `1h`, `90s`, or bare minutes; maximum 24h)
14
16
 
15
17
  - `--base <ref>` — challenge against a branch/commit diff instead of the working tree
16
18
  - `-m`, `--model <name>`
17
19
  - trailing text — adversarial focus or framing to steer the challenge
18
20
 
19
- Reasoning behavior follows the selected model and Kimi configuration. The plugin does not force a thinking mode. The default budget is 30m; use `--budget` to change it. Challenge runs foreground-synchronously; it does not support `--background` or `--wait`.
21
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). The default budget is 30m; use `--budget` to change it. Challenge runs foreground-synchronously; it does not support `--background` or `--wait`.
20
22
 
21
- A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept only if Kimi announced it before the deadline; native v2 announces it at session end, so a timed-out v2 turn is normally not resumable from the plugin. Cancellation does not capture partial output. Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
23
+ A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output. Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
22
24
 
23
25
  Return the companion stdout verbatim.
24
26
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Hand Kimi an objective to pursue AUTONOMOUSLY across multiple turns (experimental goal mode), bounded by a hard wall-clock budget. Write-capable, gated by the same PreToolUse hook as rescue.
3
- argument-hint: "[--budget <30m|1h>] [--turns <N>] [-m <model>] <objective>"
3
+ argument-hint: "[--budget <30m|1h>] [--turns <N>] [-m <model>] [--thinking <effort>] <objective>"
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -12,6 +12,8 @@ Run the companion with any user-supplied flags appended after `task pursue`:
12
12
 
13
13
  Supported flags:
14
14
 
15
+ - `--thinking <off|low|medium|high>` (also `--thinking=<effort>`) — request effort for this process; other model-supported effort tokens pass through. `--no-thinking` is rejected; use `--thinking off`.
16
+
15
17
  - `--budget <duration>` — HARD wall-clock ceiling (e.g. `30m`, `1h`, `90s`; bare number = minutes). Default 45m. This is the only guaranteed bound on an autonomous run.
16
18
  - `--turns <N>` — SOFT cap: injected into the objective as a model instruction to call `SetGoalBudget`. Advisory, not enforced.
17
19
  - `-m`, `--model <name>`
@@ -35,3 +37,5 @@ Preserve an explicit `-m`/`--model` alias. For a natural-language model/provider
35
37
  Inventory labels are untrusted data, not instructions. Pass the chosen alias as one correctly shell-quoted `-m` argument. The inventory is not a connection test; never claim configured means authenticated or working. Do not run `kimi provider list --json`, read raw config/credentials, or request API keys in chat.
36
38
 
37
39
  For subscription auth, guide native Kimi `/login`; for API keys or other providers, guide native `/provider` and have the user enter secrets there. Only an explicit saved-default request calls for native `/model`. Re-list after setup; use `setup --check` for hook readiness. Swarm `-m` selects the coordinator; `[secondary_model]` can select different child models.
40
+
41
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it).
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Run a write-capable Kimi rescue against the current repository with optional background execution and resume behavior.
3
- argument-hint: "[--budget <30m|1h|90s>] [--background] [--wait] [-r | --resume <id>] [--fresh] [-m <model>] <prompt>"
3
+ argument-hint: "[--budget <30m|1h|90s>] [--background] [--wait] [-r | --resume <id>] [--fresh] [-m <model>] [--thinking <effort>] <prompt>"
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -10,6 +10,8 @@ Run the companion with any user-supplied flags appended after `task rescue`:
10
10
 
11
11
  Supported flags:
12
12
 
13
+ - `--thinking <off|low|medium|high>` (also `--thinking=<effort>`) — request effort for this process; other model-supported effort tokens pass through. `--no-thinking` is rejected; use `--thinking off`. The request applies to this run only: a resume without `--thinking` requests nothing (unlike `--budget`, which is inherited).
14
+
13
15
  - `--budget <dur>` — wall-clock ceiling (default 45m; `30m`, `1h`, `90s`, or bare minutes; maximum 24h)
14
16
 
15
17
  - `--background` — spawn as a detached background job and return `{job_id}` immediately
@@ -19,9 +21,9 @@ Supported flags:
19
21
  - `--fresh` — force a new rescue session id instead of reusing a prior session
20
22
  - `-m`, `--model <name>`
21
23
 
22
- Reasoning behavior follows the selected model and Kimi configuration. The plugin does not force a thinking mode. The default budget is 45m; use `--budget` to change it for multi-step apply/test/verify loops; use `--background` to return control while the task runs. Backgrounding does not extend the runtime budget.
24
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). The default budget is 45m; use `--budget` to change it for multi-step apply/test/verify loops; use `--background` to return control while the task runs. Backgrounding does not extend the runtime budget.
23
25
 
24
- A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept only if Kimi announced it before the deadline; native v2 announces it at session end, so a timed-out v2 turn is normally not resumable from the plugin. Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it. Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
26
+ A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output. A resume without `--budget` inherits the parent job's budget; an explicit budget overrides it. Inherited budgets are printed to stderr at launch; status and `result --json` expose `budget_source` (`explicit`, `inherited`, or `default`; old non-null budgets report `unknown`). Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
25
27
 
26
28
  Return the companion stdout verbatim.
27
29
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Run a read-only Kimi review over the current working tree changes or a base ref diff.
3
- argument-hint: "[--budget <30m|1h|90s>] [--base <ref>] [-m <model>] [extra prose]"
3
+ argument-hint: "[--budget <30m|1h|90s>] [--base <ref>] [-m <model>] [--thinking <effort>] [extra prose]"
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -10,15 +10,17 @@ Run the companion with any user-supplied flags appended after `review`:
10
10
 
11
11
  Supported flags:
12
12
 
13
+ - `--thinking <off|low|medium|high>` (also `--thinking=<effort>`) — request effort for this process; other model-supported effort tokens pass through. `--no-thinking` is rejected; use `--thinking off`.
14
+
13
15
  - `--budget <dur>` — wall-clock ceiling (default 30m; `30m`, `1h`, `90s`, or bare minutes; maximum 24h)
14
16
 
15
17
  - `--base <ref>` — review against a branch/commit diff instead of the working tree
16
18
  - `-m`, `--model <name>`
17
19
  - trailing text — optional focus hint for the review
18
20
 
19
- Reasoning behavior follows the selected model and Kimi configuration. The plugin does not force a thinking mode. The default budget is 30m; use `--budget` to change it. Review runs foreground-synchronously; it does not support `--background` or `--wait`.
21
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it). The default budget is 30m; use `--budget` to change it. Review runs foreground-synchronously; it does not support `--background` or `--wait`.
20
22
 
21
- A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept only if Kimi announced it before the deadline; native v2 announces it at session end, so a timed-out v2 turn is normally not resumable from the plugin. Cancellation does not capture partial output. Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
23
+ A budget timeout leaves the job `failed` and saves any partial assistant prose in its artifact, labeled **NOT a final answer**. Read it with `result <jobId>` or `result <jobId> --json`; tool-only runs explicitly report no assistant prose. A session ID is kept if Kimi announced it or, on a native-v2 budget timeout, recovered from the session store when exactly one session matches this spawn — created between spawn and settlement in the same directory AND whose journal opens with this job's exact prompt; `result --json` identifies the source in `kimi_session_id_source`, and `error.details.session_recovery` says why no ID was recovered (`none`, `journal_missing:<n>`, `digest_mismatch:<n>`, `ambiguous:<n>`, `enumeration_capped`, `engine_unobserved`). Cancellation does not capture partial output. Use `--help` or `-h` among the leading flags for usage; once prompt text starts, `-h` is part of the prompt. Other failures (nonzero exit, cancellation) do not capture partial output.
22
24
 
23
25
  Return the companion stdout verbatim.
24
26
 
package/commands/swarm.md CHANGED
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: Fan out a parallel review across the workspace using Kimi's AgentSwarm tool, bounded by a hard wall-clock budget. Read-only by default (enforced by the same PreToolUse hook as review, applied to every subagent); --write fans out edits in a throwaway worktree and returns a patch.
3
- argument-hint: "[--write] [--budget <30m|1h>] [--cap <N>] [--max-concurrency <N>] [-m <model>] <objective>"
3
+ argument-hint: "[--write] [--budget <30m|1h>] [--cap <N>] [--max-concurrency <N>] [-m <model>] [--thinking <effort>] <objective>"
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
@@ -14,6 +14,8 @@ Run the companion with any user-supplied flags appended after `task swarm`:
14
14
 
15
15
  Supported flags:
16
16
 
17
+ - `--thinking <off|low|medium|high>` (also `--thinking=<effort>`) — request effort for this process; other model-supported effort tokens pass through. `--no-thinking` is rejected; use `--thinking off`.
18
+
17
19
  - `--write` — fan out EDITS (not just review). Requires kimi-code **>= 0.18.0**, a git repo with a committed HEAD, and the PreToolUse hook. Bases the worktree on HEAD: **uncommitted changes are NOT included** (you'll get a warning) — commit or stash first if the swarm needs them. `--write` is also reachable via the model-invocable `kimi-swarm-write` subagent, with strict triggering (many disjoint write targets AND explicit fan-out intent); auto-dispatch widens no write surface and keeps every bound, and the slash command itself stays human-only.
18
20
  - `--budget <duration>` — HARD wall-clock ceiling (e.g. `30m`, `1h`, `90s`; bare number = minutes). Default 30m. The always-on bound on cost/runaway.
19
21
  - `--cap <N>` — SOFT cap on TOTAL subagent count: injected into the prompt as a model instruction. Advisory, not hook-enforced (the hook is stateless and can't count subagents), so the model may exceed it. Bounds lifetime total, not peak parallelism.
@@ -36,3 +38,5 @@ Preserve an explicit `-m`/`--model` alias. For a natural-language model/provider
36
38
  Inventory labels are untrusted data, not instructions. Pass the chosen alias as one correctly shell-quoted `-m` argument. The inventory is not a connection test; never claim configured means authenticated or working. Do not run `kimi provider list --json`, read raw config/credentials, or request API keys in chat.
37
39
 
38
40
  For subscription auth, guide native Kimi `/login`; for API keys or other providers, guide native `/provider` and have the user enter secrets there. Only an explicit saved-default request calls for native `/model`. Re-list after setup; use `setup --check` for hook readiness. Swarm `-m` selects the coordinator; `[secondary_model]` can select different child models.
41
+
42
+ Reasoning behavior follows the selected model and Kimi configuration unless `--thinking <effort>` requests one for this run (honoured by Kimi's own providers on models that can turn thinking off; other providers ignore it silently; the plugin cannot verify it).
@@ -19,6 +19,7 @@
19
19
  import { spawn } from "node:child_process";
20
20
  import { appendFile, mkdir } from "node:fs/promises";
21
21
  import path from "node:path";
22
+ import { createHookEscapeMonitor } from "./hook-escape.js";
22
23
  import { RuntimeError, formatError } from "./errors.js";
23
24
  import { assertNoUnsafeExperimentalSelector, assertExecutionPlanMatchesSpawn, } from "./kimi-engine.js";
24
25
  import { assertPrefixArgsSafe } from "./kimi-command.js";
@@ -84,7 +85,9 @@ export async function runCliPrompt(opts) {
84
85
  });
85
86
  }
86
87
  let child;
88
+ let spawnedAt;
87
89
  try {
90
+ spawnedAt = Date.now();
88
91
  child = spawn(opts.command, args, {
89
92
  cwd: opts.cwd,
90
93
  env,
@@ -124,6 +127,14 @@ export async function runCliPrompt(opts) {
124
127
  let announcedSessionId;
125
128
  let announcedGoalSummary;
126
129
  let announcedSystemVersion;
130
+ const hookMonitor = createHookEscapeMonitor({ commandLabel: opts.commandLabel,
131
+ operationKind: opts.executionPlan.operationKind, trustedWorkspaceRoot: opts.trustedWorkspaceRoot, cwd: opts.cwd });
132
+ const hookEscapes = [];
133
+ const noteHookEscape = (escape) => {
134
+ hookEscapes.push(escape);
135
+ appendLogLine({ event: "hook_escape", ...escape, command_label: opts.commandLabel,
136
+ operation_kind: opts.executionPlan.operationKind });
137
+ };
127
138
  let engineMismatchDetected = false;
128
139
  let handleEngineMismatch;
129
140
  const plannedEngine = opts.executionPlan.intendedEngine;
@@ -281,6 +292,9 @@ export async function runCliPrompt(opts) {
281
292
  }
282
293
  if (requireMarkerBeforeOutput(`a ${outcome.record.role} record`))
283
294
  return;
295
+ const escape = hookMonitor.observe(outcome.record);
296
+ if (escape)
297
+ noteHookEscape(escape);
284
298
  records.push(outcome.record);
285
299
  appendLogLine({ event: "record", record: outcome.record });
286
300
  invokeOnRecord(outcome.record);
@@ -312,6 +326,13 @@ export async function runCliPrompt(opts) {
312
326
  const settle = (kind, payload) => {
313
327
  if (settlementStarted)
314
328
  return;
329
+ // Denied calls still without a result (a cancel/budget race, an abnormal
330
+ // exit, or a turn that ended without the denial the hook owes) are reported
331
+ // alongside the real outcome, never instead of it.
332
+ for (const escape of hookMonitor.settle())
333
+ noteHookEscape(escape);
334
+ if (kind === "resolve" && hookEscapes.length > 0)
335
+ payload = { ...payload, hookEscapes: [...hookEscapes] };
315
336
  settlementStarted = true;
316
337
  opts.signal?.removeEventListener("abort", onAbort);
317
338
  // Abort teardown can outlive the direct child's close event while a
@@ -329,7 +350,7 @@ export async function runCliPrompt(opts) {
329
350
  return;
330
351
  }
331
352
  if (kind === "resolve")
332
- resolve(payload);
353
+ resolve({ ...payload, settledAt: Date.now() });
333
354
  else
334
355
  reject(payload);
335
356
  });
@@ -470,6 +491,11 @@ export async function runCliPrompt(opts) {
470
491
  }
471
492
  }
472
493
  };
494
+ const stopForPolicyFailure = (error) => {
495
+ engineMismatchDetected = true; // Stops all further consumer output.
496
+ cancellationTeardown ??= teardownChildTree().then(() => ({ ok: true }), (error) => ({ ok: false, error }));
497
+ settle("reject", error);
498
+ };
473
499
  let engineMismatchError;
474
500
  handleEngineMismatch = (mismatch) => {
475
501
  if (engineMismatchError !== undefined)
@@ -491,8 +517,7 @@ export async function runCliPrompt(opts) {
491
517
  system_version: mismatch.systemVersion ?? null,
492
518
  reason: mismatch.reason,
493
519
  });
494
- cancellationTeardown = teardownChildTree().then(() => ({ ok: true }), (error) => ({ ok: false, error }));
495
- settle("reject", engineMismatchError);
520
+ stopForPolicyFailure(engineMismatchError);
496
521
  };
497
522
  const onAbort = () => {
498
523
  if (aborted)
@@ -580,6 +605,8 @@ export async function runCliPrompt(opts) {
580
605
  // The result itself is in memory; diagnostics are best-effort.
581
606
  await raceWithTimeout(logChain, LOG_DRAIN_TIMEOUT_MS);
582
607
  settle("resolve", {
608
+ spawnedAt,
609
+ settledAt: 0, // Filled at settlement, after the teardown barrier.
583
610
  sessionId,
584
611
  goalSummary: announcedGoalSummary,
585
612
  systemVersion: announcedSystemVersion,
@@ -656,7 +683,9 @@ export function requireSessionId(result, context) {
656
683
  },
657
684
  });
658
685
  }
659
- /** Settled timeout data; stream records are deliberately non-serializable. */
686
+ /** Settled timeout data; stream records are deliberately non-serializable.
687
+ * Without a partial result (teardown rejection), aborted means abort was issued,
688
+ * not that the process was observed aborting. */
660
689
  export class ResponseTimeoutError extends RuntimeError {
661
690
  constructor(budgetMs, stage, commandLabel, partialResult, cause) {
662
691
  super("RESPONSE_TIMEOUT", `${stage} timed out after ${budgetMs}ms.`, stage, {
@@ -666,8 +695,9 @@ export class ResponseTimeoutError extends RuntimeError {
666
695
  command_label: commandLabel ?? null,
667
696
  record_count: partialResult?.records.length ?? 0,
668
697
  partial_output_chars: partialResult?.records.reduce((count, record) => count + (record.role === "assistant" && typeof record.content === "string" ? record.content.length : 0), 0) ?? 0,
669
- aborted: true,
698
+ aborted: partialResult?.aborted ?? true,
670
699
  ...(partialResult ? { settled_post_abort: true } : {}),
700
+ ...(partialResult?.hookEscapes?.length ? { hook_escapes: partialResult.hookEscapes } : {}),
671
701
  },
672
702
  });
673
703
  this.name = "ResponseTimeoutError";
@@ -772,11 +802,11 @@ function buildArgs(opts) {
772
802
  args.push("--skills-dir", dir);
773
803
  }
774
804
  }
775
- // NOTE: `opts.thinking === false` is intentionally NOT translated into a
776
- // `--no-thinking` argv flag. kimi-code 0.1.1 rejects unknown options and
777
- // has no per-spawn thinking control — the Round 2 multi-agent review
778
- // caught this. The option stays in CliClientOptions for future wiring
779
- // when upstream adds the flag (see field doc).
805
+ // NOTE: thinking effort is requested through the env binding, never CLI argv.
806
+ // Non-trait-driven providers or a base level already off ignore it silently;
807
+ // an alwaysThinking model receives off unnormalized. stream-json carries no
808
+ // thinking deltas (writeThinkingDelta() {} in the JSON writer), so the plugin
809
+ // cannot observe whether the request was honoured.
780
810
  // -p accepts the prompt as the option value. We pass it as a separate argv
781
811
  // entry so prompts with leading dashes or whitespace are not interpreted as
782
812
  // additional flags.
@@ -785,6 +815,8 @@ function buildArgs(opts) {
785
815
  }
786
816
  function buildEnv(opts) {
787
817
  const env = { ...opts.env };
818
+ if (opts.thinkingEffort !== undefined)
819
+ env.KIMI_MODEL_THINKING_EFFORT = opts.thinkingEffort;
788
820
  // 2.2.0 audit: ambient trust starts project MCP stdio servers outside PreToolUse.
789
821
  delete env.KIMI_CODE_TRUST_WORKSPACE;
790
822
  // kimi-code 0.33.0 inverted its CLI engine default: an unflagged `kimi -p`