toolcraft 0.0.25 → 0.0.26
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/dist/cli.js +11 -9
- package/dist/error-report.js +14 -11
- package/dist/redaction.d.ts +4 -0
- package/dist/redaction.js +70 -0
- package/node_modules/@poe-code/config-mutations/dist/execution/apply-mutation.js +33 -9
- package/node_modules/@poe-code/config-mutations/dist/formats/json.d.ts +2 -1
- package/node_modules/@poe-code/config-mutations/dist/formats/json.js +36 -9
- package/node_modules/@poe-code/config-mutations/dist/types.d.ts +2 -0
- package/node_modules/@poe-code/design-system/dist/components/browser.js +1 -1
- package/node_modules/@poe-code/design-system/dist/explorer/actions.js +1 -1
- package/node_modules/@poe-code/design-system/dist/explorer/keymap.js +11 -1
- package/node_modules/@poe-code/design-system/dist/explorer/reducer.js +64 -8
- package/node_modules/@poe-code/design-system/dist/explorer/render/detail.js +9 -11
- package/node_modules/@poe-code/design-system/dist/explorer/render/footer.js +18 -8
- package/node_modules/@poe-code/design-system/dist/explorer/render/header.js +11 -18
- package/node_modules/@poe-code/design-system/dist/explorer/render/index.js +2 -10
- package/node_modules/@poe-code/design-system/dist/explorer/render/list.js +32 -22
- package/node_modules/@poe-code/design-system/dist/explorer/render/modal.js +5 -9
- package/node_modules/@poe-code/design-system/dist/explorer/render/text.d.ts +12 -0
- package/node_modules/@poe-code/design-system/dist/explorer/render/text.js +81 -0
- package/node_modules/@poe-code/design-system/dist/explorer/state.d.ts +1 -0
- package/node_modules/@poe-code/design-system/dist/explorer/state.js +2 -0
- package/node_modules/@poe-code/design-system/dist/prompts/index.js +3 -3
- package/node_modules/@poe-code/process-runner/dist/docker/docker-execution-env.js +24 -3
- package/node_modules/@poe-code/process-runner/dist/docker/docker-runner.js +1 -0
- package/node_modules/auth-store/dist/keychain-store.js +20 -1
- package/node_modules/mcp-oauth/dist/client/auth-store-session-store.js +6 -3
- package/node_modules/tiny-mcp-client/dist/internal.d.ts +2 -0
- package/node_modules/tiny-mcp-client/dist/internal.js +30 -13
- package/node_modules/tiny-mcp-client/src/internal.ts +35 -16
- package/node_modules/tiny-mcp-client/src/transports.test.ts +68 -0
- package/package.json +2 -2
|
@@ -478,6 +478,9 @@ export class McpClient {
|
|
|
478
478
|
const abortPromise = new Promise<CallToolResult>((_, reject) => {
|
|
479
479
|
const rejectWithAbortReason = () => {
|
|
480
480
|
sendCancellationNotification();
|
|
481
|
+
if (requestId !== undefined) {
|
|
482
|
+
messageLayer.cancelRequest(requestId, signal.reason);
|
|
483
|
+
}
|
|
481
484
|
reject(signal.reason);
|
|
482
485
|
};
|
|
483
486
|
|
|
@@ -2350,11 +2353,16 @@ export class StdioTransport implements McpTransport {
|
|
|
2350
2353
|
|
|
2351
2354
|
this.readable = child.stdout;
|
|
2352
2355
|
this.writable = child.stdin;
|
|
2356
|
+
const stderrDecoder = new TextDecoder();
|
|
2353
2357
|
child.stderr.on("data", (chunk: unknown) => {
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
+
const decoded =
|
|
2359
|
+
chunk instanceof Uint8Array
|
|
2360
|
+
? stderrDecoder.decode(chunk, { stream: true })
|
|
2361
|
+
: `${stderrDecoder.decode()}${String(chunk)}`;
|
|
2362
|
+
this.appendStderrOutput(decoded);
|
|
2363
|
+
});
|
|
2364
|
+
child.stderr.once("end", () => {
|
|
2365
|
+
this.appendStderrOutput(stderrDecoder.decode());
|
|
2358
2366
|
});
|
|
2359
2367
|
this.closed = new Promise((resolve) => {
|
|
2360
2368
|
let settled = false;
|
|
@@ -2405,6 +2413,17 @@ export class StdioTransport implements McpTransport {
|
|
|
2405
2413
|
return this.stderrOutput;
|
|
2406
2414
|
}
|
|
2407
2415
|
|
|
2416
|
+
private appendStderrOutput(chunk: string): void {
|
|
2417
|
+
if (chunk.length === 0) {
|
|
2418
|
+
return;
|
|
2419
|
+
}
|
|
2420
|
+
|
|
2421
|
+
this.stderrOutput += chunk;
|
|
2422
|
+
if (this.stderrOutput.length > StdioTransport.STDERR_MAX_LENGTH) {
|
|
2423
|
+
this.stderrOutput = this.stderrOutput.slice(-StdioTransport.STDERR_MAX_LENGTH);
|
|
2424
|
+
}
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2408
2427
|
dispose(reason = new Error("Stdio transport disposed")): void {
|
|
2409
2428
|
void reason;
|
|
2410
2429
|
|
|
@@ -2965,18 +2984,6 @@ export function serializeJsonRpcMessage(message: JsonRpcMessage): string {
|
|
|
2965
2984
|
return `${JSON.stringify(message)}\n`;
|
|
2966
2985
|
}
|
|
2967
2986
|
|
|
2968
|
-
function chunkToString(chunk: unknown): string {
|
|
2969
|
-
if (typeof chunk === "string") {
|
|
2970
|
-
return chunk;
|
|
2971
|
-
}
|
|
2972
|
-
|
|
2973
|
-
if (chunk instanceof Uint8Array) {
|
|
2974
|
-
return Buffer.from(chunk).toString("utf8");
|
|
2975
|
-
}
|
|
2976
|
-
|
|
2977
|
-
return String(chunk);
|
|
2978
|
-
}
|
|
2979
|
-
|
|
2980
2987
|
function normalizeLine(line: string): string {
|
|
2981
2988
|
return line.endsWith("\r") ? line.slice(0, -1) : line;
|
|
2982
2989
|
}
|
|
@@ -3266,6 +3273,18 @@ export class JsonRpcMessageLayer {
|
|
|
3266
3273
|
});
|
|
3267
3274
|
}
|
|
3268
3275
|
|
|
3276
|
+
cancelRequest(requestId: RequestId, reason: unknown): boolean {
|
|
3277
|
+
const pending = this.pendingRequests.get(requestId);
|
|
3278
|
+
if (pending === undefined) {
|
|
3279
|
+
return false;
|
|
3280
|
+
}
|
|
3281
|
+
|
|
3282
|
+
this.pendingRequests.delete(requestId);
|
|
3283
|
+
clearTimeout(pending.timeout);
|
|
3284
|
+
pending.reject(reason);
|
|
3285
|
+
return true;
|
|
3286
|
+
}
|
|
3287
|
+
|
|
3269
3288
|
dispose(reason = new Error("JSON-RPC message layer disposed")): void {
|
|
3270
3289
|
if (this.disposedError !== undefined) {
|
|
3271
3290
|
return;
|
|
@@ -1471,6 +1471,40 @@ describe("JsonRpcMessageLayer sendRequest", () => {
|
|
|
1471
1471
|
vi.useRealTimers();
|
|
1472
1472
|
}
|
|
1473
1473
|
});
|
|
1474
|
+
|
|
1475
|
+
it("clears pending request state and timeout when a request is cancelled", async () => {
|
|
1476
|
+
vi.useFakeTimers();
|
|
1477
|
+
try {
|
|
1478
|
+
const input = new PassThrough();
|
|
1479
|
+
const output = new PassThrough();
|
|
1480
|
+
trackForCleanup(input, output);
|
|
1481
|
+
const layer = new JsonRpcMessageLayer(input, output, 25);
|
|
1482
|
+
const onTimeout = vi.fn();
|
|
1483
|
+
const pendingCount = () =>
|
|
1484
|
+
(
|
|
1485
|
+
layer as unknown as {
|
|
1486
|
+
pendingRequests: Map<unknown, unknown>;
|
|
1487
|
+
}
|
|
1488
|
+
).pendingRequests.size;
|
|
1489
|
+
|
|
1490
|
+
const responsePromise = layer.sendRequest("slow/method", undefined, {
|
|
1491
|
+
onTimeout,
|
|
1492
|
+
});
|
|
1493
|
+
expect(pendingCount()).toBe(1);
|
|
1494
|
+
|
|
1495
|
+
expect(layer.cancelRequest(1, "user cancelled")).toBe(true);
|
|
1496
|
+
|
|
1497
|
+
await expect(responsePromise).rejects.toBe("user cancelled");
|
|
1498
|
+
expect(pendingCount()).toBe(0);
|
|
1499
|
+
|
|
1500
|
+
await vi.advanceTimersByTimeAsync(25);
|
|
1501
|
+
|
|
1502
|
+
expect(onTimeout).not.toHaveBeenCalled();
|
|
1503
|
+
expect(layer.cancelRequest(1, "already gone")).toBe(false);
|
|
1504
|
+
} finally {
|
|
1505
|
+
vi.useRealTimers();
|
|
1506
|
+
}
|
|
1507
|
+
});
|
|
1474
1508
|
});
|
|
1475
1509
|
|
|
1476
1510
|
describe("JsonRpcMessageLayer UTF-8 input", () => {
|
|
@@ -2643,6 +2677,22 @@ describe("StdioTransport stderr capture", () => {
|
|
|
2643
2677
|
expect(transport.getStderrOutput()).toBe("first second");
|
|
2644
2678
|
});
|
|
2645
2679
|
|
|
2680
|
+
it("preserves UTF-8 characters split across stderr chunks", () => {
|
|
2681
|
+
const child = createMockChildProcess();
|
|
2682
|
+
const spawn = vi.fn<StdioSpawn>(() => child);
|
|
2683
|
+
|
|
2684
|
+
const transport = new StdioTransport({
|
|
2685
|
+
command: "node",
|
|
2686
|
+
spawn,
|
|
2687
|
+
});
|
|
2688
|
+
|
|
2689
|
+
const encoded = Buffer.from("é", "utf8");
|
|
2690
|
+
child.stderr.write(encoded.subarray(0, 1));
|
|
2691
|
+
child.stderr.write(encoded.subarray(1));
|
|
2692
|
+
|
|
2693
|
+
expect(transport.getStderrOutput()).toBe("é");
|
|
2694
|
+
});
|
|
2695
|
+
|
|
2646
2696
|
it("caps stderr at 64KB keeping the tail", () => {
|
|
2647
2697
|
const child = createMockChildProcess();
|
|
2648
2698
|
const spawn = vi.fn<StdioSpawn>(() => child);
|
|
@@ -7123,6 +7173,21 @@ describe("McpClient callTool", () => {
|
|
|
7123
7173
|
throw new Error("Expected initialized notification line to be written");
|
|
7124
7174
|
}
|
|
7125
7175
|
|
|
7176
|
+
const activeMessageLayer = (
|
|
7177
|
+
client as unknown as {
|
|
7178
|
+
messageLayer: JsonRpcMessageLayer | null;
|
|
7179
|
+
}
|
|
7180
|
+
).messageLayer;
|
|
7181
|
+
if (activeMessageLayer === null) {
|
|
7182
|
+
throw new Error("Expected message layer to exist after connect");
|
|
7183
|
+
}
|
|
7184
|
+
const pendingCount = () =>
|
|
7185
|
+
(
|
|
7186
|
+
activeMessageLayer as unknown as {
|
|
7187
|
+
pendingRequests: Map<unknown, unknown>;
|
|
7188
|
+
}
|
|
7189
|
+
).pendingRequests.size;
|
|
7190
|
+
|
|
7126
7191
|
const abortController = new AbortController();
|
|
7127
7192
|
const callToolPromise = client.callTool(
|
|
7128
7193
|
{
|
|
@@ -7142,6 +7207,8 @@ describe("McpClient callTool", () => {
|
|
|
7142
7207
|
const callToolRequest = JSON.parse(callToolLineResult.value) as {
|
|
7143
7208
|
id: number;
|
|
7144
7209
|
};
|
|
7210
|
+
expect(pendingCount()).toBe(1);
|
|
7211
|
+
|
|
7145
7212
|
abortController.abort("user cancelled");
|
|
7146
7213
|
|
|
7147
7214
|
const cancelledLineResult = await iterator.next();
|
|
@@ -7158,6 +7225,7 @@ describe("McpClient callTool", () => {
|
|
|
7158
7225
|
});
|
|
7159
7226
|
|
|
7160
7227
|
await callToolRejection;
|
|
7228
|
+
expect(pendingCount()).toBe(0);
|
|
7161
7229
|
await client.close();
|
|
7162
7230
|
});
|
|
7163
7231
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolcraft",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.26",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@clack/core": "^1.0.0",
|
|
47
47
|
"@clack/prompts": "^1.0.0",
|
|
48
|
-
"toolcraft-schema": "0.0.
|
|
48
|
+
"toolcraft-schema": "0.0.26",
|
|
49
49
|
"commander": "^14.0.3",
|
|
50
50
|
"jose": "^6.1.2",
|
|
51
51
|
"jsonc-parser": "^3.3.1",
|