kimi-plugin-cc 2.4.4 → 2.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +21 -0
  4. package/README.md +50 -34
  5. package/dist/commands/swarm.js +1 -1
  6. package/dist/dsh/companion.js +174 -0
  7. package/dist/dsh/index.js +156 -0
  8. package/dist/hooks/config-safety.js +3 -2
  9. package/dist/hooks/install-paths.js +2 -2
  10. package/dist/kimi-engine.js +1 -0
  11. package/dist/swarm-activation.js +1 -1
  12. package/dist/version.js +1 -1
  13. package/docs/migration.md +4 -4
  14. package/docs/models.md +5 -1
  15. package/docs/registry-releases.md +20 -17
  16. package/docs/safety.md +28 -15
  17. package/docs/swarm-recovery.md +1 -1
  18. package/docs/upstream-2.4.1-certification.md +54 -0
  19. package/package.json +41 -6
  20. package/plugins/kimi-codex/.codex-plugin/plugin.json +1 -1
  21. package/plugins/kimi-codex/dist/commands/swarm.js +1 -1
  22. package/plugins/kimi-codex/dist/dsh/companion.js +174 -0
  23. package/plugins/kimi-codex/dist/dsh/index.js +156 -0
  24. package/plugins/kimi-codex/dist/hooks/config-safety.js +3 -2
  25. package/plugins/kimi-codex/dist/hooks/install-paths.js +2 -2
  26. package/plugins/kimi-codex/dist/kimi-engine.js +1 -0
  27. package/plugins/kimi-codex/dist/swarm-activation.js +1 -1
  28. package/plugins/kimi-codex/dist/version.js +1 -1
  29. package/plugins/kimi-dsh/LICENSE +201 -0
  30. package/plugins/kimi-dsh/README.md +80 -0
  31. package/plugins/kimi-dsh/cordis.patch.yml +45 -0
  32. package/plugins/kimi-dsh/dist/background-spawn.js +216 -0
  33. package/plugins/kimi-dsh/dist/cli-cancellation.js +43 -0
  34. package/plugins/kimi-dsh/dist/cli-client.js +876 -0
  35. package/plugins/kimi-dsh/dist/commands/ask.js +336 -0
  36. package/plugins/kimi-dsh/dist/commands/cancel.js +216 -0
  37. package/plugins/kimi-dsh/dist/commands/cli-helpers.js +201 -0
  38. package/plugins/kimi-dsh/dist/commands/models.js +140 -0
  39. package/plugins/kimi-dsh/dist/commands/not-implemented.js +4 -0
  40. package/plugins/kimi-dsh/dist/commands/pursue.js +307 -0
  41. package/plugins/kimi-dsh/dist/commands/recover-swarm.js +135 -0
  42. package/plugins/kimi-dsh/dist/commands/registry.js +74 -0
  43. package/plugins/kimi-dsh/dist/commands/repair-sessions.js +160 -0
  44. package/plugins/kimi-dsh/dist/commands/replay.js +124 -0
  45. package/plugins/kimi-dsh/dist/commands/rescue.js +347 -0
  46. package/plugins/kimi-dsh/dist/commands/result.js +66 -0
  47. package/plugins/kimi-dsh/dist/commands/review-gate.js +390 -0
  48. package/plugins/kimi-dsh/dist/commands/review.js +220 -0
  49. package/plugins/kimi-dsh/dist/commands/setup.js +1047 -0
  50. package/plugins/kimi-dsh/dist/commands/status.js +27 -0
  51. package/plugins/kimi-dsh/dist/commands/swarm.js +754 -0
  52. package/plugins/kimi-dsh/dist/commands/worker.js +25 -0
  53. package/plugins/kimi-dsh/dist/companion.js +97 -0
  54. package/plugins/kimi-dsh/dist/config.js +22 -0
  55. package/plugins/kimi-dsh/dist/dsh/companion.js +174 -0
  56. package/plugins/kimi-dsh/dist/dsh/index.js +156 -0
  57. package/plugins/kimi-dsh/dist/errors.js +40 -0
  58. package/plugins/kimi-dsh/dist/git.js +224 -0
  59. package/plugins/kimi-dsh/dist/help.js +43 -0
  60. package/plugins/kimi-dsh/dist/hook-escape.js +71 -0
  61. package/plugins/kimi-dsh/dist/hooks/approval-hook.js +101 -0
  62. package/plugins/kimi-dsh/dist/hooks/approval-policy.js +211 -0
  63. package/plugins/kimi-dsh/dist/hooks/config-safety.js +653 -0
  64. package/plugins/kimi-dsh/dist/hooks/install-paths.js +428 -0
  65. package/plugins/kimi-dsh/dist/hooks/install.js +210 -0
  66. package/plugins/kimi-dsh/dist/hooks/managed-block.js +619 -0
  67. package/plugins/kimi-dsh/dist/hooks/review-gate-stop.js +19 -0
  68. package/plugins/kimi-dsh/dist/job-id.js +12 -0
  69. package/plugins/kimi-dsh/dist/job-store.js +659 -0
  70. package/plugins/kimi-dsh/dist/jobs.js +217 -0
  71. package/plugins/kimi-dsh/dist/kimi-command.js +70 -0
  72. package/plugins/kimi-dsh/dist/kimi-engine.js +632 -0
  73. package/plugins/kimi-dsh/dist/kimi-errors.js +260 -0
  74. package/plugins/kimi-dsh/dist/kimi-home.js +9 -0
  75. package/plugins/kimi-dsh/dist/kimi-timeouts.js +52 -0
  76. package/plugins/kimi-dsh/dist/kimi-version-probe.js +216 -0
  77. package/plugins/kimi-dsh/dist/logging.js +22 -0
  78. package/plugins/kimi-dsh/dist/mcp/binding.js +58 -0
  79. package/plugins/kimi-dsh/dist/mcp/job-control.js +345 -0
  80. package/plugins/kimi-dsh/dist/mcp/launcher.js +257 -0
  81. package/plugins/kimi-dsh/dist/mcp/operations.js +301 -0
  82. package/plugins/kimi-dsh/dist/mcp/protocol.js +275 -0
  83. package/plugins/kimi-dsh/dist/mcp/server.js +8 -0
  84. package/plugins/kimi-dsh/dist/mcp/stdio.js +78 -0
  85. package/plugins/kimi-dsh/dist/mcp/supervised-child.js +15 -0
  86. package/plugins/kimi-dsh/dist/mcp/tool-result.js +7 -0
  87. package/plugins/kimi-dsh/dist/mcp/workspace.js +34 -0
  88. package/plugins/kimi-dsh/dist/model-command.js +32 -0
  89. package/plugins/kimi-dsh/dist/native-v2-preflight.js +417 -0
  90. package/plugins/kimi-dsh/dist/package.json +1 -0
  91. package/plugins/kimi-dsh/dist/parsing.js +620 -0
  92. package/plugins/kimi-dsh/dist/paths.js +27 -0
  93. package/plugins/kimi-dsh/dist/plugin-data.js +98 -0
  94. package/plugins/kimi-dsh/dist/process-tree.js +479 -0
  95. package/plugins/kimi-dsh/dist/prompt-size.js +18 -0
  96. package/plugins/kimi-dsh/dist/render.js +177 -0
  97. package/plugins/kimi-dsh/dist/rescue-approval.js +865 -0
  98. package/plugins/kimi-dsh/dist/schemas/review-gate-output.js +43 -0
  99. package/plugins/kimi-dsh/dist/session-recovery.js +200 -0
  100. package/plugins/kimi-dsh/dist/session-title.js +293 -0
  101. package/plugins/kimi-dsh/dist/stream-json.js +346 -0
  102. package/plugins/kimi-dsh/dist/swarm-activation.js +834 -0
  103. package/plugins/kimi-dsh/dist/swarm-recovery.js +134 -0
  104. package/plugins/kimi-dsh/dist/types.js +1 -0
  105. package/plugins/kimi-dsh/dist/vendor/shell-quote/LICENSE +24 -0
  106. package/plugins/kimi-dsh/dist/vendor/shell-quote/index.js +1 -0
  107. package/plugins/kimi-dsh/dist/vendor/shell-quote/parse.js +229 -0
  108. package/plugins/kimi-dsh/dist/vendor/smol-toml/LICENSE +24 -0
  109. package/plugins/kimi-dsh/dist/vendor/smol-toml/date.js +156 -0
  110. package/plugins/kimi-dsh/dist/vendor/smol-toml/error.js +67 -0
  111. package/plugins/kimi-dsh/dist/vendor/smol-toml/extract.js +293 -0
  112. package/plugins/kimi-dsh/dist/vendor/smol-toml/parse.js +164 -0
  113. package/plugins/kimi-dsh/dist/vendor/smol-toml/primitive.js +151 -0
  114. package/plugins/kimi-dsh/dist/vendor/smol-toml/struct.js +156 -0
  115. package/plugins/kimi-dsh/dist/vendor/smol-toml/util.js +57 -0
  116. package/plugins/kimi-dsh/dist/version.js +7 -0
  117. package/plugins/kimi-dsh/package.json +48 -0
  118. package/plugins/kimi-dsh/scripts/companion.sh +37 -0
  119. package/plugins/kimi-dsh/scripts/review-gate-hook.sh +32 -0
