ladder-mcp 1.0.2 → 1.1.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/CHANGELOG.md +215 -115
- package/dist/desktop-work.js +10 -2
- package/dist/index.js +226 -195
- package/dist/kimi-api.js +5 -1
- package/dist/kimi-mcp-config.js +32 -16
- package/dist/kimi-runner.js +122 -15
- package/dist/progress.js +102 -0
- package/dist/session-store.js +25 -9
- package/dist/task-store.js +4 -0
- package/dist/transports/acp.js +300 -14
- package/dist/transports/cli-admin.js +9 -7
- package/dist/version.js +17 -0
- package/package.json +42 -38
package/CHANGELOG.md
CHANGED
|
@@ -1,115 +1,215 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to Ladder_mcp are documented here. Format loosely follows
|
|
4
|
-
[Keep a Changelog](https://keepachangelog.com/); this project uses
|
|
5
|
-
[Semantic Versioning](https://semver.org/).
|
|
6
|
-
|
|
7
|
-
## [1.0
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
###
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
`
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
`
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to Ladder_mcp are documented here. Format loosely follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/); this project uses
|
|
5
|
+
[Semantic Versioning](https://semver.org/).
|
|
6
|
+
|
|
7
|
+
## [1.1.0] - 2026-06-28
|
|
8
|
+
|
|
9
|
+
Breaking tool-surface redesign: the MCP tool list is now an intent-first set of
|
|
10
|
+
6 default tools, with niche/admin features gated behind `LADDER_EXPERIMENTAL=1`.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- `src/index.ts` now registers 6 default tools: `kimi_code`, `kimi_ask`,
|
|
15
|
+
`kimi_sessions`, `kimi_tasks`, `kimi_status`, `kimi_setup`.
|
|
16
|
+
- `kimi_code` folds `kimi_analyze`, `kimi_resume`, and `kimi_chat`. It defaults to
|
|
17
|
+
`transport='cli'` (validated `work_dir` via `validateWorkDir`) and supports
|
|
18
|
+
`edit`, `background`, `session_id`, and `new_session`.
|
|
19
|
+
- `kimi_ask` folds `kimi_query` and `kimi_verify`; providing `context` switches to
|
|
20
|
+
verify mode.
|
|
21
|
+
- `kimi_sessions` folds `kimi_list_sessions` and `kimi_acp_sessions` behind the
|
|
22
|
+
`source` parameter (`cli`, `acp`, `all`).
|
|
23
|
+
- `kimi_tasks` action-dispatches `status`, `output`, and `cancel` (including ACP
|
|
24
|
+
session cancellation via `session_id`).
|
|
25
|
+
- `kimi_status` detail-switches between `basic` and `full`; `full` adds
|
|
26
|
+
capabilities, doctor, and provider list. `isError` is now true whenever a
|
|
27
|
+
remediation is required.
|
|
28
|
+
- `kimi_setup` renames `kimi_generate_mcp_config` and resolves the default server
|
|
29
|
+
command from `process.execPath`.
|
|
30
|
+
|
|
31
|
+
### Removed
|
|
32
|
+
|
|
33
|
+
The 20-tool default surface is replaced by the 6 tools above. The following tool
|
|
34
|
+
names are no longer registered by default:
|
|
35
|
+
|
|
36
|
+
- `kimi_analyze`, `kimi_resume`, `kimi_chat`
|
|
37
|
+
- `kimi_query`, `kimi_verify`
|
|
38
|
+
- `kimi_list_sessions`, `kimi_acp_sessions`
|
|
39
|
+
- `kimi_task_status`, `kimi_task_output`, `kimi_task_cancel`, `kimi_cancel`
|
|
40
|
+
- `kimi_capabilities`, `kimi_doctor`, `kimi_provider_list`
|
|
41
|
+
- `kimi_generate_mcp_config`
|
|
42
|
+
|
|
43
|
+
### Migration
|
|
44
|
+
|
|
45
|
+
| Old tool | New |
|
|
46
|
+
|---|---|
|
|
47
|
+
| `kimi_analyze` | `kimi_code` (edit=false) |
|
|
48
|
+
| `kimi_resume` | `kimi_code` (session_id set) |
|
|
49
|
+
| `kimi_chat` | `kimi_code` (transport='acp') |
|
|
50
|
+
| `kimi_query` | `kimi_ask` |
|
|
51
|
+
| `kimi_verify` | `kimi_ask` (context/role set) |
|
|
52
|
+
| `kimi_list_sessions` | `kimi_sessions` (source='cli') |
|
|
53
|
+
| `kimi_acp_sessions` | `kimi_sessions` (source='acp') |
|
|
54
|
+
| `kimi_task_status` | `kimi_tasks` (action='status') |
|
|
55
|
+
| `kimi_task_output` | `kimi_tasks` (action='output') |
|
|
56
|
+
| `kimi_task_cancel` | `kimi_tasks` (action='cancel') |
|
|
57
|
+
| `kimi_cancel` | `kimi_tasks` (action='cancel', task_id or session_id) |
|
|
58
|
+
| `kimi_status` | `kimi_status` |
|
|
59
|
+
| `kimi_capabilities` | `kimi_status` (detail='full') |
|
|
60
|
+
| `kimi_doctor` | `kimi_status` (detail='full') |
|
|
61
|
+
| `kimi_provider_list` | `kimi_status` (detail='full') |
|
|
62
|
+
| `kimi_generate_mcp_config` | `kimi_setup` |
|
|
63
|
+
| `kimi_export_session` | experimental (unchanged name) |
|
|
64
|
+
| `kimi_visualize_session` | experimental |
|
|
65
|
+
| `kimi_desktop_status` | experimental |
|
|
66
|
+
| `kimi_budget_probe` | experimental |
|
|
67
|
+
|
|
68
|
+
The 4 experimental tools (`kimi_export_session`, `kimi_visualize_session`,
|
|
69
|
+
`kimi_desktop_status`, `kimi_budget_probe`) now register only when
|
|
70
|
+
`process.env.LADDER_EXPERIMENTAL === '1'`.
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
|
|
74
|
+
- **Bidirectional ACP transport** (`transports/acp.ts`): the bridge now answers the
|
|
75
|
+
agent's client-bound JSON-RPC requests, so file edits and permission flows over
|
|
76
|
+
ACP complete instead of hanging. Includes auto-approved `session/request_permission`
|
|
77
|
+
and a `fs/read_text_file`/`fs/write_text_file`/`fs/read_directory` proxy.
|
|
78
|
+
- **Live-progress visibility**: long-running `kimi_code` work surfaces progress —
|
|
79
|
+
background tasks grow a timestamped log, foreground calls emit MCP
|
|
80
|
+
`notifications/progress`, and a stall watchdog flags silent hangs. Token streams
|
|
81
|
+
are coalesced so the log is readable.
|
|
82
|
+
- **Single-source versioning** (`version.ts`) read from `package.json`, plus
|
|
83
|
+
`release:patch/minor/major` scripts and a `preversion` typecheck+test gate.
|
|
84
|
+
|
|
85
|
+
### Security
|
|
86
|
+
|
|
87
|
+
- **ACP fs proxy is sandboxed** to the session `work_dir` with realpath-based
|
|
88
|
+
containment (blocks symlink/junction escape, case-folding bypass, drive-relative
|
|
89
|
+
and UNC paths); fails closed when the work dir is unset. Permission auto-approve
|
|
90
|
+
fails closed when no single-use option is offered. File reads are size-capped.
|
|
91
|
+
- **`assertSafeCommand`** (`kimi-mcp-config.ts`) rejects PATH-resolved bare
|
|
92
|
+
`node`/`npx`, accepting only `process.execPath` or an absolute existing file;
|
|
93
|
+
`assertWritableProjectTarget` uses realpath containment instead of substring match.
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
|
|
97
|
+
- Process-tree termination on Windows (`taskkill /T /F`) for ACP close/cancel and
|
|
98
|
+
`runKimi` timeout, with awaited exit so callers don't race a dying tree.
|
|
99
|
+
- Timeouts in `runKimi` and `runKimiApi` are clamped; `timeout_ms` tool args must be
|
|
100
|
+
positive integers.
|
|
101
|
+
- `parseKimiStreamJson` tolerates leading whitespace; resume-hint extraction is
|
|
102
|
+
fuzzier; `contentToText` keeps placeholders for non-text parts.
|
|
103
|
+
- `task-store` no longer appends to terminal tasks; `runKimi` preserves both stdout
|
|
104
|
+
and stderr on failure; disk-discovered sessions recover their real `work_dir`.
|
|
105
|
+
- Capped the `readBodyCapped` non-streaming fallback (`desktop-work.ts`).
|
|
106
|
+
|
|
107
|
+
## [1.0.2] - 2026-06-28
|
|
108
|
+
|
|
109
|
+
Security and robustness patch release addressing findings from an external
|
|
110
|
+
adversarial review of `src/`.
|
|
111
|
+
|
|
112
|
+
### Fixed
|
|
113
|
+
|
|
114
|
+
- **`isAuthenticated` false-positive on corrupt credentials** (`environment.ts`):
|
|
115
|
+
a credentials file that exists but is unreadable or invalid JSON was previously
|
|
116
|
+
reported as authenticated. It now fails closed and returns `false`, satisfying
|
|
117
|
+
NFR-5 honest diagnostics.
|
|
118
|
+
- **Unbounded `stdout`/`stderr` capture in `runKimi`** (`kimi-runner.ts`): CLI
|
|
119
|
+
output is now accumulated through `appendCapped` with a hard ceiling
|
|
120
|
+
(`MAX_CAPTURE_CHARS`), preventing memory exhaustion on runaway output.
|
|
121
|
+
- **Unvalidated `max_output_tokens` and `work_dir`** (`input-validation.ts`):
|
|
122
|
+
non-finite, zero, or negative token counts are clamped to the default budget;
|
|
123
|
+
`work_dir` must be an absolute path to an existing directory before Kimi is
|
|
124
|
+
spawned. Used by `kimi_analyze` and `kimi_resume`.
|
|
125
|
+
|
|
126
|
+
### Security
|
|
127
|
+
|
|
128
|
+
- **Arbitrary command persisted to `mcp.json`** (`kimi-mcp-config.ts`):
|
|
129
|
+
`kimi_generate_mcp_config` now validates `command` against an allow-list of
|
|
130
|
+
`node`, `npx`, or an absolute path to an existing file. Other values (e.g.
|
|
131
|
+
`powershell`) are rejected and nothing is written.
|
|
132
|
+
|
|
133
|
+
## [1.0.1] - 2026-06-28
|
|
134
|
+
|
|
135
|
+
Bug-fix release. Issues found by exercising all 20 tools live against a real
|
|
136
|
+
Kimi CLI (the mock-only unit tests had missed them).
|
|
137
|
+
|
|
138
|
+
### Fixed
|
|
139
|
+
|
|
140
|
+
- **ACP responses lost spaces** (`kimi_chat`): streamed token chunks were each
|
|
141
|
+
trimmed and newline-joined, so `"Two plus two equals four."` came back as
|
|
142
|
+
`"Twoplustwoequalsfour."`. Text fragments are now concatenated as-is and only
|
|
143
|
+
the final string is trimmed. (CLI tools `kimi_analyze`/`kimi_resume` were never
|
|
144
|
+
affected.)
|
|
145
|
+
- **`kimi_export_session` silently no-op'd** while reporting `ok: true`: when no
|
|
146
|
+
session id was given, `kimi export` defaults to the most recent session and asks
|
|
147
|
+
`Export previous session …? [Y/n]` — a prompt that `-y` does not suppress in Kimi
|
|
148
|
+
CLI 0.20.1, so with stdin closed it exited 0 without writing. The tool now
|
|
149
|
+
resolves the most recent session id itself and passes it explicitly (skipping the
|
|
150
|
+
prompt), always passes `-y`, and verifies the output file exists before reporting
|
|
151
|
+
success.
|
|
152
|
+
|
|
153
|
+
### Changed
|
|
154
|
+
|
|
155
|
+
- `kimi_acp_sessions` now accepts `limit` (default 20) and `work_dir` filters,
|
|
156
|
+
for parity with `kimi_list_sessions`; previously it dumped every ACP session
|
|
157
|
+
across all projects in one response.
|
|
158
|
+
|
|
159
|
+
## [1.0.0] - 2026-06-27
|
|
160
|
+
|
|
161
|
+
First release. Windows-first MCP bridge for Kimi Code CLI v24, rebuilt in a
|
|
162
|
+
fresh `./src` application (package `ladder-mcp`). Logic is ported from the
|
|
163
|
+
read-only `kimi-code-mcp/` reference; the legacy `CacheManager`/warmup layer is
|
|
164
|
+
not carried over.
|
|
165
|
+
|
|
166
|
+
### Added — v1 core (Epics 1-3)
|
|
167
|
+
|
|
168
|
+
- Robust environment resolver (`environment.ts`): discovers `kimi.exe` via PATH
|
|
169
|
+
and `~/.kimi-code/bin/`, resolves the `~/.kimi-code/` catalog, credentials and
|
|
170
|
+
version with no hardcoded POSIX paths; no silent fallback to legacy `~/.kimi/`.
|
|
171
|
+
- CLI adapter (`kimi-runner.ts`): correct Kimi CLI v24 arguments
|
|
172
|
+
(`-p`, `--output-format stream-json`, `-S`, `-C`, `--auto`), `stream-json`
|
|
173
|
+
parsing, native session resume, Windows process-tree termination on timeout.
|
|
174
|
+
- API adapter (`kimi-api.ts`): contextless `kimi_query` / `kimi_verify` reading
|
|
175
|
+
key/endpoint from `KIMICODE_API_KEY` or `~/.kimi-code/config.toml`.
|
|
176
|
+
- Six v1 MCP tools: `kimi_analyze`, `kimi_query`, `kimi_verify`, `kimi_resume`,
|
|
177
|
+
`kimi_list_sessions`, `kimi_status`.
|
|
178
|
+
|
|
179
|
+
### Added — vNext expansion (Epic 4)
|
|
180
|
+
|
|
181
|
+
- **CLI admin & capabilities** (`transports/cli-admin.ts`): `kimi_capabilities`,
|
|
182
|
+
`kimi_doctor`, `kimi_provider_list`, `kimi_export_session`,
|
|
183
|
+
`kimi_visualize_session`. Export requires an explicit `output_path`, is
|
|
184
|
+
confined to the working directory, and excludes the global diagnostic log by
|
|
185
|
+
default.
|
|
186
|
+
- **ACP MVP over stdio** (`transports/acp.ts`): JSON-RPC client for `kimi acp`
|
|
187
|
+
with newline-delimited and `Content-Length` framing; `kimi_chat`,
|
|
188
|
+
`kimi_acp_sessions`, `kimi_cancel`.
|
|
189
|
+
- **Background task lifecycle** (`task-store.ts`): in-process task store with
|
|
190
|
+
`kimi_chat background=true`, `kimi_task_status`, `kimi_task_output`,
|
|
191
|
+
`kimi_task_cancel`.
|
|
192
|
+
- **Kimi-hosted MCP config + read-only desktop probes**
|
|
193
|
+
(`kimi-mcp-config.ts`, `desktop-work.ts`): `kimi_generate_mcp_config`,
|
|
194
|
+
`kimi_desktop_status`, `kimi_budget_probe`. Desktop access is
|
|
195
|
+
experimental/read-only — no token-store reads, no web-auth replay, no desktop
|
|
196
|
+
Work task submission.
|
|
197
|
+
|
|
198
|
+
### Security & robustness (adversarial review)
|
|
199
|
+
|
|
200
|
+
Hardened against path traversal/TOCTOU on export, writes under the read-only
|
|
201
|
+
reference tree, unbounded ACP frame/task memory, process crash on malformed ACP
|
|
202
|
+
JSON, non-idempotent task cancellation, and UTF-8 byte-boundary truncation.
|
|
203
|
+
|
|
204
|
+
The remaining lower-risk review findings (W1-W12) were also resolved before
|
|
205
|
+
release: raw ACP response-id matching (no `NaN` coercion), bounded ACP update
|
|
206
|
+
buffer, clamped ACP request timeouts, smaller buffers for parallel capability
|
|
207
|
+
probes, a timeout around task cancel hooks, a size cap on the desktop status
|
|
208
|
+
probe body, validated `kimi_chat` timeout input, and `kimi_cancel` rejecting
|
|
209
|
+
ambiguous task_id+session_id calls. Regression tests added (49 total).
|
|
210
|
+
|
|
211
|
+
### Known limitations
|
|
212
|
+
|
|
213
|
+
- Windows 11 only (NFR-1); POSIX branches are not a target.
|
|
214
|
+
|
|
215
|
+
[1.0.0]: https://semver.org/
|
package/dist/desktop-work.js
CHANGED
|
@@ -7,8 +7,16 @@ export const MAX_PROBE_BODY_BYTES = 256 * 1024;
|
|
|
7
7
|
// The surrounding AbortController still bounds total time.
|
|
8
8
|
export async function readBodyCapped(response) {
|
|
9
9
|
const reader = response.body?.getReader();
|
|
10
|
-
if (!reader)
|
|
11
|
-
|
|
10
|
+
if (!reader) {
|
|
11
|
+
// The body is not streamable; still cap the returned text so a non-streaming
|
|
12
|
+
// response cannot return an unbounded body.
|
|
13
|
+
const text = await response.text();
|
|
14
|
+
const bytes = Buffer.byteLength(text, 'utf-8');
|
|
15
|
+
if (bytes > MAX_PROBE_BODY_BYTES) {
|
|
16
|
+
return { text: Buffer.from(text, 'utf-8').subarray(0, MAX_PROBE_BODY_BYTES).toString('utf-8'), truncated: true };
|
|
17
|
+
}
|
|
18
|
+
return { text, truncated: false };
|
|
19
|
+
}
|
|
12
20
|
const decoder = new TextDecoder();
|
|
13
21
|
let text = '';
|
|
14
22
|
let total = 0;
|