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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +27 -0
- package/README.md +5 -5
- package/agents/kimi-ask.md +5 -1
- package/agents/kimi-challenge.md +4 -2
- package/agents/kimi-pursue.md +3 -1
- package/agents/kimi-rescue.md +5 -1
- package/agents/kimi-review.md +4 -2
- package/agents/kimi-swarm-write.md +3 -1
- package/agents/kimi-swarm.md +3 -1
- package/commands/ask.md +5 -3
- package/commands/challenge.md +5 -3
- package/commands/pursue.md +5 -1
- package/commands/rescue.md +5 -3
- package/commands/review.md +5 -3
- package/commands/swarm.md +5 -1
- package/dist/cli-client.js +42 -10
- package/dist/commands/ask.js +14 -7
- package/dist/commands/cli-helpers.js +66 -4
- package/dist/commands/pursue.js +7 -3
- package/dist/commands/rescue.js +16 -10
- package/dist/commands/result.js +5 -1
- package/dist/commands/review-gate.js +21 -14
- package/dist/commands/review.js +9 -5
- package/dist/commands/status.js +2 -2
- package/dist/commands/swarm.js +10 -4
- package/dist/help.js +1 -1
- package/dist/hook-escape.js +71 -0
- package/dist/hooks/approval-policy.js +17 -27
- package/dist/hooks/config-safety.js +15 -7
- package/dist/job-store.js +52 -7
- package/dist/kimi-engine.js +2 -0
- package/dist/kimi-errors.js +1 -1
- package/dist/kimi-timeouts.js +6 -10
- package/dist/kimi-version-probe.js +2 -2
- package/dist/parsing.js +59 -53
- package/dist/session-recovery.js +203 -0
- package/dist/vendor/smol-toml/date.js +50 -21
- package/dist/vendor/smol-toml/error.js +6 -2
- package/dist/vendor/smol-toml/extract.js +259 -66
- package/dist/vendor/smol-toml/parse.js +64 -48
- package/dist/vendor/smol-toml/primitive.js +107 -135
- package/dist/vendor/smol-toml/struct.js +106 -134
- package/dist/vendor/smol-toml/util.js +22 -78
- package/dist/version.js +1 -1
- package/docs/models.md +10 -0
- package/docs/registry-releases.md +24 -1
- package/docs/safety.md +59 -2
- package/package.json +1 -1
- package/plugins/kimi-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/kimi-codex/dist/cli-client.js +42 -10
- package/plugins/kimi-codex/dist/commands/ask.js +14 -7
- package/plugins/kimi-codex/dist/commands/cli-helpers.js +66 -4
- package/plugins/kimi-codex/dist/commands/pursue.js +7 -3
- package/plugins/kimi-codex/dist/commands/rescue.js +16 -10
- package/plugins/kimi-codex/dist/commands/result.js +5 -1
- package/plugins/kimi-codex/dist/commands/review-gate.js +21 -14
- package/plugins/kimi-codex/dist/commands/review.js +9 -5
- package/plugins/kimi-codex/dist/commands/status.js +2 -2
- package/plugins/kimi-codex/dist/commands/swarm.js +10 -4
- package/plugins/kimi-codex/dist/help.js +1 -1
- package/plugins/kimi-codex/dist/hook-escape.js +71 -0
- package/plugins/kimi-codex/dist/hooks/approval-policy.js +17 -27
- package/plugins/kimi-codex/dist/hooks/config-safety.js +15 -7
- package/plugins/kimi-codex/dist/job-store.js +52 -7
- package/plugins/kimi-codex/dist/kimi-engine.js +2 -0
- package/plugins/kimi-codex/dist/kimi-errors.js +1 -1
- package/plugins/kimi-codex/dist/kimi-timeouts.js +6 -10
- package/plugins/kimi-codex/dist/kimi-version-probe.js +2 -2
- package/plugins/kimi-codex/dist/parsing.js +59 -53
- package/plugins/kimi-codex/dist/session-recovery.js +203 -0
- package/plugins/kimi-codex/dist/vendor/smol-toml/date.js +50 -21
- package/plugins/kimi-codex/dist/vendor/smol-toml/error.js +6 -2
- package/plugins/kimi-codex/dist/vendor/smol-toml/extract.js +259 -66
- package/plugins/kimi-codex/dist/vendor/smol-toml/parse.js +64 -48
- package/plugins/kimi-codex/dist/vendor/smol-toml/primitive.js +107 -135
- package/plugins/kimi-codex/dist/vendor/smol-toml/struct.js +106 -134
- package/plugins/kimi-codex/dist/vendor/smol-toml/util.js +22 -78
- package/plugins/kimi-codex/dist/version.js +1 -1
- package/plugins/kimi-codex/skills/kimi-ask/SKILL.md +4 -2
- package/plugins/kimi-codex/skills/kimi-challenge/SKILL.md +4 -2
- package/plugins/kimi-codex/skills/kimi-pursue/SKILL.md +3 -1
- package/plugins/kimi-codex/skills/kimi-rescue/SKILL.md +4 -2
- package/plugins/kimi-codex/skills/kimi-review/SKILL.md +4 -2
- package/plugins/kimi-codex/skills/kimi-setup/SKILL.md +2 -0
- package/plugins/kimi-codex/skills/kimi-swarm/SKILL.md +3 -1
- package/plugins/kimi-codex/skills/kimi-swarm-write/SKILL.md +3 -1
package/dist/commands/ask.js
CHANGED
|
@@ -17,7 +17,7 @@ import { readArtifact, renderManagedJobOutput, writeArtifact } from "../render.j
|
|
|
17
17
|
import { classifyManagedCommandFailure } from "../kimi-errors.js";
|
|
18
18
|
import { startBackgroundJob } from "../background-spawn.js";
|
|
19
19
|
import { hookRefusalDetails, hookRefusalRetryProtocol, maybeWarnHookMissing, verifyHookInstalled, } from "../hooks/install.js";
|
|
20
|
-
import { captureTimeoutPartialOutput, assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing } from "./cli-helpers.js";
|
|
20
|
+
import { warnInheritedBudget, captureTimeoutPartialOutput, assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing, warnHookEscapes } from "./cli-helpers.js";
|
|
21
21
|
import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js";
|
|
22
22
|
// v1.0 cutover note (PR 2):
|
|
23
23
|
//
|
|
@@ -77,13 +77,17 @@ export async function runAsk(argv, context) {
|
|
|
77
77
|
command_type: "ask",
|
|
78
78
|
cwd: context.cwd,
|
|
79
79
|
model: parsed.model ?? null,
|
|
80
|
-
thinking:
|
|
80
|
+
thinking: null,
|
|
81
|
+
thinking_effort: parsed.thinkingEffort ?? null,
|
|
81
82
|
background: parsed.background,
|
|
82
83
|
budget_ms: parsed.budgetMs ?? (sessionResolution.sourceJob?.operation_kind === "ask" ? sessionResolution.sourceJob.budget_ms : null) ?? null,
|
|
84
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit"
|
|
85
|
+
: sessionResolution.sourceJob?.operation_kind === "ask" && sessionResolution.sourceJob.budget_ms !== null ? "inherited" : "default",
|
|
83
86
|
pid: parsed.background ? null : process.pid,
|
|
84
87
|
kimi_pid: null,
|
|
85
88
|
status: "running",
|
|
86
89
|
kimi_session_id: sessionResolution.kimiSessionId,
|
|
90
|
+
kimi_session_id_source: sessionResolution.sourceJob?.kimi_session_id_source ?? null,
|
|
87
91
|
...persistedExecutionPlanFields(executionPlan),
|
|
88
92
|
agent_profile: ASK_AGENT_PROFILE_PLACEHOLDER,
|
|
89
93
|
prompt_digest: digestPrompt(askPrompt),
|
|
@@ -105,6 +109,7 @@ export async function runAsk(argv, context) {
|
|
|
105
109
|
await markJobFailed(store, paths, job, classified, askConfig.cancellation.failedSummary, { phase: "failed" });
|
|
106
110
|
throw classified;
|
|
107
111
|
}
|
|
112
|
+
warnInheritedBudget(job, context.stderr);
|
|
108
113
|
if (parsed.background) {
|
|
109
114
|
return startBackgroundJob(job, askPrompt, context, paths, {
|
|
110
115
|
workerKind: "ask",
|
|
@@ -170,6 +175,7 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
170
175
|
prompt,
|
|
171
176
|
commandLabel: "ask",
|
|
172
177
|
model: job.model ?? undefined,
|
|
178
|
+
thinkingEffort: job.thinking_effort ?? undefined,
|
|
173
179
|
resumeSessionId: job.kimi_session_id ?? undefined,
|
|
174
180
|
logPath: job.stream_log_path,
|
|
175
181
|
signal: handlers.signal,
|
|
@@ -179,17 +185,17 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
179
185
|
throw new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.afterPrompt, "ask.runtime");
|
|
180
186
|
}
|
|
181
187
|
assertCliResultSuccess(result, "ask.runtime");
|
|
188
|
+
warnHookEscapes(result, "ask", context.stderr);
|
|
182
189
|
// Persist whichever session id kimi actually announced. For fresh
|
|
183
190
|
// sessions this is the only chance to record it. For resumed
|
|
184
191
|
// sessions it should match the input, but capture anyway in case
|
|
185
192
|
// kimi-code mints a new id on each turn.
|
|
186
193
|
if (result.sessionId !== undefined &&
|
|
187
|
-
result.sessionId.length > 0
|
|
188
|
-
result.sessionId !== job.kimi_session_id) {
|
|
194
|
+
result.sessionId.length > 0) {
|
|
189
195
|
// length>0 guard: empty-string capture would poison the row. The
|
|
190
196
|
// warning helper's null-ish check would also fire but only after
|
|
191
197
|
// the bad write. (Kimi alpha.4 challenge finding #3.)
|
|
192
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
198
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
193
199
|
}
|
|
194
200
|
await syncKimiSessionTitle({
|
|
195
201
|
promptText: prompt,
|
|
@@ -219,6 +225,9 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
219
225
|
}) ?? job);
|
|
220
226
|
}
|
|
221
227
|
catch (error) {
|
|
228
|
+
const classified = error instanceof RuntimeError && error.stage === "ask.hook-check" ? error
|
|
229
|
+
: classifyManagedCommandFailure(error, "ask", job.job_id, { background: job.background, budgetMs: job.budget_ms ?? KIMI_ASK_PROMPT_TIMEOUT_MS });
|
|
230
|
+
const partialOutput = await captureTimeoutPartialOutput(classified, store, job, context.env, handlers?.signal);
|
|
222
231
|
if (handlers?.cancelling) {
|
|
223
232
|
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, "ask.runtime", error instanceof Error ? { cause: error } : undefined);
|
|
224
233
|
return await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError, { phase: "cancelled" });
|
|
@@ -231,8 +240,6 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
231
240
|
await markJobFailed(store, paths, job, error, cancel.failedSummary, { phase: "failed" });
|
|
232
241
|
throw error;
|
|
233
242
|
}
|
|
234
|
-
const classified = classifyManagedCommandFailure(error, "ask", job.job_id, { background: job.background, budgetMs: job.budget_ms ?? KIMI_ASK_PROMPT_TIMEOUT_MS });
|
|
235
|
-
const partialOutput = captureTimeoutPartialOutput(classified, store, job);
|
|
236
243
|
await markJobFailed(store, paths, job, classified, cancel.failedSummary, { phase: "failed", partialOutput });
|
|
237
244
|
throw classified;
|
|
238
245
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import { RuntimeError } from "../errors.js";
|
|
2
2
|
import { ResponseTimeoutError } from "../cli-client.js";
|
|
3
3
|
import { observedExecutionFields } from "../kimi-engine.js";
|
|
4
|
+
import { resolveKimiHome } from "../kimi-home.js";
|
|
5
|
+
import { recoverSessionIdFromStore } from "../session-recovery.js";
|
|
6
|
+
import { formatBudgetDuration } from "../render.js";
|
|
4
7
|
/**
|
|
5
8
|
* Reassemble prose final text from cli-client records.
|
|
6
9
|
*
|
|
@@ -112,12 +115,42 @@ export function assertCliResultSuccess(result, stage) {
|
|
|
112
115
|
});
|
|
113
116
|
}
|
|
114
117
|
}
|
|
115
|
-
/** Timeout-only capture
|
|
116
|
-
|
|
118
|
+
/** Timeout-only capture. Cancellation takes precedence, including while the
|
|
119
|
+
* asynchronous store scan is in flight. No title sync on failure. */
|
|
120
|
+
export async function captureTimeoutPartialOutput(classified, store, job, env, cancellationSignal) {
|
|
121
|
+
if (cancellationSignal?.aborted)
|
|
122
|
+
return undefined;
|
|
117
123
|
const timeout = classified.cause;
|
|
118
124
|
if (!(timeout instanceof ResponseTimeoutError) || !timeout.partialResult)
|
|
119
125
|
return undefined;
|
|
120
126
|
const result = timeout.partialResult;
|
|
127
|
+
let sessionId = result.sessionId;
|
|
128
|
+
let source = sessionId ? "announced" : null;
|
|
129
|
+
const details = classified instanceof RuntimeError ? classified.details : timeout.details;
|
|
130
|
+
details.kimi_session_id_source = job.kimi_session_id_source;
|
|
131
|
+
// The persisted plan is plugin-owned. Recovery never runs on cancellation,
|
|
132
|
+
// v1, successful turns, teardown rejection, or an already-known resume id.
|
|
133
|
+
if (!sessionId && !job.kimi_session_id && job.intended_engine === "native-v2") {
|
|
134
|
+
// Without the system.version marker the row has no proven engine, and
|
|
135
|
+
// resume would refuse the id as lineage-unknown; do not advertise one.
|
|
136
|
+
if (result.observedEngine === null) {
|
|
137
|
+
details.session_recovery = "engine_unobserved";
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
const recovered = await recoverSessionIdFromStore({
|
|
141
|
+
kimiHome: resolveKimiHome(env, job.cwd), cwd: job.cwd,
|
|
142
|
+
spawnedAt: result.spawnedAt, settledAt: result.settledAt, promptDigest: job.prompt_digest,
|
|
143
|
+
store, jobId: job.job_id,
|
|
144
|
+
});
|
|
145
|
+
sessionId = recovered.sessionId;
|
|
146
|
+
if (sessionId)
|
|
147
|
+
source = "recovered_session_dir";
|
|
148
|
+
else
|
|
149
|
+
details.session_recovery = recovered.reason;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (cancellationSignal?.aborted)
|
|
153
|
+
return undefined;
|
|
121
154
|
// Best-effort metadata only. The row is still `running`, and a session id
|
|
122
155
|
// written here can collide with `jobs_running_session_idx` when a resume of
|
|
123
156
|
// the same session was started while this job ran. A store error must never
|
|
@@ -125,11 +158,22 @@ export function captureTimeoutPartialOutput(classified, store, job) {
|
|
|
125
158
|
// than the metadata, so swallow and fall through.
|
|
126
159
|
try {
|
|
127
160
|
store.updateRunningJob(job.job_id, observedExecutionFields(result));
|
|
128
|
-
if (
|
|
129
|
-
|
|
161
|
+
if (sessionId) {
|
|
162
|
+
const updated = source === "recovered_session_dir"
|
|
163
|
+
? store.claimRecoveredSessionId(job.job_id, sessionId)
|
|
164
|
+
: store.updateRunningJob(job.job_id, { kimi_session_id: sessionId, kimi_session_id_source: source });
|
|
165
|
+
if (updated?.kimi_session_id === sessionId && updated.kimi_session_id_source === source) {
|
|
166
|
+
details.kimi_session_id = sessionId;
|
|
167
|
+
details.kimi_session_id_source = source;
|
|
168
|
+
}
|
|
169
|
+
else
|
|
170
|
+
details[source === "recovered_session_dir" ? "session_recovery" : "session_id_persistence"] = "persistence_failed";
|
|
130
171
|
}
|
|
131
172
|
}
|
|
132
173
|
catch {
|
|
174
|
+
// `session_recovery` describes only the recovery branch; an announced id or
|
|
175
|
+
// the provenance update failing is a different fact.
|
|
176
|
+
details[source === "recovered_session_dir" ? "session_recovery" : "session_id_persistence"] = "persistence_failed";
|
|
133
177
|
// Diagnostics stay in the stream log; the failure transition proceeds.
|
|
134
178
|
}
|
|
135
179
|
return {
|
|
@@ -141,3 +185,21 @@ export function captureTimeoutPartialOutput(classified, store, job) {
|
|
|
141
185
|
budgetMs: timeout.details.budget_ms,
|
|
142
186
|
};
|
|
143
187
|
}
|
|
188
|
+
/** One-line human summary of hook-escape findings, or undefined when none. */
|
|
189
|
+
export function describeHookEscapes(result) {
|
|
190
|
+
const escapes = result.hookEscapes ?? [];
|
|
191
|
+
if (escapes.length === 0)
|
|
192
|
+
return undefined;
|
|
193
|
+
const first = escapes[0];
|
|
194
|
+
return `safety hook notice: ${escapes.length} policy-denied tool call(s) did not come back as the managed hook's denial (first: ${first.tool_name} ${first.kind}). Detection evidence only — the call may have been rejected upstream before the hook ran, blocked by another hook, or executed because the hook drifted. Run /kimi:setup --check; details in \`result <jobId> --json\` (hook_escapes).`;
|
|
195
|
+
}
|
|
196
|
+
export function warnHookEscapes(result, commandType, stderr) {
|
|
197
|
+
const note = describeHookEscapes(result);
|
|
198
|
+
if (note !== undefined)
|
|
199
|
+
stderr.write(`[${commandType}] ${note}\n`);
|
|
200
|
+
}
|
|
201
|
+
export function warnInheritedBudget(job, stderr) {
|
|
202
|
+
if (job.budget_source === "inherited" && job.budget_ms !== null) {
|
|
203
|
+
stderr.write(`[${job.command_type}] budget ${formatBudgetDuration(job.budget_ms)} inherited from job ${job.resumed_from_job_id}; pass --budget to override\n`);
|
|
204
|
+
}
|
|
205
|
+
}
|
package/dist/commands/pursue.js
CHANGED
|
@@ -14,7 +14,7 @@ import { ensurePluginPaths, resolvePluginPaths } from "../paths.js";
|
|
|
14
14
|
import { parsePursueArgs } from "../parsing.js";
|
|
15
15
|
import { readArtifact, renderManagedJobOutput, writeArtifact } from "../render.js";
|
|
16
16
|
import { hookRefusalDetails, hookRefusalRetryProtocol, maybeWarnHookMissing, verifyHookInstalled, } from "../hooks/install.js";
|
|
17
|
-
import { assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing } from "./cli-helpers.js";
|
|
17
|
+
import { assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing, warnHookEscapes } from "./cli-helpers.js";
|
|
18
18
|
import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js";
|
|
19
19
|
// /kimi:pursue — autonomous goal mode (kimi-code 0.8.0+ headless `/goal`).
|
|
20
20
|
//
|
|
@@ -141,9 +141,11 @@ export async function runPursue(argv, context) {
|
|
|
141
141
|
command_type: "rescue",
|
|
142
142
|
cwd: context.cwd,
|
|
143
143
|
model: parsed.model ?? null,
|
|
144
|
-
thinking:
|
|
144
|
+
thinking: null,
|
|
145
|
+
thinking_effort: parsed.thinkingEffort ?? null,
|
|
145
146
|
background: false,
|
|
146
147
|
budget_ms: parsed.budgetMs ?? KIMI_PURSUE_DEFAULT_BUDGET_MS,
|
|
148
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
147
149
|
pid: process.pid,
|
|
148
150
|
kimi_pid: null,
|
|
149
151
|
status: "running",
|
|
@@ -232,10 +234,12 @@ async function executePursueJob(jobId, prompt, objective, budgetMs, context) {
|
|
|
232
234
|
commandLabel: "rescue",
|
|
233
235
|
trustedWorkspaceRoot: job.cwd,
|
|
234
236
|
model: job.model ?? undefined,
|
|
237
|
+
thinkingEffort: job.thinking_effort ?? undefined,
|
|
235
238
|
logPath: job.stream_log_path,
|
|
236
239
|
signal: handlers.signal,
|
|
237
240
|
}, budgetMs, "pursue.prompt");
|
|
238
241
|
store.updateRunningJob(job.job_id, observedExecutionFields(result));
|
|
242
|
+
warnHookEscapes(result, "pursue", context.stderr);
|
|
239
243
|
if (handlers.cancelling) {
|
|
240
244
|
throw new RuntimeError("PURSUE_CANCELLED", "Pursue cancelled by user request.", "pursue.runtime");
|
|
241
245
|
}
|
|
@@ -250,7 +254,7 @@ async function executePursueJob(jobId, prompt, objective, budgetMs, context) {
|
|
|
250
254
|
if (result.sessionId !== undefined &&
|
|
251
255
|
result.sessionId.length > 0 &&
|
|
252
256
|
result.sessionId !== job.kimi_session_id) {
|
|
253
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
257
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
254
258
|
}
|
|
255
259
|
await syncKimiSessionTitle({
|
|
256
260
|
promptText: objective,
|
package/dist/commands/rescue.js
CHANGED
|
@@ -17,7 +17,7 @@ import { parseRescueArgs } from "../parsing.js";
|
|
|
17
17
|
import { readArtifact, renderManagedJobOutput, writeArtifact } from "../render.js";
|
|
18
18
|
import { startBackgroundJob } from "../background-spawn.js";
|
|
19
19
|
import { hookRefusalDetails, hookRefusalRetryProtocol, maybeWarnHookMissing, verifyHookInstalled, } from "../hooks/install.js";
|
|
20
|
-
import { captureTimeoutPartialOutput, assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing } from "./cli-helpers.js";
|
|
20
|
+
import { warnInheritedBudget, captureTimeoutPartialOutput, assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing, warnHookEscapes } from "./cli-helpers.js";
|
|
21
21
|
import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js";
|
|
22
22
|
export { describeMissingResult } from "../background-spawn.js";
|
|
23
23
|
// v1.0 cutover note (PR 3):
|
|
@@ -69,13 +69,17 @@ export async function runRescue(argv, context) {
|
|
|
69
69
|
command_type: "rescue",
|
|
70
70
|
cwd: context.cwd,
|
|
71
71
|
model: parsed.model ?? null,
|
|
72
|
-
thinking:
|
|
72
|
+
thinking: null,
|
|
73
|
+
thinking_effort: parsed.thinkingEffort ?? null,
|
|
73
74
|
background: parsed.background,
|
|
74
75
|
budget_ms: parsed.budgetMs ?? (sessionResolution.sourceJob?.operation_kind === "rescue" ? sessionResolution.sourceJob.budget_ms : null) ?? null,
|
|
76
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit"
|
|
77
|
+
: sessionResolution.sourceJob?.operation_kind === "rescue" && sessionResolution.sourceJob.budget_ms !== null ? "inherited" : "default",
|
|
75
78
|
pid: parsed.background ? null : process.pid,
|
|
76
79
|
kimi_pid: null,
|
|
77
80
|
status: "running",
|
|
78
81
|
kimi_session_id: sessionResolution.kimiSessionId,
|
|
82
|
+
kimi_session_id_source: sessionResolution.sourceJob?.kimi_session_id_source ?? null,
|
|
79
83
|
...persistedExecutionPlanFields(executionPlan),
|
|
80
84
|
agent_profile: RESCUE_AGENT_PROFILE_PLACEHOLDER,
|
|
81
85
|
prompt_digest: digestPrompt(prompt),
|
|
@@ -97,6 +101,7 @@ export async function runRescue(argv, context) {
|
|
|
97
101
|
await markJobFailed(store, paths, job, classified, rescueConfig.cancellation.failedSummary, { phase: "failed" });
|
|
98
102
|
throw classified;
|
|
99
103
|
}
|
|
104
|
+
warnInheritedBudget(job, context.stderr);
|
|
100
105
|
if (parsed.background) {
|
|
101
106
|
return startBackgroundJob(job, prompt, context, paths, {
|
|
102
107
|
workerKind: "rescue",
|
|
@@ -184,6 +189,7 @@ export async function executeRescueJob(jobId, prompt, context, options) {
|
|
|
184
189
|
commandLabel: "rescue",
|
|
185
190
|
trustedWorkspaceRoot: job.cwd,
|
|
186
191
|
model: job.model ?? undefined,
|
|
192
|
+
thinkingEffort: job.thinking_effort ?? undefined,
|
|
187
193
|
resumeSessionId: job.kimi_session_id ?? undefined,
|
|
188
194
|
logPath: job.stream_log_path,
|
|
189
195
|
signal: handlers.signal,
|
|
@@ -195,12 +201,12 @@ export async function executeRescueJob(jobId, prompt, context, options) {
|
|
|
195
201
|
throw new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.afterPrompt, "rescue.runtime");
|
|
196
202
|
}
|
|
197
203
|
assertCliResultSuccess(result, "rescue.runtime");
|
|
204
|
+
warnHookEscapes(result, "rescue", context.stderr);
|
|
198
205
|
if (result.sessionId !== undefined &&
|
|
199
|
-
result.sessionId.length > 0
|
|
200
|
-
result.sessionId !== job.kimi_session_id) {
|
|
206
|
+
result.sessionId.length > 0) {
|
|
201
207
|
// length>0 guard: empty-string capture would poison the row. (Kimi
|
|
202
208
|
// alpha.4 challenge finding #3.)
|
|
203
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
209
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
204
210
|
}
|
|
205
211
|
await syncKimiSessionTitle({
|
|
206
212
|
promptText: prompt,
|
|
@@ -246,16 +252,16 @@ export async function executeRescueJob(jobId, prompt, context, options) {
|
|
|
246
252
|
}) ?? job);
|
|
247
253
|
}
|
|
248
254
|
catch (error) {
|
|
249
|
-
if (handlers.cancelling) {
|
|
250
|
-
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, "rescue.runtime", error instanceof Error ? { cause: error } : undefined);
|
|
251
|
-
return await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError, { phase: "cancelled" });
|
|
252
|
-
}
|
|
253
255
|
const classified = classifyManagedCommandFailure(error, "rescue", job.job_id, {
|
|
254
256
|
preserveStage: true,
|
|
255
257
|
background: job.background,
|
|
256
258
|
budgetMs: job.budget_ms ?? KIMI_RESCUE_PROMPT_TIMEOUT_MS,
|
|
257
259
|
});
|
|
258
|
-
const partialOutput = captureTimeoutPartialOutput(classified, store, job);
|
|
260
|
+
const partialOutput = await captureTimeoutPartialOutput(classified, store, job, context.env, handlers.signal);
|
|
261
|
+
if (handlers.cancelling) {
|
|
262
|
+
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, "rescue.runtime", error instanceof Error ? { cause: error } : undefined);
|
|
263
|
+
return await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError, { phase: "cancelled" });
|
|
264
|
+
}
|
|
259
265
|
return await markJobFailed(store, paths, job, classified, cancel.failedSummary, { phase: "failed", partialOutput });
|
|
260
266
|
}
|
|
261
267
|
finally {
|
package/dist/commands/result.js
CHANGED
|
@@ -2,7 +2,7 @@ import { RuntimeError } from "../errors.js";
|
|
|
2
2
|
import { resolveRepoIdentity } from "../git.js";
|
|
3
3
|
import { sweepStaleJobs } from "../jobs.js";
|
|
4
4
|
import { reconcileHistoricalJobProvenance } from "../kimi-engine.js";
|
|
5
|
-
import { withJobStore } from "../job-store.js";
|
|
5
|
+
import { renderBudgetSource, withJobStore, parseHookEscapes } from "../job-store.js";
|
|
6
6
|
import { ensurePluginPaths, resolvePluginPaths } from "../paths.js";
|
|
7
7
|
import { parseJobLookupArgs } from "../parsing.js";
|
|
8
8
|
import { readArtifact, renderTerminalJobArtifact } from "../render.js";
|
|
@@ -43,6 +43,10 @@ function renderResultEnvelope(job, artifactPath, body) {
|
|
|
43
43
|
kind: job.command_type,
|
|
44
44
|
status: job.status,
|
|
45
45
|
budget_ms: job.budget_ms,
|
|
46
|
+
budget_source: renderBudgetSource(job),
|
|
47
|
+
thinking_effort_requested: job.thinking_effort ?? null,
|
|
48
|
+
hook_escapes: parseHookEscapes(job.hook_escapes),
|
|
49
|
+
kimi_session_id_source: job.kimi_session_id_source,
|
|
46
50
|
kimi_session_id: job.kimi_session_id,
|
|
47
51
|
// True when a budget timeout preserved assistant prose in the artifact.
|
|
48
52
|
partial_output: job.status === "failed" && Number(job.error?.details?.partial_output_chars ?? 0) > 0,
|
|
@@ -15,9 +15,10 @@ import { KIMI_REVIEW_GATE_TIMEOUT_MS, isTimeoutCode } from "../kimi-timeouts.js"
|
|
|
15
15
|
import { writeInvocationLogHeader } from "../logging.js";
|
|
16
16
|
import { ensurePluginPaths, resolvePluginPaths } from "../paths.js";
|
|
17
17
|
import { renderManagedJobOutput, writeArtifact, } from "../render.js";
|
|
18
|
+
import { validateThinkingEffort } from "../parsing.js";
|
|
18
19
|
import { maybeWarnHookMissing, verifyHookInstalled } from "../hooks/install.js";
|
|
19
20
|
import { resolveKimiHome } from "../kimi-home.js";
|
|
20
|
-
import { assertCliResultSuccess, reassembleProseFromRecords } from "./cli-helpers.js";
|
|
21
|
+
import { assertCliResultSuccess, describeHookEscapes, reassembleProseFromRecords } from "./cli-helpers.js";
|
|
21
22
|
const REVIEW_GATE_AGENT_PROFILE_PLACEHOLDER = "<cli-client>";
|
|
22
23
|
// v1.0 cutover note (PR 2):
|
|
23
24
|
//
|
|
@@ -82,18 +83,19 @@ export async function runReviewGateStopHook(payload, context) {
|
|
|
82
83
|
...payload,
|
|
83
84
|
cwd,
|
|
84
85
|
}, assistantMessage, context);
|
|
86
|
+
const note = output.hookEscapeNote !== undefined ? `Kimi review gate ${output.hookEscapeNote}` : undefined;
|
|
85
87
|
if (output.decision === "BLOCK" && output.confidence === "high") {
|
|
86
88
|
return {
|
|
87
89
|
decision: "block",
|
|
88
90
|
reason: buildBlockReason(output),
|
|
91
|
+
...(note !== undefined ? { systemMessage: note } : {}),
|
|
89
92
|
};
|
|
90
93
|
}
|
|
91
94
|
if (output.decision === "BLOCK") {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
};
|
|
95
|
+
const concern = `Kimi review gate noted concerns but allowed stop: ${output.summary}`;
|
|
96
|
+
return { systemMessage: note !== undefined ? `${concern}\n${note}` : concern };
|
|
95
97
|
}
|
|
96
|
-
return {};
|
|
98
|
+
return note !== undefined ? { systemMessage: note } : {};
|
|
97
99
|
}
|
|
98
100
|
catch (error) {
|
|
99
101
|
return {
|
|
@@ -105,6 +107,7 @@ function reviewGateSkipped(reason) {
|
|
|
105
107
|
return { systemMessage: `review-gate skipped: ${reason}` };
|
|
106
108
|
}
|
|
107
109
|
async function executeReviewGate(payload, assistantMessage, context) {
|
|
110
|
+
let hookEscapeNote;
|
|
108
111
|
const paths = resolvePluginPaths(context.env);
|
|
109
112
|
await ensurePluginPaths(paths);
|
|
110
113
|
const repoIdentity = await resolveRepoIdentity(payload.cwd);
|
|
@@ -121,6 +124,10 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
121
124
|
cwd: payload.cwd,
|
|
122
125
|
repoRoot: repoIdentity.repoRoot,
|
|
123
126
|
});
|
|
127
|
+
// Unset or empty → request "off" (the 8 s budget is why); "inherit" → export
|
|
128
|
+
// nothing; anything else is lowercased and syntax-checked like --thinking.
|
|
129
|
+
const gateThinking = context.env.KIMI_PLUGIN_CC_REVIEW_GATE_THINKING?.trim() || "off";
|
|
130
|
+
const thinkingEffort = gateThinking.toLowerCase() === "inherit" ? undefined : validateThinkingEffort(gateThinking, "review_gate.parse");
|
|
124
131
|
const configuredModel = context.env.KIMI_PLUGIN_CC_REVIEW_GATE_MODEL;
|
|
125
132
|
const model = configuredModel?.trim() ? configuredModel : undefined;
|
|
126
133
|
const executionPlan = await prepareKimiExecutionPlan({
|
|
@@ -148,11 +155,13 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
148
155
|
cwd: payload.cwd,
|
|
149
156
|
model: model ?? null,
|
|
150
157
|
thinking: false,
|
|
158
|
+
thinking_effort: thinkingEffort ?? null,
|
|
151
159
|
background: false,
|
|
152
160
|
pid: null,
|
|
153
161
|
kimi_pid: null,
|
|
154
162
|
status: "running",
|
|
155
163
|
kimi_session_id: null,
|
|
164
|
+
budget_source: "default",
|
|
156
165
|
...persistedExecutionPlanFields(executionPlan),
|
|
157
166
|
agent_profile: REVIEW_GATE_AGENT_PROFILE_PLACEHOLDER,
|
|
158
167
|
prompt_digest: digestPrompt(prompt),
|
|
@@ -177,17 +186,15 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
177
186
|
prompt,
|
|
178
187
|
commandLabel: "review_gate",
|
|
179
188
|
model,
|
|
180
|
-
//
|
|
181
|
-
|
|
182
|
-
// flag for this; control is config-based (default_thinking /
|
|
183
|
-
// [thinking].mode). The field carries intent through the
|
|
184
|
-
// contract; when upstream adds a per-spawn flag, buildArgs will
|
|
185
|
-
// translate it. (Round 2 Codex finding.)
|
|
186
|
-
thinking: false,
|
|
189
|
+
// Requested via env; provider/model may ignore it. The 8s budget still applies.
|
|
190
|
+
thinkingEffort,
|
|
187
191
|
logPath,
|
|
188
192
|
}, KIMI_REVIEW_GATE_TIMEOUT_MS, "review_gate.runtime");
|
|
189
193
|
activeStore.updateRunningJob(job.job_id, observedExecutionFields(result));
|
|
190
194
|
assertCliResultSuccess(result, "review_gate.runtime");
|
|
195
|
+
// Detection evidence only (runtime/hook-escape.ts): the gate stays fail-open
|
|
196
|
+
// and annotates its decision; the finding is also on the job row.
|
|
197
|
+
hookEscapeNote = describeHookEscapes(result);
|
|
191
198
|
if (result.sessionId !== undefined && result.sessionId.length > 0) {
|
|
192
199
|
// length>0 guard matches the other commands (Kimi alpha.4
|
|
193
200
|
// challenge finding #3 — defense-in-depth, since
|
|
@@ -195,7 +202,7 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
195
202
|
// can't synthesize empty strings today, but the guard locks the
|
|
196
203
|
// SQLite contract independent of upstream behavior).
|
|
197
204
|
activeStore.updateRunningJob(job.job_id, {
|
|
198
|
-
kimi_session_id: result.sessionId,
|
|
205
|
+
kimi_session_id_source: "announced", kimi_session_id: result.sessionId,
|
|
199
206
|
});
|
|
200
207
|
}
|
|
201
208
|
const finalText = reassembleProseFromRecords(result.records);
|
|
@@ -216,7 +223,7 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
216
223
|
final_output_path: artifactPath,
|
|
217
224
|
error: null,
|
|
218
225
|
});
|
|
219
|
-
return rendered.output;
|
|
226
|
+
return { ...rendered.output, hookEscapeNote };
|
|
220
227
|
}
|
|
221
228
|
catch (error) {
|
|
222
229
|
const classified = classifyManagedCommandFailure(error, "review_gate", job.job_id);
|
package/dist/commands/review.js
CHANGED
|
@@ -17,7 +17,7 @@ import { renderManagedJobOutput, writeArtifact } from "../render.js";
|
|
|
17
17
|
import { RuntimeError } from "../errors.js";
|
|
18
18
|
import { resolveRepoIdentity } from "../git.js";
|
|
19
19
|
import { hookRefusalDetails, hookRefusalRetryProtocol, maybeWarnHookMissing, verifyHookInstalled, } from "../hooks/install.js";
|
|
20
|
-
import { captureTimeoutPartialOutput, assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing } from "./cli-helpers.js";
|
|
20
|
+
import { captureTimeoutPartialOutput, assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing, warnHookEscapes } from "./cli-helpers.js";
|
|
21
21
|
import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js";
|
|
22
22
|
// v1.0 cutover note (PR 2):
|
|
23
23
|
//
|
|
@@ -79,9 +79,11 @@ export async function runReview(argv, context, commandType) {
|
|
|
79
79
|
command_type: commandType,
|
|
80
80
|
cwd: context.cwd,
|
|
81
81
|
model: parsed.model ?? null,
|
|
82
|
-
thinking:
|
|
82
|
+
thinking: null,
|
|
83
|
+
thinking_effort: parsed.thinkingEffort ?? null,
|
|
83
84
|
background: false,
|
|
84
85
|
budget_ms: parsed.budgetMs ?? null,
|
|
86
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
85
87
|
pid: process.pid,
|
|
86
88
|
kimi_pid: null,
|
|
87
89
|
status: "running",
|
|
@@ -112,6 +114,7 @@ export async function runReview(argv, context, commandType) {
|
|
|
112
114
|
prompt: previewPrompt,
|
|
113
115
|
commandLabel: commandType,
|
|
114
116
|
model: parsed.model,
|
|
117
|
+
thinkingEffort: parsed.thinkingEffort,
|
|
115
118
|
logPath,
|
|
116
119
|
signal: handlers.signal,
|
|
117
120
|
}, job.budget_ms ?? KIMI_REVIEW_PROMPT_TIMEOUT_MS, `${commandType}.prompt`);
|
|
@@ -120,6 +123,7 @@ export async function runReview(argv, context, commandType) {
|
|
|
120
123
|
throw new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.afterPrompt, `${commandType}.runtime`);
|
|
121
124
|
}
|
|
122
125
|
assertCliResultSuccess(result, `${commandType}.runtime`);
|
|
126
|
+
warnHookEscapes(result, commandType, context.stderr);
|
|
123
127
|
// Persist whichever session id kimi announced. Review never resumes,
|
|
124
128
|
// but the id is the only handle for post-hoc replay against
|
|
125
129
|
// ~/.kimi-code/sessions/.
|
|
@@ -128,7 +132,7 @@ export async function runReview(argv, context, commandType) {
|
|
|
128
132
|
// poison the row — consumers reading SQLite distinguish "missing"
|
|
129
133
|
// (NULL) from "captured" (non-empty UUID) only via NULL-ness.
|
|
130
134
|
// (Kimi alpha.4 challenge finding #3.)
|
|
131
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
135
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
132
136
|
}
|
|
133
137
|
await syncKimiSessionTitle({
|
|
134
138
|
promptText: previewPrompt,
|
|
@@ -159,13 +163,13 @@ export async function runReview(argv, context, commandType) {
|
|
|
159
163
|
return rendered.output;
|
|
160
164
|
}
|
|
161
165
|
catch (error) {
|
|
166
|
+
const classified = classifyManagedCommandFailure(error, commandType, job.job_id, { background: job.background, budgetMs: job.budget_ms ?? KIMI_REVIEW_PROMPT_TIMEOUT_MS });
|
|
167
|
+
const partialOutput = await captureTimeoutPartialOutput(classified, store, job, context.env, handlers.signal);
|
|
162
168
|
if (handlers.cancelling) {
|
|
163
169
|
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, `${commandType}.runtime`, error instanceof Error ? { cause: error } : undefined);
|
|
164
170
|
await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError);
|
|
165
171
|
throw cancelledError;
|
|
166
172
|
}
|
|
167
|
-
const classified = classifyManagedCommandFailure(error, commandType, job.job_id, { background: job.background, budgetMs: job.budget_ms ?? KIMI_REVIEW_PROMPT_TIMEOUT_MS });
|
|
168
|
-
const partialOutput = captureTimeoutPartialOutput(classified, store, job);
|
|
169
173
|
await markJobFailed(store, paths, job, classified, cancel.failedSummary, { partialOutput });
|
|
170
174
|
throw classified;
|
|
171
175
|
}
|
package/dist/commands/status.js
CHANGED
|
@@ -2,7 +2,7 @@ import { RuntimeError } from "../errors.js";
|
|
|
2
2
|
import { resolveRepoIdentity } from "../git.js";
|
|
3
3
|
import { sweepStaleJobs } from "../jobs.js";
|
|
4
4
|
import { reconcileHistoricalJobProvenance } from "../kimi-engine.js";
|
|
5
|
-
import { withJobStore } from "../job-store.js";
|
|
5
|
+
import { parseHookEscapes, renderBudgetSource, withJobStore } from "../job-store.js";
|
|
6
6
|
import { ensurePluginPaths, resolvePluginPaths } from "../paths.js";
|
|
7
7
|
import { parseJobLookupArgs } from "../parsing.js";
|
|
8
8
|
export async function runStatus(argv, context) {
|
|
@@ -22,6 +22,6 @@ export async function runStatus(argv, context) {
|
|
|
22
22
|
throw new RuntimeError("JOB_NOT_FOUND", "No matching job was found for status.", "status.lookup");
|
|
23
23
|
}
|
|
24
24
|
const job = await reconcileHistoricalJobProvenance(store, found);
|
|
25
|
-
return `${JSON.stringify(job, null, 2)}\n`;
|
|
25
|
+
return `${JSON.stringify({ ...job, thinking_effort_requested: job.thinking_effort ?? null, hook_escapes: parseHookEscapes(job.hook_escapes), budget_source: renderBudgetSource(job) }, null, 2)}\n`;
|
|
26
26
|
});
|
|
27
27
|
}
|
package/dist/commands/swarm.js
CHANGED
|
@@ -15,7 +15,7 @@ import { ensurePluginPaths, resolvePluginPaths } from "../paths.js";
|
|
|
15
15
|
import { MAX_DURATION_MS, parseSwarmArgs } from "../parsing.js";
|
|
16
16
|
import { readArtifact, renderManagedJobOutput, writeArtifact } from "../render.js";
|
|
17
17
|
import { hookRefusalDetails, hookRefusalRetryProtocol, maybeWarnHookMissing, verifyHookInstalled, } from "../hooks/install.js";
|
|
18
|
-
import { assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing } from "./cli-helpers.js";
|
|
18
|
+
import { assertCliResultSuccess, reassembleProseFromRecords, warnIfSessionIdMissing, warnHookEscapes } from "./cli-helpers.js";
|
|
19
19
|
import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js";
|
|
20
20
|
// /kimi:swarm — READ-ONLY parallel fan-out (kimi-code 0.12.0 AgentSwarm tool).
|
|
21
21
|
//
|
|
@@ -208,9 +208,11 @@ async function runReadSwarm(parsed, objective, context) {
|
|
|
208
208
|
command_type: "review",
|
|
209
209
|
cwd: context.cwd,
|
|
210
210
|
model: parsed.model ?? null,
|
|
211
|
-
thinking:
|
|
211
|
+
thinking: null,
|
|
212
|
+
thinking_effort: parsed.thinkingEffort ?? null,
|
|
212
213
|
background: false,
|
|
213
214
|
budget_ms: parsed.budgetMs ?? KIMI_SWARM_DEFAULT_BUDGET_MS,
|
|
215
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
214
216
|
pid: process.pid,
|
|
215
217
|
kimi_pid: null,
|
|
216
218
|
status: "running",
|
|
@@ -307,9 +309,11 @@ async function runWriteSwarm(parsed, objective, context) {
|
|
|
307
309
|
command_type: "rescue",
|
|
308
310
|
cwd: context.cwd,
|
|
309
311
|
model: parsed.model ?? null,
|
|
310
|
-
thinking:
|
|
312
|
+
thinking: null,
|
|
313
|
+
thinking_effort: parsed.thinkingEffort ?? null,
|
|
311
314
|
background: false,
|
|
312
315
|
budget_ms: parsed.budgetMs ?? KIMI_SWARM_DEFAULT_BUDGET_MS,
|
|
316
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
313
317
|
pid: process.pid,
|
|
314
318
|
kimi_pid: null,
|
|
315
319
|
status: "running",
|
|
@@ -491,6 +495,7 @@ writeMode) {
|
|
|
491
495
|
// by other labels). Only set in write mode.
|
|
492
496
|
trustedWorkspaceRoot: writeMode?.workspaceRoot,
|
|
493
497
|
model: job.model ?? undefined,
|
|
498
|
+
thinkingEffort: job.thinking_effort ?? undefined,
|
|
494
499
|
logPath: job.stream_log_path,
|
|
495
500
|
signal: handlers.signal,
|
|
496
501
|
}, budgetMs, "swarm.prompt");
|
|
@@ -499,10 +504,11 @@ writeMode) {
|
|
|
499
504
|
throw new RuntimeError("SWARM_CANCELLED", "Swarm cancelled by user request.", "swarm.runtime");
|
|
500
505
|
}
|
|
501
506
|
assertCliResultSuccess(result, "swarm.runtime");
|
|
507
|
+
warnHookEscapes(result, "swarm", context.stderr);
|
|
502
508
|
if (result.sessionId !== undefined &&
|
|
503
509
|
result.sessionId.length > 0 &&
|
|
504
510
|
result.sessionId !== job.kimi_session_id) {
|
|
505
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
511
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
506
512
|
}
|
|
507
513
|
await syncKimiSessionTitle({
|
|
508
514
|
promptText: objective,
|
package/dist/help.js
CHANGED
|
@@ -11,7 +11,7 @@ export function companionHelp(argv) {
|
|
|
11
11
|
: 1;
|
|
12
12
|
if (!hasHelpFlag(argv.slice(argumentStart)))
|
|
13
13
|
return undefined;
|
|
14
|
-
const suffix = " Use --help or -h among the leading flags (before any prompt text or --) to show this usage.";
|
|
14
|
+
const suffix = " Thinking effort is a per-run request, not a guarantee. Use --help or -h among the leading flags (before any prompt text or --) to show this usage.";
|
|
15
15
|
const usage = (name, positionals, flags, description) => `Usage: companion.sh ${name}${positionals ? ` ${positionals}` : ""}. ${description} Supported flags: ${flags}.${suffix}`;
|
|
16
16
|
switch (command) {
|
|
17
17
|
case "--help":
|