@@ -9,7 +9,7 @@ import { assertExecutionPlanMatchesSpawn, assertNoUnsafeExperimentalSelector, }
9
9
  import { resolveKimiHome } from "./kimi-home.js";
10
10
  import { assertNativeV2Preflight } from "./native-v2-preflight.js";
11
11
  import { collectDescendantIdentities, collectProcessGroupsIdentities, probeProcessIdentity, revalidateProcessIdentities, waitForProcessTreeExit, } from "./process-tree.js";
12
- const PREACTIVATION_VERSIONS = ["2.3.2", "2.3.3", "2.4.0"];
12
+ const PREACTIVATION_VERSIONS = ["2.3.2", "2.3.3", "2.4.0", "2.4.1"];
13
13
  const READY_TIMEOUT_MS = 10_000;
14
14
  const REST_TIMEOUT_MS = 5_000;
15
15
  // Exact 2.4.0 can take longer than 5s to drain session/workspace lifecycle work.
package/dist/version.js CHANGED
@@ -4,4 +4,4 @@
4
4
  // and AGENTS.md on every release. A future improvement would read this from
5
5
  // package.json at build time, but that adds a build-step dependency we
6
6
  // don't want yet.
7
- export const KIMI_PLUGIN_CC_VERSION = "2.4.4";
7
+ export const KIMI_PLUGIN_CC_VERSION = "2.5.1";
package/docs/migration.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Compatibility and upgrades
2
2
 
3
- Plugin 2.4.4 certifies Kimi Code CLI 2.4.0 for all eight operations, alongside exact native-v2 versions `0.42.0`, `0.43.0`, `0.43.1`, `2.0.0`, `2.0.1`, `2.0.2`, `2.1.0`, `2.1.1`, `2.2.0`, `2.3.0`, `2.3.1`, `2.3.2`, and `2.3.3`. Later patches and minor releases are not accepted automatically. The npm distribution adds an installation channel; it does not change this compatibility table.
3
+ Plugin 2.4.5 certifies Kimi Code CLI 2.4.1 for all eight operations, alongside exact native-v2 versions `0.42.0`, `0.43.0`, `0.43.1`, `2.0.0`, `2.0.1`, `2.0.2`, `2.1.0`, `2.1.1`, `2.2.0`, `2.3.0`, `2.3.1`, `2.3.2`, `2.3.3`, and `2.4.0`. Later patches and minor releases are not accepted automatically. The npm distribution adds an installation channel; it does not change this compatibility table.
4
4
 
5
5
  Explicitly pinned legacy-v1 binaries remain supported within `KIMI_TESTED_MINORS`, through 0.41.x, subject to each operation's minimum version. The [runtime table](../runtime/kimi-engine.ts) is the authority.
6
6
 
@@ -8,11 +8,11 @@ Use the [README installation and update steps](../README.md) for Claude Code or
8
8
 
9
9
  ## Plugin versions and upgrades
10
10
 
11
- Plugin versions advance independently using ordinary SemVer and may deliberately align with a certified CLI release. Plugin 2.4.4 certifies exact CLI 2.4.0; the nearby numbers do not imply version alignment. Published versions and tags are never reused. Every upstream patch requires its own certification. The native-v2 no-plan profile, plugin/marketplace IDs and existing job store are preserved.
11
+ Plugin versions advance independently using ordinary SemVer and may deliberately align with a certified CLI release. Plugin 2.4.5 certifies exact CLI 2.4.1; the nearby numbers do not imply version alignment. Published versions and tags are never reused. Every upstream patch requires its own certification. The native-v2 no-plan profile, plugin/marketplace IDs and existing job store are preserved.
12
12
 
13
- ## CLI 2.3.2, 2.3.3 and 2.4.0 swarm activation
13
+ ## CLI 2.3.2, 2.3.3, 2.4.0 and 2.4.1 swarm activation
14
14
 
15
- Upstream 2.3.2 removes model self-activation of `AgentSwarm` in fresh print sessions. On exact 2.3.2, 2.3.3 and 2.4.0, swarm commands and MCP calls use the same `runSwarm` lifecycle:
15
+ Upstream 2.3.2 removes model self-activation of `AgentSwarm` in fresh print sessions. On exact 2.3.2, 2.3.3, 2.4.0 and 2.4.1, swarm commands and MCP calls use the same `runSwarm` lifecycle:
16
16
 
17
17
  1. A short-lived `web --no-open --host 127.0.0.1 --port 0 --log-level error` process uses authenticated loopback routes to verify the exact v2 server, choose the explicit or configured default model, create a session, bind the model and auto permission, enable and verify `swarm_mode`, and shut down. The child environment sets `KIMI_CODE_SESSION_IDLE_RECLAIM_MS=0` to disable ambient idle-session reclamation.
18
18
  2. One ordinary `kimi -p -r` prompt runner resumes that session. Its recorded session-id source is `preactivated`, and the returned print session must match it.
package/docs/models.md CHANGED
@@ -6,7 +6,7 @@ configured model for one task without changing that default.
6
6
  ## See configured models
7
7
 
8
8
  In Claude Code, run `/kimi:setup --models`. In Codex, ask `$kimi-setup` to list
9
- models. The underlying command is:
9
+ models. In DSH, run `/kimi-setup --models` (or `--models --json`). The underlying command is:
10
10
 
