kimi-plugin-cc 2.2.2 → 2.4.0
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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +5 -3
- package/.mcp.json +13 -0
- package/CHANGELOG.md +18 -0
- package/README.md +57 -5
- package/agents/kimi-challenge.md +3 -3
- package/agents/kimi-pursue.md +1 -1
- package/agents/kimi-rescue.md +2 -2
- package/agents/kimi-review.md +3 -3
- package/commands/README.md +2 -2
- package/commands/challenge.md +1 -1
- package/commands/pursue.md +1 -1
- package/commands/review.md +1 -1
- package/dist/background-spawn.js +9 -17
- package/dist/cli-client.js +24 -63
- package/dist/commands/ask.js +28 -31
- package/dist/commands/cancel.js +50 -23
- package/dist/commands/cli-helpers.js +7 -16
- package/dist/commands/pursue.js +24 -33
- package/dist/commands/registry.js +6 -19
- package/dist/commands/rescue.js +23 -22
- package/dist/commands/review-gate.js +18 -28
- package/dist/commands/review.js +41 -45
- package/dist/commands/setup.js +85 -171
- package/dist/commands/swarm.js +107 -91
- package/dist/commands/worker.js +0 -6
- package/dist/companion.js +13 -40
- package/dist/git.js +14 -7
- package/dist/help.js +2 -0
- package/dist/hooks/approval-hook.js +9 -20
- package/dist/hooks/approval-policy.js +36 -69
- package/dist/hooks/config-safety.js +6 -4
- package/dist/hooks/install-paths.js +62 -138
- package/dist/hooks/install.js +37 -108
- package/dist/hooks/managed-block.js +88 -214
- package/dist/job-id.js +12 -0
- package/dist/job-store.js +65 -28
- package/dist/jobs.js +9 -1
- package/dist/kimi-command.js +1 -3
- package/dist/kimi-engine.js +1 -1
- package/dist/kimi-timeouts.js +9 -21
- package/dist/kimi-version-probe.js +16 -1210
- package/dist/mcp/binding.js +58 -0
- package/dist/mcp/job-control.js +345 -0
- package/dist/mcp/launcher.js +257 -0
- package/dist/mcp/operations.js +301 -0
- package/dist/mcp/protocol.js +275 -0
- package/dist/mcp/server.js +8 -0
- package/dist/mcp/stdio.js +78 -0
- package/dist/mcp/supervised-child.js +15 -0
- package/dist/mcp/tool-result.js +7 -0
- package/dist/mcp/workspace.js +34 -0
- package/dist/model-command.js +32 -0
- package/dist/native-v2-preflight.js +1 -1
- package/dist/parsing.js +4 -18
- package/dist/rescue-approval.js +78 -164
- package/dist/session-recovery.js +7 -10
- package/dist/stream-json.js +6 -174
- package/dist/version.js +1 -1
- package/docs/migration.md +2 -6
- package/docs/registry-releases.md +23 -7
- package/docs/safety.md +30 -14
- package/package.json +7 -3
- package/plugins/kimi-codex/.codex-plugin/plugin.json +8 -5
- package/plugins/kimi-codex/.mcp.json +28 -0
- package/plugins/kimi-codex/dist/background-spawn.js +9 -17
- package/plugins/kimi-codex/dist/cli-client.js +24 -63
- package/plugins/kimi-codex/dist/commands/ask.js +28 -31
- package/plugins/kimi-codex/dist/commands/cancel.js +50 -23
- package/plugins/kimi-codex/dist/commands/cli-helpers.js +7 -16
- package/plugins/kimi-codex/dist/commands/pursue.js +24 -33
- package/plugins/kimi-codex/dist/commands/registry.js +6 -19
- package/plugins/kimi-codex/dist/commands/rescue.js +23 -22
- package/plugins/kimi-codex/dist/commands/review-gate.js +18 -28
- package/plugins/kimi-codex/dist/commands/review.js +41 -45
- package/plugins/kimi-codex/dist/commands/setup.js +85 -171
- package/plugins/kimi-codex/dist/commands/swarm.js +107 -91
- package/plugins/kimi-codex/dist/commands/worker.js +0 -6
- package/plugins/kimi-codex/dist/companion.js +13 -40
- package/plugins/kimi-codex/dist/git.js +14 -7
- package/plugins/kimi-codex/dist/help.js +2 -0
- package/plugins/kimi-codex/dist/hooks/approval-hook.js +9 -20
- package/plugins/kimi-codex/dist/hooks/approval-policy.js +36 -69
- package/plugins/kimi-codex/dist/hooks/config-safety.js +6 -4
- package/plugins/kimi-codex/dist/hooks/install-paths.js +62 -138
- package/plugins/kimi-codex/dist/hooks/install.js +37 -108
- package/plugins/kimi-codex/dist/hooks/managed-block.js +88 -214
- package/plugins/kimi-codex/dist/job-id.js +12 -0
- package/plugins/kimi-codex/dist/job-store.js +65 -28
- package/plugins/kimi-codex/dist/jobs.js +9 -1
- package/plugins/kimi-codex/dist/kimi-command.js +1 -3
- package/plugins/kimi-codex/dist/kimi-engine.js +1 -1
- package/plugins/kimi-codex/dist/kimi-timeouts.js +9 -21
- package/plugins/kimi-codex/dist/kimi-version-probe.js +16 -1210
- package/plugins/kimi-codex/dist/mcp/binding.js +58 -0
- package/plugins/kimi-codex/dist/mcp/job-control.js +345 -0
- package/plugins/kimi-codex/dist/mcp/launcher.js +257 -0
- package/plugins/kimi-codex/dist/mcp/operations.js +301 -0
- package/plugins/kimi-codex/dist/mcp/protocol.js +275 -0
- package/plugins/kimi-codex/dist/mcp/server.js +8 -0
- package/plugins/kimi-codex/dist/mcp/stdio.js +78 -0
- package/plugins/kimi-codex/dist/mcp/supervised-child.js +15 -0
- package/plugins/kimi-codex/dist/mcp/tool-result.js +7 -0
- package/plugins/kimi-codex/dist/mcp/workspace.js +34 -0
- package/plugins/kimi-codex/dist/model-command.js +32 -0
- package/plugins/kimi-codex/dist/native-v2-preflight.js +1 -1
- package/plugins/kimi-codex/dist/parsing.js +4 -18
- package/plugins/kimi-codex/dist/rescue-approval.js +78 -164
- package/plugins/kimi-codex/dist/session-recovery.js +7 -10
- package/plugins/kimi-codex/dist/stream-json.js +6 -174
- package/plugins/kimi-codex/dist/version.js +1 -1
- package/plugins/kimi-codex/skills/kimi-ask/SKILL.md +2 -2
- package/plugins/kimi-codex/skills/kimi-cancel/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-challenge/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-pursue/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-replay/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-rescue/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-result/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-review/SKILL.md +3 -3
- package/plugins/kimi-codex/skills/kimi-setup/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-status/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-swarm/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-swarm-write/SKILL.md +1 -1
|
@@ -50,13 +50,9 @@ export async function verifyHookInstalled(env) {
|
|
|
50
50
|
configPath,
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
//
|
|
54
|
-
//
|
|
55
|
-
//
|
|
56
|
-
// reason; it never changes the installed=false decision.
|
|
57
|
-
//
|
|
58
|
-
// `hostId` selects THIS host's block in the shared config so Claude Code and
|
|
59
|
-
// Codex verify their own managed block independently (v1.7.0 host scoping).
|
|
53
|
+
// Classify command mismatches into actionable drift reasons without changing
|
|
54
|
+
// the installed=false decision. hostId isolates this host's block in the
|
|
55
|
+
// shared config.
|
|
60
56
|
const check = evaluateInstalled(raw, expected.command, {
|
|
61
57
|
hostId: resolveHostId(env, expected.hookScriptPath),
|
|
62
58
|
nodeExists: (binPath) => existsSync(binPath),
|
|
@@ -73,9 +69,8 @@ export async function verifyHookInstalled(env) {
|
|
|
73
69
|
...(check.drift !== undefined ? { drift: check.drift } : {}),
|
|
74
70
|
};
|
|
75
71
|
}
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
// readable (see point 3 above). Fail closed on any stat/access error.
|
|
72
|
+
// A byte-exact command does not prove the hook can run. Confirm the script
|
|
73
|
+
// remains readable and fail closed on every access error.
|
|
79
74
|
try {
|
|
80
75
|
await access(expected.hookScriptPath, fsConstants.R_OK);
|
|
81
76
|
}
|
|
@@ -86,61 +81,28 @@ export async function verifyHookInstalled(env) {
|
|
|
86
81
|
configPath,
|
|
87
82
|
};
|
|
88
83
|
}
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
// the thing that catches a dead Node. Two adversarial reviews (2026-07-25)
|
|
93
|
-
// rejected the original, wider rationale, and it was verified empirically:
|
|
94
|
-
//
|
|
95
|
-
// - It does NOT catch a dangling Homebrew symlink. A dangling symlink cannot
|
|
96
|
-
// be exec'd at all, and `command -v node` skips it, so companion.sh (which
|
|
97
|
-
// `exec`s the binary it resolves, scripts/companion.sh:34,50) lands on a
|
|
98
|
-
// DIFFERENT node. The expected command is recomputed from the live process
|
|
99
|
-
// on every call, so it changes, and plain byte-exact equality above
|
|
100
|
-
// already refuses — with a RECOVERABLE `drift` that /kimi:setup converges.
|
|
101
|
-
// - It does NOT catch the 2026-07-25 dead-node zombie (a config pinning
|
|
102
|
-
// ~/.hermes/node). That is a byte mismatch, likewise caught above.
|
|
103
|
-
// - On the default path it is close to self-evident: `resolveNodeBinary`
|
|
104
|
-
// returns the path THIS process was launched through, which therefore
|
|
105
|
-
// existed and was executable moments ago.
|
|
106
|
-
//
|
|
107
|
-
// THE EXACT PREDICATE it covers: config and expected command still match
|
|
108
|
-
// byte-for-byte, yet the Node token embedded in that command fails X_OK AT
|
|
109
|
-
// VERIFICATION TIME. Three reachable ways to get there:
|
|
84
|
+
// Confirm the pinned interpreter with a NARROW X_OK backstop. Interpreter
|
|
85
|
+
// moves that change the recomputed command are already refused as drift; this
|
|
86
|
+
// check covers only unchanged command bytes whose Node token fails X_OK now:
|
|
110
87
|
//
|
|
111
|
-
// 1. An absolute
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
// `chmod -x`'d. `realpathSync` still resolves it, so `preferStableNodePath`
|
|
119
|
-
// keeps argv0 and the bytes are unchanged — equality passes, X_OK fails.
|
|
120
|
-
// 3. Same, but the pathname is REMOVED after launch. `realpathSync` throws
|
|
121
|
-
// and we fall back to `execPath`, which in argv0===execPath layouts
|
|
122
|
-
// (nvm/asdf) is the identical spelling — so equality still passes while
|
|
123
|
-
// the path is gone.
|
|
88
|
+
// 1. An absolute KIMI_PLUGIN_CC_NODE_BIN override names a dead interpreter
|
|
89
|
+
// other than the running process, so launch never proved it executable.
|
|
90
|
+
// 2. The interpreter is chmodded after launch. realpathSync still resolves
|
|
91
|
+
// it, the preferred path and command bytes stay unchanged, but X_OK fails.
|
|
92
|
+
// 3. The pathname is removed after launch. realpathSync throws, and the
|
|
93
|
+
// execPath fallback can retain the same spelling, so equality still passes
|
|
94
|
+
// while the pinned path is gone.
|
|
124
95
|
//
|
|
125
|
-
//
|
|
126
|
-
//
|
|
127
|
-
//
|
|
128
|
-
//
|
|
129
|
-
// before every model spawn and so catches degradation since the last probe.
|
|
96
|
+
// Refusing these cases matters because a failed hook spawn is ALLOW upstream.
|
|
97
|
+
// This per-spawn check also catches degradation since setup's last execution
|
|
98
|
+
// probe. It proves only the exec bit, not a working Node, architecture, or
|
|
99
|
+
// version; setup's shell probe executes the byte-identical command instead.
|
|
130
100
|
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
// identical command (setup.ts::probeHook) and now fails install nonzero. The
|
|
134
|
-
// verifier runs on every spawn and cannot afford a fork, so it approximates.
|
|
101
|
+
// Fail closed on EVERY access error. Do not harmonize this with spawning code
|
|
102
|
+
// that ignores selected errnos: a security verifier cannot "try and see".
|
|
135
103
|
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
// and see; a security verifier cannot. Do not "harmonize" these.
|
|
139
|
-
//
|
|
140
|
-
// Not re-pin-recoverable: no `drift` is attached (drift only exists when the
|
|
141
|
-
// equality check FAILS, so it can never displace a recoverable path), and
|
|
142
|
-
// `hookRefusalDetails` therefore omits `retryable_after_setup`, which agent
|
|
143
|
-
// callers map to "surface and stop." Setup cannot conjure a working Node.
|
|
104
|
+
// This refusal carries no drift and therefore no retryable_after_setup field:
|
|
105
|
+
// setup cannot repair a broken Node installation.
|
|
144
106
|
try {
|
|
145
107
|
await access(expected.nodeBin, fsConstants.X_OK);
|
|
146
108
|
}
|
|
@@ -151,9 +113,6 @@ export async function verifyHookInstalled(env) {
|
|
|
151
113
|
`cannot spawn (kimi-code reads a failed hook as ALLOW). Repair the Node install, or set ` +
|
|
152
114
|
`KIMI_PLUGIN_CC_NODE_BIN to a valid Node >=22.5 executable and run /kimi:setup.`,
|
|
153
115
|
configPath,
|
|
154
|
-
// Machine-readable discriminator: this is the ONE refusal whose remedy is
|
|
155
|
-
// NOT "run /kimi:setup" (LLM-caller discipline — an agent cannot read the
|
|
156
|
-
// prose above, and every other refusal emits an identical `{config_path}`).
|
|
157
116
|
refusalKind: "node-bin-not-executable",
|
|
158
117
|
nodeBin: expected.nodeBin,
|
|
159
118
|
};
|
|
@@ -164,30 +123,10 @@ function resolveKimiCodeConfigPath(env) {
|
|
|
164
123
|
return path.join(resolveKimiHome(env), "config.toml");
|
|
165
124
|
}
|
|
166
125
|
/**
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Structured `details` payload for a hook-refusal `RuntimeError`. Single source
|
|
173
|
-
* of truth so all five model-spawning commands emit the same machine-readable
|
|
174
|
-
* shape — an LLM caller cannot see stderr, so anything it must act on has to
|
|
175
|
-
* ride the error's structured context (LLM-caller discipline, v0.3.6+).
|
|
176
|
-
*
|
|
177
|
-
* `drift_axis === "hook-script"` is the ONLY value a caller may treat as
|
|
178
|
-
* retryable (run /kimi:setup for this host, retry once). Its absence means the
|
|
179
|
-
* refusal is not a moved-path problem and re-running setup will not fix it.
|
|
180
|
-
*/
|
|
181
|
-
/**
|
|
182
|
-
* Caller-facing self-heal protocol, appended to every hook-refusal message.
|
|
183
|
-
*
|
|
184
|
-
* The slash-command wrappers are deliberately thin, so the retry protocol
|
|
185
|
-
* rides the refusal itself — the LLM caller reads it on stdout at exactly the
|
|
186
|
-
* moment it applies, and one source here serves both hosts and all surfaces
|
|
187
|
-
* (commands, agents, Codex skills) without duplicating it in each file.
|
|
188
|
-
* Mirrors the fuller contract in agents/*.md: re-pin via setup, retry ONCE,
|
|
189
|
-
* only on `retryable_after_setup: true` AND a zero setup exit; never the
|
|
190
|
-
* skip env. Embeds the resolved plugin root so the command is runnable as-is.
|
|
126
|
+
* Caller-facing repair protocol shared by every hook-refusal surface. Re-pin
|
|
127
|
+
* through the resolved plugin root, retry ONCE only when
|
|
128
|
+
* `retryable_after_setup` is literally true and setup exits zero, and never use
|
|
129
|
+
* the skip-check environment variable as a repair.
|
|
191
130
|
*/
|
|
192
131
|
export function hookRefusalRetryProtocol(env) {
|
|
193
132
|
const root = env.CLAUDE_PLUGIN_ROOT ?? env.PLUGIN_ROOT ?? "${CLAUDE_PLUGIN_ROOT}";
|
|
@@ -196,6 +135,13 @@ export function hookRefusalRetryProtocol(env) {
|
|
|
196
135
|
`if it exits 0, retry the refused command once. Anything else — or a second refusal — ` +
|
|
197
136
|
`surface the refusal instead of retrying.`);
|
|
198
137
|
}
|
|
138
|
+
/**
|
|
139
|
+
* Structured details for a hook-refusal RuntimeError. `retryable_after_setup`
|
|
140
|
+
* is present only for drift and is literally true only when setup can re-pin
|
|
141
|
+
* every differing token: hook-script drift, or node-bin/both drift whose Node
|
|
142
|
+
* tokens name the same file. A different interpreter is not automatically
|
|
143
|
+
* repairable. Callers must also require a zero setup exit before one retry.
|
|
144
|
+
*/
|
|
199
145
|
export function hookRefusalDetails(status) {
|
|
200
146
|
return {
|
|
201
147
|
config_path: status.configPath,
|
|
@@ -210,16 +156,6 @@ export function hookRefusalDetails(status) {
|
|
|
210
156
|
drift_axis: status.drift.axis,
|
|
211
157
|
drift_installed_command: status.drift.installedCommand,
|
|
212
158
|
drift_expected_command: status.drift.expectedCommand,
|
|
213
|
-
// Retryable exactly when EVERY differing token is benign:
|
|
214
|
-
// - the hook script moved → the install path is version-stamped, so
|
|
215
|
-
// setup re-pins it to the running install.
|
|
216
|
-
// - the node token changed spelling but names the SAME file → not
|
|
217
|
-
// an interpreter move (this is the v1.9.0 re-pin, which also
|
|
218
|
-
// moves the script, hence axis "both").
|
|
219
|
-
// A node token naming a DIFFERENT file is never retryable: the pinned
|
|
220
|
-
// interpreter may be gone, and a hook that cannot spawn exits 127,
|
|
221
|
-
// which kimi-code treats as ALLOW. Re-pinning would paper over a real
|
|
222
|
-
// enforcement gap instead of surfacing it.
|
|
223
159
|
retryable_after_setup: status.drift.axis === "hook-script" || status.drift.nodeInterpreterUnchanged === true,
|
|
224
160
|
}
|
|
225
161
|
: {}),
|
|
@@ -254,18 +190,11 @@ export function formatHookMissingWarning(status, commandLabel) {
|
|
|
254
190
|
"",
|
|
255
191
|
].join("\n");
|
|
256
192
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Process-lifetime latch so commands don't spam the warning on every
|
|
259
|
-
* call inside a single test run.
|
|
260
|
-
*/
|
|
193
|
+
/** Once-per-process latch for missing-hook warnings. */
|
|
261
194
|
let warnedThisProcess = false;
|
|
262
195
|
/**
|
|
263
|
-
* Emit the warning to stderr at most once per process.
|
|
264
|
-
*
|
|
265
|
-
* Why stderr rather than stdout: stdout is reserved for the command's
|
|
266
|
-
* load-bearing output (artifact prose, JSON envelopes). LLM-caller
|
|
267
|
-
* discipline says stderr is humans-only, and this warning is exactly
|
|
268
|
-
* that — a developer-facing nudge to run /kimi:setup before tagging.
|
|
196
|
+
* Emit the warning to stderr at most once per process. Stderr is for humans;
|
|
197
|
+
* stdout remains reserved for load-bearing command output.
|
|
269
198
|
*/
|
|
270
199
|
export function maybeWarnHookMissing(status, commandLabel, stderr = process.stderr) {
|
|
271
200
|
if (status.installed)
|