kimi-plugin-cc 2.0.8 → 2.2.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 +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +21 -0
- package/README.md +5 -5
- package/agents/kimi-ask.md +1 -1
- package/agents/kimi-challenge.md +1 -1
- package/agents/kimi-rescue.md +1 -1
- package/agents/kimi-review.md +1 -1
- package/commands/ask.md +1 -1
- package/commands/challenge.md +1 -1
- package/commands/rescue.md +1 -1
- package/commands/review.md +1 -1
- package/dist/cli-client.js +9 -3
- package/dist/commands/ask.js +10 -6
- package/dist/commands/cli-helpers.js +53 -4
- package/dist/commands/pursue.js +2 -1
- package/dist/commands/rescue.js +12 -9
- package/dist/commands/result.js +3 -1
- package/dist/commands/review-gate.js +2 -1
- package/dist/commands/review.js +4 -3
- package/dist/commands/status.js +2 -2
- package/dist/commands/swarm.js +3 -1
- package/dist/hooks/config-safety.js +15 -7
- package/dist/job-store.js +36 -4
- 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/registry-releases.md +22 -1
- package/docs/safety.md +49 -2
- package/package.json +1 -1
- package/plugins/kimi-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/kimi-codex/dist/cli-client.js +9 -3
- package/plugins/kimi-codex/dist/commands/ask.js +10 -6
- package/plugins/kimi-codex/dist/commands/cli-helpers.js +53 -4
- package/plugins/kimi-codex/dist/commands/pursue.js +2 -1
- package/plugins/kimi-codex/dist/commands/rescue.js +12 -9
- package/plugins/kimi-codex/dist/commands/result.js +3 -1
- package/plugins/kimi-codex/dist/commands/review-gate.js +2 -1
- package/plugins/kimi-codex/dist/commands/review.js +4 -3
- package/plugins/kimi-codex/dist/commands/status.js +2 -2
- package/plugins/kimi-codex/dist/commands/swarm.js +3 -1
- package/plugins/kimi-codex/dist/hooks/config-safety.js +15 -7
- package/plugins/kimi-codex/dist/job-store.js +36 -4
- 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 +1 -1
- package/plugins/kimi-codex/skills/kimi-challenge/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-rescue/SKILL.md +1 -1
- package/plugins/kimi-codex/skills/kimi-review/SKILL.md +1 -1
|
@@ -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
|
|
4
|
+
"version": "2.2.0",
|
|
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,27 @@
|
|
|
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.0 — 2026-10-15
|
|
6
|
+
|
|
7
|
+
- Port the vendored parser to unmodified smol-toml 1.9.1 JavaScript, closing
|
|
8
|
+
GHSA-r4xh-jqrq-34v2; adapt the config assignment walker and retain EOF-comment
|
|
9
|
+
protection with linear-scaling and shipped-mirror regressions.
|
|
10
|
+
- Recover native-v2 timeout session IDs only from exactly one bounded, matching
|
|
11
|
+
session-store candidate: created between spawn and settlement in the job's cwd,
|
|
12
|
+
and whose main journal opens with a user message carrying the job's exact prompt
|
|
13
|
+
(`prompt_digest`), so attribution is proof, not proximity. Persist
|
|
14
|
+
announced/recovered provenance in `kimi_session_id_source`, report recovery
|
|
15
|
+
refusals in error details (`session_recovery`), skip recovery when no
|
|
16
|
+
`system.version` marker was observed, and retain the existing lineage and raw
|
|
17
|
+
journal plan-taint checks on every resume.
|
|
18
|
+
- Expose `budget_source` in status and JSON results, and print inherited ask/rescue
|
|
19
|
+
budgets with their parent job at launch. Historical non-null budgets remain unknown.
|
|
20
|
+
- Allow 30 seconds for installed-state spawn-heavy tests; refresh install examples
|
|
21
|
+
and preserve the settled result's abort flag in timeout details.
|
|
22
|
+
- Permit deliberate plugin/CLI version-number alignment without treating the number
|
|
23
|
+
as compatibility evidence. CLI 2.2.0 remains the certified maximum, unchanged;
|
|
24
|
+
the certification table, hook policy, preflight closures and teardown remain unchanged.
|
|
25
|
+
|
|
5
26
|
## 2.0.8 — 2026-10-14
|
|
6
27
|
|
|
7
28
|
- 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
|
|
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
|
|
111
|
+
npm install --prefix ~/.local/share/kimi-plugin-cc kimi-plugin-cc@2.2.0
|
|
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
|
|
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
|
|
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
|
|
620
|
+
- Kimi Code CLI 2.2.0(2.1.1 も認証済み。プラグイン 2.2.0 の推奨バージョン)
|
|
621
621
|
|
|
622
622
|
現在、Windows には対応していません。ターミナルでバージョンを確認します。
|
|
623
623
|
|
package/agents/kimi-ask.md
CHANGED
|
@@ -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
|
package/agents/kimi-challenge.md
CHANGED
|
@@ -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.
|
|
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
|
package/agents/kimi-rescue.md
CHANGED
|
@@ -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
|
package/agents/kimi-review.md
CHANGED
|
@@ -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.
|
|
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
|
package/commands/ask.md
CHANGED
|
@@ -21,7 +21,7 @@ Supported flags:
|
|
|
21
21
|
|
|
22
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.
|
|
23
23
|
|
|
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
|
|
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 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
25
|
|
|
26
26
|
Return the companion stdout verbatim.
|
|
27
27
|
|
package/commands/challenge.md
CHANGED
|
@@ -18,7 +18,7 @@ Supported flags:
|
|
|
18
18
|
|
|
19
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`.
|
|
20
20
|
|
|
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
|
|
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 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
22
|
|
|
23
23
|
Return the companion stdout verbatim.
|
|
24
24
|
|
package/commands/rescue.md
CHANGED
|
@@ -21,7 +21,7 @@ Supported flags:
|
|
|
21
21
|
|
|
22
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.
|
|
23
23
|
|
|
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
|
|
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 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
25
|
|
|
26
26
|
Return the companion stdout verbatim.
|
|
27
27
|
|
package/commands/review.md
CHANGED
|
@@ -18,7 +18,7 @@ Supported flags:
|
|
|
18
18
|
|
|
19
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`.
|
|
20
20
|
|
|
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
|
|
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 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
22
|
|
|
23
23
|
Return the companion stdout verbatim.
|
|
24
24
|
|
package/dist/cli-client.js
CHANGED
|
@@ -84,7 +84,9 @@ export async function runCliPrompt(opts) {
|
|
|
84
84
|
});
|
|
85
85
|
}
|
|
86
86
|
let child;
|
|
87
|
+
let spawnedAt;
|
|
87
88
|
try {
|
|
89
|
+
spawnedAt = Date.now();
|
|
88
90
|
child = spawn(opts.command, args, {
|
|
89
91
|
cwd: opts.cwd,
|
|
90
92
|
env,
|
|
@@ -329,7 +331,7 @@ export async function runCliPrompt(opts) {
|
|
|
329
331
|
return;
|
|
330
332
|
}
|
|
331
333
|
if (kind === "resolve")
|
|
332
|
-
resolve(payload);
|
|
334
|
+
resolve({ ...payload, settledAt: Date.now() });
|
|
333
335
|
else
|
|
334
336
|
reject(payload);
|
|
335
337
|
});
|
|
@@ -580,6 +582,8 @@ export async function runCliPrompt(opts) {
|
|
|
580
582
|
// The result itself is in memory; diagnostics are best-effort.
|
|
581
583
|
await raceWithTimeout(logChain, LOG_DRAIN_TIMEOUT_MS);
|
|
582
584
|
settle("resolve", {
|
|
585
|
+
spawnedAt,
|
|
586
|
+
settledAt: 0, // Filled at settlement, after the teardown barrier.
|
|
583
587
|
sessionId,
|
|
584
588
|
goalSummary: announcedGoalSummary,
|
|
585
589
|
systemVersion: announcedSystemVersion,
|
|
@@ -656,7 +660,9 @@ export function requireSessionId(result, context) {
|
|
|
656
660
|
},
|
|
657
661
|
});
|
|
658
662
|
}
|
|
659
|
-
/** Settled timeout data; stream records are deliberately non-serializable.
|
|
663
|
+
/** Settled timeout data; stream records are deliberately non-serializable.
|
|
664
|
+
* Without a partial result (teardown rejection), aborted means abort was issued,
|
|
665
|
+
* not that the process was observed aborting. */
|
|
660
666
|
export class ResponseTimeoutError extends RuntimeError {
|
|
661
667
|
constructor(budgetMs, stage, commandLabel, partialResult, cause) {
|
|
662
668
|
super("RESPONSE_TIMEOUT", `${stage} timed out after ${budgetMs}ms.`, stage, {
|
|
@@ -666,7 +672,7 @@ export class ResponseTimeoutError extends RuntimeError {
|
|
|
666
672
|
command_label: commandLabel ?? null,
|
|
667
673
|
record_count: partialResult?.records.length ?? 0,
|
|
668
674
|
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,
|
|
675
|
+
aborted: partialResult?.aborted ?? true,
|
|
670
676
|
...(partialResult ? { settled_post_abort: true } : {}),
|
|
671
677
|
},
|
|
672
678
|
});
|
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 } from "./cli-helpers.js";
|
|
21
21
|
import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js";
|
|
22
22
|
// v1.0 cutover note (PR 2):
|
|
23
23
|
//
|
|
@@ -80,10 +80,13 @@ export async function runAsk(argv, context) {
|
|
|
80
80
|
thinking: parsed.thinking ?? null,
|
|
81
81
|
background: parsed.background,
|
|
82
82
|
budget_ms: parsed.budgetMs ?? (sessionResolution.sourceJob?.operation_kind === "ask" ? sessionResolution.sourceJob.budget_ms : null) ?? null,
|
|
83
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit"
|
|
84
|
+
: sessionResolution.sourceJob?.operation_kind === "ask" && sessionResolution.sourceJob.budget_ms !== null ? "inherited" : "default",
|
|
83
85
|
pid: parsed.background ? null : process.pid,
|
|
84
86
|
kimi_pid: null,
|
|
85
87
|
status: "running",
|
|
86
88
|
kimi_session_id: sessionResolution.kimiSessionId,
|
|
89
|
+
kimi_session_id_source: sessionResolution.sourceJob?.kimi_session_id_source ?? null,
|
|
87
90
|
...persistedExecutionPlanFields(executionPlan),
|
|
88
91
|
agent_profile: ASK_AGENT_PROFILE_PLACEHOLDER,
|
|
89
92
|
prompt_digest: digestPrompt(askPrompt),
|
|
@@ -105,6 +108,7 @@ export async function runAsk(argv, context) {
|
|
|
105
108
|
await markJobFailed(store, paths, job, classified, askConfig.cancellation.failedSummary, { phase: "failed" });
|
|
106
109
|
throw classified;
|
|
107
110
|
}
|
|
111
|
+
warnInheritedBudget(job, context.stderr);
|
|
108
112
|
if (parsed.background) {
|
|
109
113
|
return startBackgroundJob(job, askPrompt, context, paths, {
|
|
110
114
|
workerKind: "ask",
|
|
@@ -184,12 +188,11 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
184
188
|
// sessions it should match the input, but capture anyway in case
|
|
185
189
|
// kimi-code mints a new id on each turn.
|
|
186
190
|
if (result.sessionId !== undefined &&
|
|
187
|
-
result.sessionId.length > 0
|
|
188
|
-
result.sessionId !== job.kimi_session_id) {
|
|
191
|
+
result.sessionId.length > 0) {
|
|
189
192
|
// length>0 guard: empty-string capture would poison the row. The
|
|
190
193
|
// warning helper's null-ish check would also fire but only after
|
|
191
194
|
// the bad write. (Kimi alpha.4 challenge finding #3.)
|
|
192
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
195
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
193
196
|
}
|
|
194
197
|
await syncKimiSessionTitle({
|
|
195
198
|
promptText: prompt,
|
|
@@ -219,6 +222,9 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
219
222
|
}) ?? job);
|
|
220
223
|
}
|
|
221
224
|
catch (error) {
|
|
225
|
+
const classified = error instanceof RuntimeError && error.stage === "ask.hook-check" ? error
|
|
226
|
+
: classifyManagedCommandFailure(error, "ask", job.job_id, { background: job.background, budgetMs: job.budget_ms ?? KIMI_ASK_PROMPT_TIMEOUT_MS });
|
|
227
|
+
const partialOutput = await captureTimeoutPartialOutput(classified, store, job, context.env, handlers?.signal);
|
|
222
228
|
if (handlers?.cancelling) {
|
|
223
229
|
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, "ask.runtime", error instanceof Error ? { cause: error } : undefined);
|
|
224
230
|
return await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError, { phase: "cancelled" });
|
|
@@ -231,8 +237,6 @@ export async function executeAskJob(jobId, prompt, context, options) {
|
|
|
231
237
|
await markJobFailed(store, paths, job, error, cancel.failedSummary, { phase: "failed" });
|
|
232
238
|
throw error;
|
|
233
239
|
}
|
|
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
240
|
await markJobFailed(store, paths, job, classified, cancel.failedSummary, { phase: "failed", partialOutput });
|
|
237
241
|
throw classified;
|
|
238
242
|
}
|
|
@@ -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,8 @@ export function captureTimeoutPartialOutput(classified, store, job) {
|
|
|
141
185
|
budgetMs: timeout.details.budget_ms,
|
|
142
186
|
};
|
|
143
187
|
}
|
|
188
|
+
export function warnInheritedBudget(job, stderr) {
|
|
189
|
+
if (job.budget_source === "inherited" && job.budget_ms !== null) {
|
|
190
|
+
stderr.write(`[${job.command_type}] budget ${formatBudgetDuration(job.budget_ms)} inherited from job ${job.resumed_from_job_id}; pass --budget to override\n`);
|
|
191
|
+
}
|
|
192
|
+
}
|
package/dist/commands/pursue.js
CHANGED
|
@@ -144,6 +144,7 @@ export async function runPursue(argv, context) {
|
|
|
144
144
|
thinking: parsed.thinking ?? null,
|
|
145
145
|
background: false,
|
|
146
146
|
budget_ms: parsed.budgetMs ?? KIMI_PURSUE_DEFAULT_BUDGET_MS,
|
|
147
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
147
148
|
pid: process.pid,
|
|
148
149
|
kimi_pid: null,
|
|
149
150
|
status: "running",
|
|
@@ -250,7 +251,7 @@ async function executePursueJob(jobId, prompt, objective, budgetMs, context) {
|
|
|
250
251
|
if (result.sessionId !== undefined &&
|
|
251
252
|
result.sessionId.length > 0 &&
|
|
252
253
|
result.sessionId !== job.kimi_session_id) {
|
|
253
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
254
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
254
255
|
}
|
|
255
256
|
await syncKimiSessionTitle({
|
|
256
257
|
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 } 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):
|
|
@@ -72,10 +72,13 @@ export async function runRescue(argv, context) {
|
|
|
72
72
|
thinking: parsed.thinking ?? null,
|
|
73
73
|
background: parsed.background,
|
|
74
74
|
budget_ms: parsed.budgetMs ?? (sessionResolution.sourceJob?.operation_kind === "rescue" ? sessionResolution.sourceJob.budget_ms : null) ?? null,
|
|
75
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit"
|
|
76
|
+
: sessionResolution.sourceJob?.operation_kind === "rescue" && sessionResolution.sourceJob.budget_ms !== null ? "inherited" : "default",
|
|
75
77
|
pid: parsed.background ? null : process.pid,
|
|
76
78
|
kimi_pid: null,
|
|
77
79
|
status: "running",
|
|
78
80
|
kimi_session_id: sessionResolution.kimiSessionId,
|
|
81
|
+
kimi_session_id_source: sessionResolution.sourceJob?.kimi_session_id_source ?? null,
|
|
79
82
|
...persistedExecutionPlanFields(executionPlan),
|
|
80
83
|
agent_profile: RESCUE_AGENT_PROFILE_PLACEHOLDER,
|
|
81
84
|
prompt_digest: digestPrompt(prompt),
|
|
@@ -97,6 +100,7 @@ export async function runRescue(argv, context) {
|
|
|
97
100
|
await markJobFailed(store, paths, job, classified, rescueConfig.cancellation.failedSummary, { phase: "failed" });
|
|
98
101
|
throw classified;
|
|
99
102
|
}
|
|
103
|
+
warnInheritedBudget(job, context.stderr);
|
|
100
104
|
if (parsed.background) {
|
|
101
105
|
return startBackgroundJob(job, prompt, context, paths, {
|
|
102
106
|
workerKind: "rescue",
|
|
@@ -196,11 +200,10 @@ export async function executeRescueJob(jobId, prompt, context, options) {
|
|
|
196
200
|
}
|
|
197
201
|
assertCliResultSuccess(result, "rescue.runtime");
|
|
198
202
|
if (result.sessionId !== undefined &&
|
|
199
|
-
result.sessionId.length > 0
|
|
200
|
-
result.sessionId !== job.kimi_session_id) {
|
|
203
|
+
result.sessionId.length > 0) {
|
|
201
204
|
// length>0 guard: empty-string capture would poison the row. (Kimi
|
|
202
205
|
// alpha.4 challenge finding #3.)
|
|
203
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
206
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
204
207
|
}
|
|
205
208
|
await syncKimiSessionTitle({
|
|
206
209
|
promptText: prompt,
|
|
@@ -246,16 +249,16 @@ export async function executeRescueJob(jobId, prompt, context, options) {
|
|
|
246
249
|
}) ?? job);
|
|
247
250
|
}
|
|
248
251
|
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
252
|
const classified = classifyManagedCommandFailure(error, "rescue", job.job_id, {
|
|
254
253
|
preserveStage: true,
|
|
255
254
|
background: job.background,
|
|
256
255
|
budgetMs: job.budget_ms ?? KIMI_RESCUE_PROMPT_TIMEOUT_MS,
|
|
257
256
|
});
|
|
258
|
-
const partialOutput = captureTimeoutPartialOutput(classified, store, job);
|
|
257
|
+
const partialOutput = await captureTimeoutPartialOutput(classified, store, job, context.env, handlers.signal);
|
|
258
|
+
if (handlers.cancelling) {
|
|
259
|
+
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, "rescue.runtime", error instanceof Error ? { cause: error } : undefined);
|
|
260
|
+
return await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError, { phase: "cancelled" });
|
|
261
|
+
}
|
|
259
262
|
return await markJobFailed(store, paths, job, classified, cancel.failedSummary, { phase: "failed", partialOutput });
|
|
260
263
|
}
|
|
261
264
|
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 } 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,8 @@ 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
|
+
kimi_session_id_source: job.kimi_session_id_source,
|
|
46
48
|
kimi_session_id: job.kimi_session_id,
|
|
47
49
|
// True when a budget timeout preserved assistant prose in the artifact.
|
|
48
50
|
partial_output: job.status === "failed" && Number(job.error?.details?.partial_output_chars ?? 0) > 0,
|
|
@@ -153,6 +153,7 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
153
153
|
kimi_pid: null,
|
|
154
154
|
status: "running",
|
|
155
155
|
kimi_session_id: null,
|
|
156
|
+
budget_source: "default",
|
|
156
157
|
...persistedExecutionPlanFields(executionPlan),
|
|
157
158
|
agent_profile: REVIEW_GATE_AGENT_PROFILE_PLACEHOLDER,
|
|
158
159
|
prompt_digest: digestPrompt(prompt),
|
|
@@ -195,7 +196,7 @@ async function executeReviewGate(payload, assistantMessage, context) {
|
|
|
195
196
|
// can't synthesize empty strings today, but the guard locks the
|
|
196
197
|
// SQLite contract independent of upstream behavior).
|
|
197
198
|
activeStore.updateRunningJob(job.job_id, {
|
|
198
|
-
kimi_session_id: result.sessionId,
|
|
199
|
+
kimi_session_id_source: "announced", kimi_session_id: result.sessionId,
|
|
199
200
|
});
|
|
200
201
|
}
|
|
201
202
|
const finalText = reassembleProseFromRecords(result.records);
|
package/dist/commands/review.js
CHANGED
|
@@ -82,6 +82,7 @@ export async function runReview(argv, context, commandType) {
|
|
|
82
82
|
thinking: parsed.thinking ?? null,
|
|
83
83
|
background: false,
|
|
84
84
|
budget_ms: parsed.budgetMs ?? null,
|
|
85
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
85
86
|
pid: process.pid,
|
|
86
87
|
kimi_pid: null,
|
|
87
88
|
status: "running",
|
|
@@ -128,7 +129,7 @@ export async function runReview(argv, context, commandType) {
|
|
|
128
129
|
// poison the row — consumers reading SQLite distinguish "missing"
|
|
129
130
|
// (NULL) from "captured" (non-empty UUID) only via NULL-ness.
|
|
130
131
|
// (Kimi alpha.4 challenge finding #3.)
|
|
131
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
132
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
132
133
|
}
|
|
133
134
|
await syncKimiSessionTitle({
|
|
134
135
|
promptText: previewPrompt,
|
|
@@ -159,13 +160,13 @@ export async function runReview(argv, context, commandType) {
|
|
|
159
160
|
return rendered.output;
|
|
160
161
|
}
|
|
161
162
|
catch (error) {
|
|
163
|
+
const classified = classifyManagedCommandFailure(error, commandType, job.job_id, { background: job.background, budgetMs: job.budget_ms ?? KIMI_REVIEW_PROMPT_TIMEOUT_MS });
|
|
164
|
+
const partialOutput = await captureTimeoutPartialOutput(classified, store, job, context.env, handlers.signal);
|
|
162
165
|
if (handlers.cancelling) {
|
|
163
166
|
const cancelledError = new RuntimeError(cancel.errorCodes.cancelled, cancel.cancelMessages.default, `${commandType}.runtime`, error instanceof Error ? { cause: error } : undefined);
|
|
164
167
|
await markJobCancelled(store, paths, job, cancel.cancelledSummary, cancelledError);
|
|
165
168
|
throw cancelledError;
|
|
166
169
|
}
|
|
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
170
|
await markJobFailed(store, paths, job, classified, cancel.failedSummary, { partialOutput });
|
|
170
171
|
throw classified;
|
|
171
172
|
}
|
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 { 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, budget_source: renderBudgetSource(job) }, null, 2)}\n`;
|
|
26
26
|
});
|
|
27
27
|
}
|
package/dist/commands/swarm.js
CHANGED
|
@@ -211,6 +211,7 @@ async function runReadSwarm(parsed, objective, context) {
|
|
|
211
211
|
thinking: parsed.thinking ?? null,
|
|
212
212
|
background: false,
|
|
213
213
|
budget_ms: parsed.budgetMs ?? KIMI_SWARM_DEFAULT_BUDGET_MS,
|
|
214
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
214
215
|
pid: process.pid,
|
|
215
216
|
kimi_pid: null,
|
|
216
217
|
status: "running",
|
|
@@ -310,6 +311,7 @@ async function runWriteSwarm(parsed, objective, context) {
|
|
|
310
311
|
thinking: parsed.thinking ?? null,
|
|
311
312
|
background: false,
|
|
312
313
|
budget_ms: parsed.budgetMs ?? KIMI_SWARM_DEFAULT_BUDGET_MS,
|
|
314
|
+
budget_source: parsed.budgetMs !== undefined ? "explicit" : "default",
|
|
313
315
|
pid: process.pid,
|
|
314
316
|
kimi_pid: null,
|
|
315
317
|
status: "running",
|
|
@@ -502,7 +504,7 @@ writeMode) {
|
|
|
502
504
|
if (result.sessionId !== undefined &&
|
|
503
505
|
result.sessionId.length > 0 &&
|
|
504
506
|
result.sessionId !== job.kimi_session_id) {
|
|
505
|
-
store.updateRunningJob(job.job_id, { kimi_session_id: result.sessionId });
|
|
507
|
+
store.updateRunningJob(job.job_id, { kimi_session_id_source: "announced", kimi_session_id: result.sessionId });
|
|
506
508
|
}
|
|
507
509
|
await syncKimiSessionTitle({
|
|
508
510
|
promptText: objective,
|