11
11
  ```sh
12
12
  "<plugin-root>/scripts/companion.sh" setup --models
@@ -35,6 +35,8 @@ several, and guide setup when there is none. They do not guess model IDs or
35
35
  silently substitute the default after an error. An explicit `-m` remains a
36
36
  pass-through alias, so upstream can resolve it or report an error.
37
37
 
38
+ DSH activations are one-shot and do not expose per-call model fields. Set `model` in the bundle's `kimi-plugin-cc` profile row to use one exact configured alias for every delegation from that profile; omit it to use the native Kimi default. This does not change the saved default or add fallback selection.
39
+
38
40
  Omitting `-m` uses the default for a **fresh** session. A resumed session keeps
39
41
  its previous model unless you supply `-m`. The optional review gate also uses
40
42
  the default unless `KIMI_PLUGIN_CC_REVIEW_GATE_MODEL` explicitly selects an alias.
@@ -87,6 +89,8 @@ including `kosongConfig/configSection.ts`, `envOverlay.ts`, and
87
89
 
88
90
  Use `--thinking off`, `--thinking high`, or `--thinking=<effort>` before the prompt. Values are lowercased and must match `/^[a-z][a-z0-9-]{0,31}$/` (a plugin-owned syntax bound; a future upstream token outside it is rejected before upstream sees it); upstream per-model `supportEfforts`, not a plugin enum, determines supported values. `--no-thinking` is an error: use `--thinking off`. In CLI 2.2.0 only the three Moonshot `kimi*` provider definitions are trait-driven. BYO providers ignore the request silently; an always-thinking model may remain thinking.
89
91
 
92
+ DSH forwards the profile's `thinkingEffort` value as `--thinking <effort>` on every delegation. Omission preserves the ambient operator value; the same provider and observability limits apply.
93
+
90
94
  Jobs persist nullable `thinking_effort`; status and `result --json` expose `thinking_effort_requested`, not observed effort. Detached ask/rescue workers replay the request. A resume without `--thinking` exports no new override (any ambient operator value remains). No config.toml write occurs.
91
95
 
92
96
  The review gate requests `off` by default. `KIMI_PLUGIN_CC_REVIEW_GATE_THINKING=inherit` exports no override; another non-empty value is lowercased and must match the same regex. Unset or empty means `off`; an invalid value makes the gate skip visibly. The gate remains fail-open on its 8 s timeout: a BYO provider or always-thinking model can ignore the request, and even an honoured request does not guarantee completion within the budget.
@@ -1,16 +1,14 @@
1
1
  # Registry releases
2
2
 
3
3
  The npm package `kimi-plugin-cc` ships the Claude plugin at its root and the
4
- self-contained Codex plugin under `plugins/kimi-codex`. GitHub marketplaces
5
- remain available. The package has no install scripts and no separate CLI.
4
+ self-contained Codex and DSH plugins under `plugins/`. DSH users install that
5
+ same root package with `dsh plugin --profile <name> add kimi-plugin-cc`.
6
+ GitHub marketplaces remain available. The package has no install scripts and
7
+ no separate CLI.
6
8
 
7
9
  ## Publishing status
8
10
 
9
- Plugin **2.4.4** adds exact CLI **2.4.0** certification for all eight operations,
10
- with the existing host-preactivated swarm lifecycle and durable recovery.
11
- See the [certification record](./upstream-2.4.0-certification.md).
12
- Release execution and registry verification are recorded in the release notes;
13
- publication uses the same validated-tarball OIDC workflow below.
11
+ Plugin **2.4.5** certifies exact CLI **2.4.1** for all eight operations with host-preactivated swarm sessions. [Release v2.4.5](https://github.com/linxule/kimi-plugin-cc/releases/tag/v2.4.5) is anchored at `de8c195c2986443a088b674717133b164d2e4ef2`; its [CI check](https://github.com/linxule/kimi-plugin-cc/actions/runs/41226096281) and [release-event publishing run](https://github.com/linxule/kimi-plugin-cc/actions/runs/41226438326) passed. The registry tarball has SHA-1 `39f97a6de4b26ad51ac77305054682fcd5cd0164`, contains 233 files, and matches the CI artifact byte-for-byte. Fresh registry installs passed setup/check and unsupported-version refusal for both Claude Code and Codex, and both compiled mirrors are byte-identical to the release checkout. See the [certification record](./upstream-2.4.1-certification.md) and structured verification at `.claude/kimi-code-research/release-2.4.5/registry-verification.json`.
14
12
 
15
13
  Plugin **2.4.2** adds durable interrupted-swarm recovery and Windows spawn diagnostics.
16
14
  Exact CLI certification remains unchanged through **2.3.2**; this is not a new
@@ -90,15 +88,18 @@ bun run build
90
88
  bun run generate:surfaces
91
89
  # Review and stage generated distributions before the drift gate.
92
90
  bun run check
93
- bun run check:package .tmp/npm
91
+ node scripts/check-package.mjs .tmp/npm
92
+ node scripts/check-dsh-package.mjs .tmp/dsh-npm
94
93
  ```
95
94
 
96
- The package check inspects the actual tarball, rejects sync-conflict copies in
95
+ The root package check inspects the actual tarball, rejects sync-conflict copies in
97
96
  any path component, verifies runtime copies and vendored licenses, and
98
- installs/checks the safety hook in isolated homes for both hosts. It also
97
+ installs/checks the safety hook in isolated homes for all three hosts. It also
99
98
  exercises unsupported-version refusal using a fake CLI and modern MCP discovery
100
- plus legacy initialization on both extracted compiled distributions. It does
101
- not invoke a model or read the maintainer's Kimi configuration.
99
+ plus legacy initialization on the extracted compiled distributions. The DSH
100
+ check installs that same root tarball into an isolated DSH home, verifies all
101
+ seven tools, and boots the Web host. Neither check invokes a model or reads the
102
+ maintainer's Kimi configuration.
102
103
 
103
104
  ## First publication (completed bootstrap reference)
104
105
 
@@ -135,8 +136,10 @@ operations; Bun remains the development toolchain.
135
136
 
136
137
  Push the reviewed release commit, wait for CI, tag it, and publish its GitHub
137
138
  release. `.github/workflows/publish.yml` runs on `release.published`; it checks
138
- the tag against `package.json`, runs the full gate and package smoke, then
139
- publishes the validated tarball through OIDC with provenance. The publish job
140
- has no source checkout or build scripts. A manual dispatch with an existing
141
- release tag is available for recovery after a verified publication failure.
142
- Check npm before retrying; released versions are immutable.
139
+ the tag against `package.json`, runs the full gate and both package smokes, then
140
+ publishes the root tarball through OIDC with provenance. The DSH smoke installs
141
+ that same tarball directly into an isolated DSH profile, so no second npm
142
+ package or Trusted Publishing binding is needed. The publish job has no source
143
+ checkout or build scripts. A manual dispatch with an existing release tag is
144
+ available for recovery after a verified publication failure. Check npm before
145
+ retrying; released versions are immutable.
package/docs/safety.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This guide describes the current checkout runtime. Read-only tasks deny file writes and shell commands. Rescue and pursue can edit your workspace. Write-swarm returns a patch from a temporary Git worktree.
4
4
 
5
- Native agent-core-v2 is certified at exact CLI versions `0.42.0`, `0.43.0`, `0.43.1`, `2.0.0`, `2.0.1`, `2.0.2`, `2.1.0`, `2.1.1`, `2.2.0`, `2.3.0`, `2.3.1`, `2.3.2`, `2.3.3`, and `2.4.0`, with plan mode disabled. The [runtime certification table](../runtime/kimi-engine.ts) controls routing. The hook is not an operating-system sandbox.
5
+ Native agent-core-v2 is certified at exact CLI versions `0.42.0`, `0.43.0`, `0.43.1`, `2.0.0`, `2.0.1`, `2.0.2`, `2.1.0`, `2.1.1`, `2.2.0`, `2.3.0`, `2.3.1`, `2.3.2`, `2.3.3`, `2.4.0`, and `2.4.1`, with plan mode disabled. The [runtime certification table](../runtime/kimi-engine.ts) controls routing. The hook is not an operating-system sandbox.
6
6
 
7
7
  ## Why the safety story is hook-based
8
8
 
@@ -78,20 +78,23 @@ Key constraints (verified by [`runtime/hooks/managed-block.ts`](../runtime/hooks
78
78
  7. **Serialized, identity-bound setup mutations.** Install and uninstall hold a private `0o600` sibling lock across the complete read-modify-write transaction. The candidate lock is published atomically; lock reads are no-follow, nonblocking, regular-file-only, and capped at 4 KiB. Acquisition is bounded, live owners are never stolen, stale recovery is guarded by a nonrecursive recovery lease, and inode/token ownership is rechecked before config mutation or lock removal. Simultaneous Claude Code/Codex setup runs therefore cannot lose either host's block, and a replaced lock is never treated as ours. A newly created Kimi home is `0o700`; atomic config writes remain `0o600`.
79
79
  8. **Inline hook arrays are normalized before insertion.** kimi-code accepts both `hooks = [...]` and `[[hooks]]`, but appending a managed array-of-tables block after an inline assignment can produce a conflicting document. Setup converts a valid inline hook array to canonical `[[hooks]]` tables before inserting the host block and emits an explicit warning that formatting and comments inside that assignment are normalized. Surrounding config bytes are preserved.
80
80
 
81
- ### Host scoping (Claude Code ↔ Codex share one config)
81
+ ### Host scoping (all hosts share one config)
82
82
 
83
83
  Claude Code and Codex install this plugin to **different, version-stamped
84
- paths** (`~/.claude/plugins/cache/…` vs `~/.codex/plugins/cache/…`) but read
85
- the **same** `~/.kimi-code/config.toml`. So the managed block is **host-scoped**:
84
+ paths** (`~/.claude/plugins/cache/…` vs `~/.codex/plugins/cache/…`), while DSH
85
+ uses its own profile package path. All read the **same**
86
+ `~/.kimi-code/config.toml`. So the managed block is **host-scoped**:
86
87
  its marker carries a `:<host-id>` suffix, and each host owns, verifies, and
87
88
  uninstalls only its **own** block.
88
89
 
89
90
  - **Host id** (`runtime/hooks/install-paths.ts::resolveHostId`) is derived
90
91
  version-independently from the hook path: `~/.claude/…` → `claude-code`,
91
- `~/.codex/…` → `codex`, else a stable `host-<sha1>` for dev checkouts. A
92
- plugin upgrade *refreshes* the same host's block rather than adding a new one.
93
- - **No clobbering.** `/kimi:setup` (Claude) and `$kimi-setup` (Codex) each write
94
- their own block and leave the other's byte-identical. Before v1.7.0 there was
92
+ `~/.codex/…` → `codex`, else a stable `host-<sha1>` for dev checkouts. DSH
93
+ explicitly pins `dsh`. A plugin upgrade *refreshes* the same host's block
94
+ rather than adding a new one.
95
+ - **No clobbering.** `/kimi:setup` (Claude), `$kimi-setup` (Codex), and
96
+ `/kimi-setup` (DSH) each write their own block and leave the others
97
+ byte-identical. Before v1.7.0 there was
95
98
  a single block exact-matched to the running host, so the two hosts overwrote
96
99
  each other and the loser's write-commands refused with "hook path drift."
97
100
  - **Enforcement is redundant-safe.** kimi-code fires *every* `[[hooks]]` entry
@@ -103,8 +106,8 @@ uninstalls only its **own** block.
103
106
  - **Migration + cleanup.** A pre-v1.7.0 un-suffixed block is adopted and
104
107
  converted in place by the current host on its next `/kimi:setup`. Orphaned,
105
108
  marker-less `[[hooks]]` entries that are unambiguously our approval hook
106
- (canonical command, `approval-hook.js` under a kimi-marketplace/kimi-plugin-cc
107
- tree) are pruned **host-scoped** (v1.8.2): install and scoped uninstall touch
109
+ (canonical command, `approval-hook.js` under a kimi-marketplace/kimi-plugin-cc/
110
+ dsh-kimi-plugin-cc tree) are pruned **host-scoped** (v1.8.2): install and scoped uninstall touch
108
111
  only tables whose command path derives to the *current* host. `/kimi:setup
109
112
  --uninstall` removes only the current host's block (plus legacy + this host's
110
113
  orphans); `/kimi:setup --uninstall --all` removes every host's block and every
@@ -123,6 +126,16 @@ uninstalls only its **own** block.
123
126
  hook and is left byte-untouched (pre-v1.8.2, the host-blind prune here caused
124
127
  each host's setup to disarm the other after any kimi login — the "seesaw").
125
128
 
129
+ ## DeepSeek Harness providers
130
+
131
+ The DSH bundle exposes the same seven operations as the other hosts: `kimi_ask`, `kimi_review`, `kimi_challenge`, `kimi_rescue`, `kimi_pursue`, `kimi_swarm`, and `kimi_swarm_write`. Each activation starts the existing companion through DSH's managed subprocess service and uses the same `kimi -p` transport, hook verification, exact-version certification, job store, and response or safety budgets. ACP is not used.
132
+
133
+ Run `/kimi-setup` explicitly before delegating. Installing or enabling the bundle does not modify Kimi configuration. DSH uses host id `dsh` and `$DSH_HOME/plugin-data/kimi-plugin-cc` unless an absolute data-root override selects another store. Its provider-owned environment clears other-host roots/data, hook/script overrides, trusted roots, and verification bypasses instead of inheriting them.
134
+
135
+ The parent receives only complete successful stdout. stderr remains on the host, and nonzero, empty, or truncated output becomes a bounded diagnostic rather than partial prose. Cancellation terminates the managed process range and waits for quiescence. DSH activation ids are distinct from companion job ids; use `/kimi-status`, `/kimi-result`, or `/kimi-cancel` for the persisted job.
136
+
137
+ Write boundaries are identical to the companion commands: rescue and pursue edit the real selected workspace, ask/review/challenge and read-only swarm deny writes and shell commands, and swarm-write works from born HEAD in a temporary worktree and returns a patch without applying or committing it. `/kimi-setup --uninstall` removes only the DSH managed block; the all-host uninstall flag is not exposed.
138
+
126
139
  ## The hook's per-command policy
127
140
 
128
141
  [`runtime/hooks/approval-policy.ts`](../runtime/hooks/approval-policy.ts) is the single source of truth:
@@ -205,13 +218,13 @@ If another installed host still points to an older hook, that hook may veto thes
205
218
  - **Resume is intentionally not exposed yet.** In goal mode `goal.summary` emits a *goalId* distinct from the resume-hint *sessionId*; `kimi -r <sessionId>` re-enters the session but not necessarily the goal continuation. The plugin captures and surfaces the goalId but does not offer `--resume` for pursue until that split is reconciled upstream — exposing it now would be a silent-failure trap. **Re-verified against kimi-code 0.26.0 (2026-07-16):** the headless CLI still has no argv, prompt syntax, or session-resume path that calls `resumeGoal()`. `parseHeadlessGoalCreate` (`apps/kimi-code/src/cli/goal-prompt.ts`) accepts only the `/goal <objective>` *create* shape on both the v1 and experimental-v2 drivers, and upstream's own docs (`docs/en/guides/goals.md`, § "Use goal mode carefully") state that in non-interactive prompt mode *only goal creation is supported* — goal management is a TUI/kimi-web control. PR #552 makes a plain `-r <sessionId>` correctly *restore* the paused goal snapshot, but nothing in the headless path *acts* on it; the real `resumeGoal()` is wired only to the TUI (`/goal resume`) and kimi-web RPC (PR #1693, web-only). Implementing `--resume` would therefore require either prompt-injected model compliance (rejected — the plugin bounds autonomy with hard limits, not model goodwill) or abandoning the subprocess model for kimi-web's RPC. Re-check if upstream ever ships a headless `goal resume` verb.
206
219
  - **A model-invocable `kimi-pursue` agent (v1.3) wraps this command.** The main thread can dispatch autonomous goal mode, not just the human-typed `/kimi:pursue` — the same command↔agent mirror as rescue/review/swarm. Auto-dispatch does NOT widen the blast radius: pursue runs under `commandLabel: "rescue"`, so the managed PreToolUse hook + workspace allowlist gate every tool call on every continuation turn (no git mutation), and the mandatory `--budget` wall-clock ceiling bounds the autonomy regardless of who launched it. Because it is write-capable AND autonomous — the plugin's highest blast radius — the agent's description requires an explicit user request for hands-off multi-turn pursuit, steers single bounded tasks to `kimi-rescue`, and never auto-promotes a fix or a question into a goal loop. Like the command, it refuses without the hook and offers no `--resume`.
207
220
 
208
- ## Swarm activation on CLI 2.3.2, 2.3.3 and 2.4.0
221
+ ## Swarm activation on CLI 2.3.2, 2.3.3, 2.4.0 and 2.4.1
209
222
 
210
223
  For interrupted runs, see [durable recovery and its explicit limits](swarm-recovery.md).
211
224
 
212
225
  Upstream 2.3.2 removes model self-activation of `AgentSwarm` in fresh print sessions. A rejected call can therefore coexist with zero child journals and a successful exit; a tool-call record, aggregate denial, or coordinator-produced patch does not prove fan-out. The plugin does not use prompt workarounds or replace its print transport with general RPC.
213
226
 
214
- For versions requiring activation (currently exact 2.3.2, 2.3.3 and 2.4.0), both slash-command and MCP swarm operations use the same `runSwarm` implementation and one ordinary `kimi -p -r` prompt runner per job, bracketed by short-lived host-managed web lifecycles:
227
+ For versions requiring activation (currently exact 2.3.2, 2.3.3, 2.4.0 and 2.4.1), both slash-command and MCP swarm operations use the same `runSwarm` implementation and one ordinary `kimi -p -r` prompt runner per job, bracketed by short-lived host-managed web lifecycles:
215
228
 
216
229
  1. The exact planned CLI starts `web --no-open --host 127.0.0.1 --port 0 --log-level error`. The child environment sets `KIMI_CODE_SESSION_IDLE_RECLAIM_MS=0`, so ambient idle-session reclamation cannot disrupt the plugin-owned lifecycle. The plugin accepts only the expected loopback ready URL, uses a supplied token for authenticated REST requests, and keeps that token in memory, never writing it to logs. `/api/v1/meta` must confirm backend v2, the exact planned version, and no dangerous authentication bypass. The plugin uses the explicit model or environment-model alias, otherwise reading the default alias from `/api/v1/config`; creates a session in the job cwd; binds that model with `permission_mode:auto` and `swarm_mode:true`; verifies those settings and `plan_mode:false` through `/status`; verifies clean shutdown; and requires the main journal's manual `swarm_mode.enter` record.
217
230
  2. The ordinary stream-json print runner resumes that session with `kimi -p -r`. The job records `kimi_session_id_source:"preactivated"`, and the session returned by print must exactly match the preactivated id. Every coordinator and child tool call remains governed by the same managed PreToolUse hook and operation allowlist.
@@ -224,7 +237,7 @@ Older certified versions keep the direct `kimi -p` path. The web processes are n
224
237
  `/kimi:swarm` (v1.2) fans a **read-only** review out across subagents using kimi-code's `AgentSwarm` tool (kimi-code 0.12.0+). The coordinator launches one subagent per target (file/module/question); each inspects the workspace with read tools and reports findings, which the coordinator consolidates into one markdown report. It opens **zero new write surface**.
225
238
 
226
239
  - **The hook label is `swarm`, and it allows the read-only tool set PLUS `AgentSwarm`.** The coordinator must be allowed to call `AgentSwarm` (else the swarm never launches), but no write/edit/shell tool is allowed. The exact allowed tool name is `AgentSwarm` (verified at 0.42.0 against `packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agentSwarmTool.ts`: `'AgentSwarm'`, strict schema). The singular `Agent` tool is deliberately *not* allowed — swarm is the fan-out surface, not arbitrary delegation.
227
- - **Every subagent inherits the `swarm` label and fires the same hook.** On native v2 (0.42.0) `AgentSwarm` children run in-process in a child DI scope with their OWN eager external-hooks service, so every child tool call passes the same before-execute channel and the same managed hook — there is no sub-vs-main branch and no deny-all shortcut on the swarm route. So a subagent's `Write`/`Edit`/`Bash` is denied exactly like a single-turn review's. The swarm listener in that channel is non-terminal and nothing auto-approves `AgentSwarm` ahead of the hook. (Legacy-v1 ≤ 0.41 reached the same result by placing the hook policy at index 0 of every agent's permission stack.) **Required for final certification evidence** (`tests/runtime/real-binary-smoke.test.ts`, run via `bun run smoke:real`): distinct child journals must exist, and each assigned Write/Edit `path` must be correlated through its `toolCallId` with the managed denial in that exact tool result; unrelated denials and coordinator-only reports are insufficient. On 2.3.2, 2.3.3 and 2.4.0, targeted controls also prove that direct OFF produces no children while the preactivated ON path produces the real child journals and denials.
240
+ - **Every subagent inherits the `swarm` label and fires the same hook.** On native v2 (0.42.0) `AgentSwarm` children run in-process in a child DI scope with their OWN eager external-hooks service, so every child tool call passes the same before-execute channel and the same managed hook — there is no sub-vs-main branch and no deny-all shortcut on the swarm route. So a subagent's `Write`/`Edit`/`Bash` is denied exactly like a single-turn review's. The swarm listener in that channel is non-terminal and nothing auto-approves `AgentSwarm` ahead of the hook. (Legacy-v1 ≤ 0.41 reached the same result by placing the hook policy at index 0 of every agent's permission stack.) **Required for final certification evidence** (`tests/runtime/real-binary-smoke.test.ts`, run via `bun run smoke:real`): distinct child journals must exist, and each assigned Write/Edit `path` must be correlated through its `toolCallId` with the managed denial in that exact tool result; unrelated denials and coordinator-only reports are insufficient. On 2.3.2, 2.3.3, 2.4.0 and 2.4.1, targeted controls also prove that direct OFF produces no children while the preactivated ON path produces the real child journals and denials.
228
241
  - **The managed hook is the read-only boundary; no `explore`-profile second layer is assumed.** Production deliberately omits `subagent_type` for read-only swarm rather than selecting kimi-code's `explore` profile. Every coordinator and subagent tool call is enforced by the same managed hook.
229
242
  - **Swarm refuses without the hook, like every model-spawning command.** A swarm makes the reason especially acute: it asks for up to `--cap` subagents, but this total-count hint is advisory, so a missing hook would remove enforcement from all of them at once. `KIMI_PLUGIN_CC_SKIP_HOOK_CHECK=1` remains an explicit tests/diagnostics escape hatch, not a recovery path.
230
243
  - **The only new risk is COST, and the plugin bounds it.** Read-only swarm writes nothing, so the new risk is runaway cost from N parallel model runs (and possible nested `AgentSwarm`). `/kimi:swarm` enforces a **mandatory finite wall-clock ceiling** via its AbortController (`--budget`, default 30m); the SIGTERM→SIGKILL descendant-reaping cancellation reaps the whole subagent process tree. Two **distinct** subagent bounds: `--cap N` is a *soft* prompt-injected hint on TOTAL subagent count (the hook is stateless and cannot enforce a count, so the model may exceed it), and `--max-concurrency N` is a *hard* ceiling on how many subagents kimi-code's `SubagentBatch` runs concurrently — exported as `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` (PR #888) on **kimi-code 0.18.0+** (older binaries ignore the unknown env var, so on < 0.18 only the soft hint applies). It **defaults to 4** when the user passes none (`resolveSwarmMaxConcurrency` in swarm.ts), so every swarm run — agent-dispatched or human-typed — carries an enforced peak-parallelism ceiling on 0.18.0+ rather than falling back to kimi-code's internal ramp; pass an explicit value to widen or throttle. **Never merge them into one flag:** concurrency ≠ total count — a hard concurrency cap of N still permits more than N subagents over the life of the run, just never more than N at once. The `--budget` bounds elapsed time, not a dollar amount or total token count; `--max-concurrency` bounds *peak* parallelism (the spike in simultaneous model spend), and `--cap` is only an advisory total-count nudge. Folding both onto one flag would create the "cap-as-total-count illusion" — a user reading `--cap N` would expect a total bound but receive only a peak-parallelism one.
@@ -293,9 +306,9 @@ at it (the runtime resolves that path instead of `kimi` on `PATH`; every spawn
293
306
  still exports `KIMI_CODE_NO_AUTO_UPDATE=1`, so the pinned copy never drifts).
294
307
 
295
308
  ```sh
296
- PIN=~/.local/share/kimi-plugin-cc/kimi-bin/2.4.0
309
+ PIN=~/.local/share/kimi-plugin-cc/kimi-bin/2.4.1
297
310
  mkdir -p "$PIN" && cd "$PIN" && printf '{"name":"kimi-plugin-cc-pin","private":true}\n' > package.json
298
- npm install @moonshot-ai/kimi-code@2.4.0
311
+ npm install @moonshot-ai/kimi-code@2.4.1
299
312
  export KIMI_PLUGIN_CC_KIMI_BIN="$PIN/node_modules/.bin/kimi" # e.g. in ~/.zshenv
300
313
  ```
301
314
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Normal stop: use `scripts/companion.sh cancel` for a shell-owned run, or the MCP job cancel tool for an MCP-owned run. A hard kill cannot execute cleanup. Cancellation still starts no fresh cleanup server.
4
4
 
5
- For exact CLI 2.3.2, 2.3.3 and 2.4.0 swarm runs created by this runtime, status includes a durable `swarm_recovery` record. It contains the resolved home/workspace, companion identity, launch intent, verified process identities and session identity. It never contains the web authentication token, credentials, prompt or config contents. Session identity is committed before the request enabling swarm mode.
5
+ For exact CLI 2.3.2, 2.3.3, 2.4.0 and 2.4.1 swarm runs created by this runtime, status includes a durable `swarm_recovery` record. It contains the resolved home/workspace, companion identity, launch intent, verified process identities and session identity. It never contains the web authentication token, credentials, prompt or config contents. Session identity is committed before the request enabling swarm mode.
6
6
 
7
7
  ## Preview, then recover
8
8
 
@@ -0,0 +1,54 @@
1
+ # Kimi Code 2.4.1 certification evidence — 2026-10-31
2
+
3
+ ## Status and exact source
4
+
5
+ **Exact CLI 2.4.1 is certified for all eight operations by plugin 2.4.5.** The exact-source gate, non-vacuous plan and swarm controls, expanded candidate and production matrices, literal standard `bun run check`, final edited-byte package, and independent Codex/Kimi reviews all passed. CI, commit, push, tag, publication, installed-host rollout, and operator CLI pin changes are not performed in this certification slice.
6
+
7
+ Candidate: `@moonshot-ai/kimi-code@2.4.1`, release commit `2c73f3f50af4fa7f2540ca0d2e33b07a1408e3a7`, compared with certified 2.4.0 (`f26e4d91ef8d5d233f6c20b42a150f96924d4f5e`). npm published the candidate at 2026-10-30T09:55:26.630Z; its npm tarball SHA-1 is `660debae9ff145564c670fcc32444aed5cc7ab79`. A temporary isolated npm installation and its executable both report 2.4.1. The clean exact source checkout is `.claude/kimi-code-research/kimi-code-2.4.1-audit`.
8
+
9
+ ## Source review
10
+
11
+ Codex's 2026-10-31 monitor supplied seven scoped diffs as leads. The main-thread certification review also covered every changed production TypeScript file, the complete release delta, Read's token helpers, profile composition, goal injection, DI and OS backends, wire reload/migrations, KAP activation dependencies, alternate final-allow spellings, and indirect plan entry. The synthesis is retained at `.claude/kimi-code-research/reports/2026-10-31-2.4.1-source-synthesis.md`.
12
+
13
+ - The exact-tag scan passed **15 tests and 96 assertions**. All 15 load-bearing files are byte-identical to 2.4.0. The plan-file guard remains the sole production final allow; executor/subscriber order, hook schema/aggregation, eager child hooks, Write/Edit `path`, Bash `command`/`cwd`, stream shapes, CLI argv, and AgentSwarm behavior remain compatible.
14
+ - Plan changes are reminder/profile prompts only. `EnterPlanMode` remains removed, fresh print still cancels configured default plan, and resumed plan sessions remain possible. The plugin retains its config preflight, Enter/ExitPlanMode deny policy, and every-agent journal-taint refusal.
15
+ - Goal injection adds full/sparse reminder selection using context history, not another goal tool, executor route, terminal exit, or budget mechanism. Read lowers the default maximum to 100,000 characters and adds estimated-token-aware pagination. Write/Edit success notes and Bash rendered guidance do not change their input schemas or execution gates.
16
+ - DI scope creation, OS backends, wire reload/migrations, KAP source, and the CLI/web activation surfaces are unchanged. No early session announcement or tool execution outcome was added; existing recovery and detection ambiguity remain.
17
+
18
+ ## Exact-binary controls
19
+
20
+ Controls used a task-authorized dedicated Agent Key in process memory/environment and empty isolated homes, except the forced removed-tool control, which used a loopback scripted provider and a dummy key. No personal config or OAuth store was read, copied, or symlinked. All live controls ran sequentially. The plan and removed-tool controls install a custom deny-all control hook; the plugin's managed hook is separately installed and proved by the operation smoke. Raw evidence is under `.claude/kimi-code-research/cert-2.4.1-live/`.
21
+
22
+ - **Plan OFF Write:** the exact 2.4.1 marker was first; Write reached the custom deny-all control hook and was denied on the same call ID. No target file or plan state was created.
23
+ - **Plan ON:** an authenticated loopback session was explicitly placed in plan mode, shut down cleanly in 5.638 seconds, and resumed with a deny-all hook. The exact marker and `plan_mode.enter` were present. Glob and ExitPlanMode reached the deny hook; a **1,831-byte** plan file was written without a plan-Write hook invocation. The workspace remained empty.
24
+ - **Removed EnterPlanMode:** the offered tools included Write but not EnterPlanMode. A scripted provider forced `call_enter_forced`; the exact binary returned `Tool "EnterPlanMode" not found` on that ID before any hook call and returned the rejection to the provider. No plan state or files appeared.
25
+ - **Swarm OFF:** a real AgentSwarm call returned the inactive-mode result with zero child journals and no probe files.
26
+ - **Swarm ON:** after adding the reviewed exact 2.4.1 activation selector and rebuilding, compiled activation produced `agent-0` and `agent-1`; each child attempted its assigned Write with a matching managed-denial result under the same toolCallId. The coordinator did not substitute writes, no probes landed, and deactivation verified `swarm_mode.exit`. Parent `KIMI_CODE_SESSION_IDLE_RECLAIM_MS=1` confirmed the child environment's `0` override remains effective.
27
+ - Focused activation passed **36 tests and 130 assertions**. The focused setup/engine/activation set after the production row passed **142 tests and 2,282 assertions**.
28
+
29
+ ### Invalid setup attempts, not accepted as evidence
30
+
31
+ - The first forced removed-tool run passed every safety assertion but failed `noWorkspaceFiles` because a relative artifact root made the child create its relative Kimi home beneath the workspace. A fresh run with an absolute artifact root passed all checks; the fixture failure is not counted.
32
+ - The first combined swarm control passed OFF, then ON refused before any model call because `PREACTIVATION_VERSIONS` did not yet include 2.4.1. The unchanged KAP source justified adding only that exact activation selector. The focused activation suite and fresh ON control then passed. The refused attempt is not ON evidence.
33
+
34
+ ## Candidate and final gates
35
+
36
+ - Expanded candidate matrix (`candidate-smoke.log`): **21 pass, 0 fail, 154 assertions, no skips**, 410.84 seconds. Real `runRescue` landed the confined sentinel and persisted operation/version/engine/session/artifact evidence. The absolute out-of-root Bash.cwd call received its exact same-call denial and created no file. Eight goal turns produced none of the three named goal files. Write-swarm produced a 278-byte child-authored patch, left the user tree clean, removed its worktree, and denied the out-of-root write.
37
+ - Frozen dependency installation made no changes; `bun audit` found no vulnerabilities. Typecheck, contract-size, and generated-surface checks passed before the production matrix.
38
+ - Compiled acceptance/refusal controls passed under Node and Bun against both root and Codex distributions: every operation accepts exact 2.4.1 and normalized `v2.4.1`; 2.4.2, prereleases, build metadata, and mismatched hook-schema components refuse.
39
+ - Expanded production-table matrix (`production-smoke.log`) with the candidate override explicitly unset: **21 pass, 0 fail, 154 assertions, no skips**, 453.88 seconds. Real rescue and deterministic Bash.cwd passed the same confinement and provenance assertions. Twelve goal turns produced none of the three named goal files. Write-swarm captured a 278-byte child-authored patch, left the user tree clean, and removed its worktree.
40
+ - Initial full repository check passed **1,315 tests with 30 expected opt-in skips, 0 failures and 17,073 assertions across 79 files** in 320.46 seconds. Initial package validation passed **232 files**. Subsequent iCloud-style `* 2` duplicates in root `dist/vendor` were verified byte-identical to canonical generated files and quarantined; the runtime mirrors match again.
41
+ - Earlier review iterations (`production-review-smoke.log` and `goal-final-smoke.log`) passed **23 tests and 163 assertions** and a goal-only test respectively, but their Bash-inclusive goal evidence is **not accepted for certification**. The final edge-hardened matrix below supersedes those goal claims. Other operation evidence from those runs remains useful.
42
+ - Clean full repository check (`check-review-final.log`) after review fixes: **1,317 pass, 30 expected opt-in skips, 0 fail, 17,314 assertions across 79 files**, 321.00 seconds. Clean package validation (`package-review-final.log`) passed **233 files**, both compiled distributions, isolated hook setup/check, version refusal, and modern/legacy MCP controls. `docs/upstream-2.4.1-certification.md` is confirmed in the archive.
43
+ - Codex's targeted re-review requested genuine error results, legacy-compatible turn starts, and a whole-workspace settlement assertion. A subsequent review added marker-prefix, call-derived turn-ID, and directory-entry requirements. The final production matrix (`production-prefix-smoke.log`) passed **24 tests and 167 assertions with no skips in 440.66 seconds**. All seven call-derived turn IDs had same-call Write denials with `isError: true` and the managed-message prefix, and the entire workspace was empty at settlement.
44
+ - Literal standard `bun run check` (`check-standard-final.log`): **1,318 pass, 30 expected opt-in skips, 0 fail, 17,319 assertions across 79 files**, 358.83 seconds. Earlier parallel attempts hit timing-sensitive lifecycle failures; the focused suites and a complete serial run passed before the literal standard gate also passed. Codex's final targeted re-review returned **APPROVE**, closing all original and subsequent findings. Final edited-byte package validation (`package-standard-final.log`) passed **233 files** and includes this record.
45
+
46
+ ## Release and publication
47
+
48
+ Plugin 2.4.5 was committed as `de8c195c2986443a088b674717133b164d2e4ef2` and pushed to `main`. [Release-commit CI 41226096281](https://github.com/linxule/kimi-plugin-cc/actions/runs/41226096281) passed the full check/package and Windows spawn jobs. Annotated tag `v2.4.5` and [GitHub release](https://github.com/linxule/kimi-plugin-cc/releases/tag/v2.4.5) were created. [Publish workflow 41226438326](https://github.com/linxule/kimi-plugin-cc/actions/runs/41226438326) passed its build and npm publish jobs.
49
+
50
+ The registry tarball has SHA-1 `39f97a6de4b26ad51ac77305054682fcd5cd0164`, contains 233 files, and matches the CI artifact byte-for-byte. Fresh npm registry installations passed isolated setup/check and unsupported-version refusal for both hosts, and the compiled mirrors are byte-identical to the release checkout. Structured proof is retained at `.claude/kimi-code-research/release-2.4.5/registry-verification.json`. Installed hosts and operator CLI pins remain unchanged.
51
+
52
+ ## Preserved boundaries
53
+
54
+ Certification remains exact and per-operation. Legacy-v1 ends at 0.41.x. Plan mode and unsafe experimental selectors remain refused. Hook verification, trusted-root confinement, concurrency/defaults, one print runner, memory-only web tokens, finite budgets, process/session identity checks, deactivation, and recovery ownership are unchanged. Existing Git trust and hook-process failure residuals remain documented; this release does not make the hook an OS sandbox. Publication does not install or re-pin either host.
package/package.json CHANGED
@@ -1,30 +1,61 @@
1
1
  {
2
2
  "name": "kimi-plugin-cc",
3
- "version": "2.4.4",
4
- "description": "Kimi for Claude Code and Codex: code questions, independent reviews, bounded fixes, autonomous goals, parallel tasks, and MCP tools through the local Kimi Code CLI.",
3
+ "version": "2.5.1",
4
+ "description": "Kimi for Claude Code, Codex, and DeepSeek Harness: code questions, independent reviews, bounded fixes, autonomous goals, parallel tasks, and MCP tools through the local Kimi Code CLI.",
5
5
  "type": "module",
6
+ "main": "dist/dsh/index.js",
6
7
  "engines": {
7
- "node": ">=22.5.0"
8
+ "node": ">=22.5.0",
9
+ "dsh": ">=0.2.1-rc.5 <0.3.0"
10
+ },
11
+ "dsh": {
12
+ "bundle": {
13
+ "patch": "./plugins/kimi-dsh/cordis.patch.yml"
14
+ }
8
15
  },
9
16
  "scripts": {
10
- "check": "bun run build && bun run check:contracts && bun run check:surfaces && bunx tsc --noEmit && bun test && git diff --exit-code -- dist plugins/kimi-codex && UNTRACKED=\"$(git ls-files --others --exclude-standard -- dist plugins/kimi-codex)\" && { [ -z \"$UNTRACKED\" ] || { echo \"drift gate: untracked dist/codex files (stage them and re-run check):\"; echo \"$UNTRACKED\"; exit 1; }; }",
17
+ "check": "bun run build && bun run check:contracts && bun run check:surfaces && bunx tsc --noEmit && bun test && git diff --exit-code -- dist plugins/kimi-codex plugins/kimi-dsh && UNTRACKED=\"$(git ls-files --others --exclude-standard -- dist plugins/kimi-codex plugins/kimi-dsh)\" && { [ -z \"$UNTRACKED\" ] || { echo \"drift gate: untracked dist/codex/dsh files (stage them and re-run check):\"; echo \"$UNTRACKED\"; exit 1; }; }",
11
18
  "check:surfaces": "bun run scripts/generate-surfaces.ts --check",
12
19
  "generate:surfaces": "bun run scripts/generate-surfaces.ts",
13
20
  "build": "rm -rf dist && bunx tsc -p tsconfig.build.json && mkdir -p dist/vendor/shell-quote dist/vendor/smol-toml && cp runtime/vendor/shell-quote/LICENSE dist/vendor/shell-quote/LICENSE && cp runtime/vendor/smol-toml/*.js runtime/vendor/smol-toml/LICENSE dist/vendor/smol-toml/ && echo '{\"type\":\"module\"}' > dist/package.json",
14
21
  "companion": "node --import tsx runtime/companion.ts",
15
22
  "test": "bun test",
16
23
  "smoke:real": "KIMI_PLUGIN_CC_SMOKE=1 bun test tests/runtime/real-binary-smoke.test.ts --path-ignore-patterns '**/worktrees/**'",
17
- "check:package": "node scripts/check-package.mjs",
24
+ "check:package": "node scripts/check-package.mjs && node scripts/check-dsh-package.mjs",
18
25
  "check:contracts": "node scripts/check-contract-size.mjs"
19
26
  },
20
27
  "devDependencies": {
28
+ "@deepseek-ai/cordis": "4.0.5",
29
+ "@deepseek-ai/dsh-commands": "0.2.1-rc.5",
30
+ "@deepseek-ai/dsh-llm": "0.2.1-rc.5",
31
+ "@deepseek-ai/dsh-session": "0.2.1-rc.5",
32
+ "@deepseek-ai/dsh-subagent": "0.2.1-rc.5",
33
+ "@deepseek-ai/dsh-subprocess": "0.2.1-rc.5",
34
+ "@deepseek-ai/dsh-working-directory": "0.2.1-rc.5",
21
35
  "@types/bun": "^1.4.2",
22
36
  "@types/node": "^26.5.1",
23
37
  "smol-toml": "1.9.1",
24
38
  "tsx": "^4.23.13",
25
39
  "typescript": "^7.0.2"
26
40
  },
27
- "dependencies": {},
41
+ "dependencies": {
42
+ "@deepseek-ai/dsh-brand": "0.2.1-rc.5",
43
+ "@deepseek-ai/dsh-tool-subagent": "0.2.1-rc.5",
44
+ "@deepseek-ai/schemastery": "3.18.5"
45
+ },
46
+ "peerDependencies": {
47
+ "@deepseek-ai/cordis": "~4.0.5",
48
+ "@deepseek-ai/dsh-commands": ">=0.2.1-rc.5 <0.3.0",
49
+ "@deepseek-ai/dsh-llm": ">=0.2.1-rc.5 <0.3.0",
50
+ "@deepseek-ai/dsh-session": ">=0.2.1-rc.5 <0.3.0",
51
+ "@deepseek-ai/dsh-subagent": ">=0.2.1-rc.5 <0.3.0",
52
+ "@deepseek-ai/dsh-subprocess": ">=0.2.1-rc.5 <0.3.0",
53
+ "@deepseek-ai/dsh-working-directory": ">=0.2.1-rc.5 <0.3.0"
54
+ },
55
+ "overrides": {
56
+ "zod": "^4.6.6",
57
+ "undici": "^8.12.2"
58
+ },
28
59
  "license": "Apache-2.0",
29
60
  "author": "Xule Lin",
30
61
  "repository": {
@@ -38,6 +69,8 @@
38
69
  "keywords": [
39
70
  "claude-code",
40
71
  "codex",
72
+ "deepseek-harness",
73
+ "dsh",
41
74
  "kimi",
42
75
  "kimi-code",
43
76
  "plugin",
@@ -58,6 +91,7 @@
58
91
  "hooks/",
59
92
  "dist/",
60
93
  "plugins/kimi-codex/",
94
+ "plugins/kimi-dsh/",
61
95
  "scripts/companion.sh",
62
96
  "scripts/review-gate-hook.sh",
63
97
  "docs/safety.md",
@@ -66,6 +100,7 @@
66
100
  "docs/migration.md",
67
101
  "docs/models.md",
68
102
  "docs/session-visibility.md",
103
+ "docs/upstream-2.4.1-certification.md",
69
104
  "README.md",
70
105
  "LICENSE",
71
106
  "CHANGELOG.md",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kimi",
3
- "version": "2.4.4",
3
+ "version": "2.5.1",
4
4
  "description": "Kimi for Codex: code questions, independent reviews, bounded fixes, autonomous goals, parallel tasks, and MCP job controls through the local Kimi Code CLI.",
5
5
  "author": {
6
6
  "name": "linxule"
@@ -28,7 +28,7 @@ import { buildKimiSessionTitle, syncKimiSessionTitle } from "../session-title.js
28
28
  // only the wall-clock hard bound. Read/write modes reuse review/rescue lineage,
29
29
  // and the mandatory PreToolUse hook enforces read-only policy or trusted-worktree
30
30
  // write confinement on the coordinator and every subagent. Write mode requires
31
- // kimi-code 0.18.0+. Exact 2.3.2, 2.3.3 and 2.4.0 additionally activate a same-job
31
+ // kimi-code 0.18.0+. Exact 2.3.2, 2.3.3, 2.4.0 and 2.4.1 additionally activate a same-job
32
32
  // session through a bounded loopback web lifecycle, then resume it through the normal print path.
33
33
  const SWARM_SUMMARY_MAX = 120;
34
34
  const SWARM_AGENT_PROFILE = "<swarm>";
@@ -0,0 +1,174 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { brandString } from "@deepseek-ai/dsh-brand";
3
+ import { assertUsableCwd, settleRunResult, subprocessRunHandle, } from "@deepseek-ai/dsh-subagent";
4
+ export const DSH_COMPANION_OPERATIONS = [
5
+ "ask",
6
+ "review",
7
+ "challenge",
8
+ "rescue",
9
+ "pursue",
10
+ "swarm",
11
+ "swarm-write",
12
+ ];
13
+ export function companionTextTask(prompt) {
14
+ if (prompt.length === 0 || prompt.some((block) => block.type !== "text")) {
15
+ throw new Error("kimi-plugin-cc: a delegation must contain only text blocks");
16
+ }
17
+ const text = prompt.map((block) => block.type === "text" ? block.text : "").join("\n\n");
18
+ if (text.trim().length === 0) {
19
+ throw new Error("kimi-plugin-cc: a delegation must not be empty");
20
+ }
21
+ return text;
22
+ }
23
+ export function companionArgv(operation, prompt, companionPath, nodeBin = process.execPath, options = {}) {
24
+ const command = operation === "ask" || operation === "review"
25
+ ? [operation]
26
+ : operation === "swarm-write"
27
+ ? ["task", "swarm", "--write"]
28
+ : ["task", operation];
29
+ return [
30
+ nodeBin,
31
+ companionPath,
32
+ ...command,
33
+ ...(operation === "ask" || operation === "rescue" ? ["--fresh"] : []),
34
+ ...(options.model === undefined ? [] : ["-m", options.model]),
35
+ ...(options.thinkingEffort === undefined ? [] : ["--thinking", options.thinkingEffort]),
36
+ ...(options.budget === undefined ? [] : ["--budget", options.budget]),
37
+ ...((operation === "review" || operation === "challenge") && options.reviewBase !== undefined
38
+ ? ["--base", options.reviewBase]
39
+ : []),
40
+ "--",
41
+ prompt,
42
+ ];
43
+ }
44
+ export function companionEnvironment(dataRoot, cwd, env, nodeBin = process.execPath) {
45
+ return {
46
+ ...env,
47
+ KIMI_PLUGIN_CC_DATA: dataRoot,
48
+ KIMI_PLUGIN_CC_HOST_ID: "dsh",
49
+ KIMI_PLUGIN_CC_NODE_BIN: nodeBin,
50
+ KIMI_PLUGIN_CC_WORKSPACE_CWD: cwd,
51
+ CLAUDE_PLUGIN_DATA: undefined,
52
+ PLUGIN_DATA: undefined,
53
+ CLAUDE_PLUGIN_ROOT: undefined,
54
+ PLUGIN_ROOT: undefined,
55
+ KIMI_PLUGIN_CC_SHELL_LAUNCH: undefined,
56
+ KIMI_PLUGIN_CC_MCP_WORKSPACE: undefined,
57
+ KIMI_PLUGIN_CC_WORKSPACE_ROOT: undefined,
58
+ KIMI_PLUGIN_CC_HOOK_SCRIPT: undefined,
59
+ KIMI_PLUGIN_CC_SKIP_HOOK_CHECK: undefined,
60
+ KIMI_PLUGIN_CC_SKIP_VERSION_PROBE: undefined,
61
+ KIMI_CODE_TRUST_WORKSPACE: undefined,
62
+ };
63
+ }
64
+ export async function startCompanionRun(request, operation, spec) {
65
+ const prompt = companionTextTask(request.prompt);
66
+ if (request.signal.aborted) {
67
+ throw new Error("kimi-plugin-cc: delegation was aborted before companion startup");
68
+ }
69
+ const cwd = assertUsableCwd("kimi-plugin-cc", "child cwd", request.cwd ?? process.cwd());
70
+ const termination = new AbortController();
71
+ let cancelled = false;
72
+ const requestCancel = () => {
73
+ cancelled = true;
74
+ if (!termination.signal.aborted) {
75
+ termination.abort(new Error("kimi-plugin-cc: delegation cancelled"));
76
+ }
77
+ };
78
+ const onAbort = () => requestCancel();
79
+ request.signal.addEventListener("abort", onAbort, { once: true });
80
+ let child;
81
+ try {
82
+ child = spec.spawn({
83
+ argv: companionArgv(operation, prompt, spec.companionPath, process.execPath, spec),
84
+ cwd,
85
+ stdio: {
86
+ stdin: "ignore",
87
+ stdout: { maxBytes: spec.maxOutputBytes },
88
+ stderr: "inherit",
89
+ },
90
+ graceMs: spec.disposeGraceMs,
91
+ signal: termination.signal,
92
+ env: companionEnvironment(spec.dataRoot, cwd, spec.env),
93
+ });
94
+ }
95
+ catch (error) {
96
+ request.signal.removeEventListener("abort", onAbort);
97
+ throw error;
98
+ }
99
+ let diagnostic;
100
+ const result = settleRunResult({
101
+ attempt: async () => {
102
+ let outcome;
103
+ try {
104
+ outcome = await child.done;
105
+ }
106
+ catch (error) {
107
+ diagnostic = `Kimi ${operation} companion failed before producing a terminal exit`;
108
+ throw error;
109
+ }
110
+ const collected = child.collected.stdout?.readFrom(0);
111
+ const text = collected?.text.trimEnd() ?? "";
112
+ if (!cancelled && outcome.exitCode === 0 && collected && !collected.lossy && text.trim().length > 0) {
113
+ return { output: [{ type: "text", text }], stopReason: "completed" };
114
+ }
115
+ const facts = [
116
+ `exit code: ${outcome.exitCode ?? "none"}`,
117
+ `signal: ${outcome.signal ?? "none"}`,
118
+ ...(collected?.lossy ? ["stdout truncated"] : []),
119
+ ...(text.trim().length === 0 ? ["stdout empty"] : []),
120
+ ];
121
+ diagnostic = `Kimi ${operation} companion failed (${facts.join("; ")})`;
122
+ return { output: [], diagnostic, stopReason: cancelled ? "aborted" : "error" };
123
+ },
124
+ collectOutput: () => [],
125
+ collectDiagnostic: () => diagnostic,
126
+ cancelled: () => cancelled,
127
+ signal: request.signal,
128
+ onAbort,
129
+ });
130
+ return subprocessRunHandle({
131
+ id: brandString(randomUUID()),
132
+ result,
133
+ signal: request.signal,
134
+ onAbort,
135
+ requestCancel,
136
+ teardown: async () => {
137
+ child.terminate();
138
+ await child.waitForExit();
139
+ await child.done.catch(() => { });
140
+ },
141
+ });
142
+ }
143
+ export async function runCompanionCommand(argv, cwd, spec, signal) {
144
+ const child = spec.spawn({
145
+ argv: [process.execPath, spec.companionPath, ...argv],
146
+ cwd,
147
+ stdio: {
148
+ stdin: "ignore",
149
+ stdout: { maxBytes: spec.maxOutputBytes },
150
+ stderr: { maxBytes: spec.maxOutputBytes },
151
+ },
152
+ graceMs: spec.disposeGraceMs,
153
+ signal,
154
+ env: companionEnvironment(spec.dataRoot, cwd, spec.env),
155
+ });
156
+ try {
157
+ const outcome = await child.done;
158
+ await child.waitForExit();
159
+ const stdout = child.collected.stdout?.readFrom(0);
160
+ const stderr = child.collected.stderr?.readFrom(0);
161
+ return {
162
+ exitCode: outcome.exitCode,
163
+ signal: outcome.signal,
164
+ stdout: stdout?.text ?? "",
165
+ stderr: stderr?.text ?? "",
166
+ truncated: Boolean(stdout?.lossy || stderr?.lossy),
167
+ };
168
+ }
169
+ catch (error) {
170
+ child.terminate();
171
+ await child.waitForExit().catch(() => false);
172
+ throw error;
173
+ }
174
+ }