linkshell-cli 0.2.120 → 0.2.122
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/src/runtime/acp/agent-workspace.js +4 -1
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.js +19 -0
- package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +1 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js +38 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +1 -1
- package/dist/cli/src/runtime/bridge-session.js +3 -3
- package/dist/cli/src/runtime/bridge-session.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/runtime/acp/agent-workspace.ts +5 -1
- package/src/runtime/acp/claude-sdk-client.ts +19 -0
- package/src/runtime/acp/claude-stream-json-client.ts +39 -1
- package/src/runtime/bridge-session.ts +3 -3
|
@@ -222,10 +222,21 @@ export class ClaudeStreamJsonClient {
|
|
|
222
222
|
let currentToolId: string | undefined;
|
|
223
223
|
let currentToolName: string | undefined;
|
|
224
224
|
let currentMessageId: string | undefined;
|
|
225
|
+
const progressItemId = `claude-progress:${input.clientMessageId}`;
|
|
225
226
|
// Map tool_use_id → tool_name so tool_result can look up the correct name
|
|
226
227
|
// even when multiple tools are in flight
|
|
227
228
|
const toolNames = new Map<string, string>();
|
|
228
229
|
|
|
230
|
+
this.input.onNotification("item/started", {
|
|
231
|
+
sessionId: input.sessionId ?? this.claudeSessionId,
|
|
232
|
+
item: {
|
|
233
|
+
id: progressItemId,
|
|
234
|
+
type: "thinking",
|
|
235
|
+
text: "Claude 正在处理请求",
|
|
236
|
+
status: "running",
|
|
237
|
+
},
|
|
238
|
+
});
|
|
239
|
+
|
|
229
240
|
rl.on("line", (line: string) => {
|
|
230
241
|
if (this.pendingCancel) {
|
|
231
242
|
child.kill("SIGTERM");
|
|
@@ -375,6 +386,16 @@ export class ClaudeStreamJsonClient {
|
|
|
375
386
|
}
|
|
376
387
|
|
|
377
388
|
case "result": {
|
|
389
|
+
const isError = event.subtype === "error" || event.is_error === true;
|
|
390
|
+
this.input.onNotification("item/completed", {
|
|
391
|
+
sessionId: this.claudeSessionId ?? input.sessionId,
|
|
392
|
+
item: {
|
|
393
|
+
id: progressItemId,
|
|
394
|
+
type: "thinking",
|
|
395
|
+
text: isError ? "Claude 运行出错" : "Claude 已完成",
|
|
396
|
+
status: isError ? "failed" : "completed",
|
|
397
|
+
},
|
|
398
|
+
});
|
|
378
399
|
// Mark the last agent message as complete so isStreaming flips to false
|
|
379
400
|
if (currentMessageId) {
|
|
380
401
|
this.input.onNotification("item/completed", {
|
|
@@ -387,7 +408,6 @@ export class ClaudeStreamJsonClient {
|
|
|
387
408
|
});
|
|
388
409
|
}
|
|
389
410
|
// Turn complete
|
|
390
|
-
const isError = event.subtype === "error" || event.is_error === true;
|
|
391
411
|
this.input.onNotification("turn/completed", {
|
|
392
412
|
sessionId: this.claudeSessionId,
|
|
393
413
|
stopReason: event.stop_reason ?? (isError ? "error" : "end_turn"),
|
|
@@ -408,11 +428,29 @@ export class ClaudeStreamJsonClient {
|
|
|
408
428
|
});
|
|
409
429
|
|
|
410
430
|
child.on("error", (err) => {
|
|
431
|
+
this.input.onNotification("item/completed", {
|
|
432
|
+
sessionId: this.claudeSessionId ?? input.sessionId,
|
|
433
|
+
item: {
|
|
434
|
+
id: progressItemId,
|
|
435
|
+
type: "thinking",
|
|
436
|
+
text: "Claude 运行出错",
|
|
437
|
+
status: "failed",
|
|
438
|
+
},
|
|
439
|
+
});
|
|
411
440
|
finish(err, undefined);
|
|
412
441
|
});
|
|
413
442
|
|
|
414
443
|
child.on("exit", (code, signal) => {
|
|
415
444
|
if (!settled) {
|
|
445
|
+
this.input.onNotification("item/completed", {
|
|
446
|
+
sessionId: this.claudeSessionId ?? input.sessionId,
|
|
447
|
+
item: {
|
|
448
|
+
id: progressItemId,
|
|
449
|
+
type: "thinking",
|
|
450
|
+
text: this.pendingCancel ? "Claude 已停止" : "Claude 意外退出",
|
|
451
|
+
status: "failed",
|
|
452
|
+
},
|
|
453
|
+
});
|
|
416
454
|
finish(
|
|
417
455
|
new Error(`Claude exited unexpectedly (code=${code ?? "null"}, signal=${signal ?? "null"})`),
|
|
418
456
|
undefined,
|
|
@@ -1138,7 +1138,7 @@ export class BridgeSession {
|
|
|
1138
1138
|
hookPort = result.port;
|
|
1139
1139
|
hookConfigPaths.push(result.configPath);
|
|
1140
1140
|
// Also set up hooks for other providers (curlCmd already has marker from setupHookServer)
|
|
1141
|
-
const curlCmd = `curl -s -X POST "http://127.0.0.1:${result.port}/hook?m=${hookMarker}&lid=$LINKSHELL_ID" -H 'Content-Type: application/json' --data-binary
|
|
1141
|
+
const curlCmd = `curl -s --connect-timeout 1 --max-time ${Math.ceil((PERMISSION_REQUEST_TIMEOUT_MS + 30_000) / 1000)} -X POST "http://127.0.0.1:${result.port}/hook?m=${hookMarker}&lid=$LINKSHELL_ID" -H 'Content-Type: application/json' --data-binary @- || true`;
|
|
1142
1142
|
hookConfigPaths.push(this.setupCodexHooks(terminalId, curlCmd, hookMarker));
|
|
1143
1143
|
hookConfigPaths.push(this.setupGeminiHooks(terminalId, curlCmd, hookMarker));
|
|
1144
1144
|
hookConfigPaths.push(this.setupCopilotHooks(terminalId, curlCmd, hookMarker));
|
|
@@ -1317,7 +1317,7 @@ export class BridgeSession {
|
|
|
1317
1317
|
});
|
|
1318
1318
|
this.log(`hook server for ${terminalId} (${provider}) listening on port ${port}, marker=${marker}`);
|
|
1319
1319
|
|
|
1320
|
-
const curlCmd = `curl -s -X POST "http://127.0.0.1:${port}/hook?m=${marker}&lid=$LINKSHELL_ID" -H 'Content-Type: application/json' --data-binary
|
|
1320
|
+
const curlCmd = `curl -s --connect-timeout 1 --max-time ${Math.ceil((PERMISSION_REQUEST_TIMEOUT_MS + 30_000) / 1000)} -X POST "http://127.0.0.1:${port}/hook?m=${marker}&lid=$LINKSHELL_ID" -H 'Content-Type: application/json' --data-binary @- || true`;
|
|
1321
1321
|
let configPath: string;
|
|
1322
1322
|
|
|
1323
1323
|
if (provider === "codex") {
|
|
@@ -1338,7 +1338,7 @@ export class BridgeSession {
|
|
|
1338
1338
|
const term = this.terminals.get(DEFAULT_TERMINAL_ID);
|
|
1339
1339
|
if (!term?.hookPort) return;
|
|
1340
1340
|
const marker = term.hookMarker;
|
|
1341
|
-
const curlCmd = `curl -s -X POST "http://127.0.0.1:${term.hookPort}/hook?m=${marker}&lid=$LINKSHELL_ID" -H 'Content-Type: application/json' --data-binary
|
|
1341
|
+
const curlCmd = `curl -s --connect-timeout 1 --max-time ${Math.ceil((PERMISSION_REQUEST_TIMEOUT_MS + 30_000) / 1000)} -X POST "http://127.0.0.1:${term.hookPort}/hook?m=${marker}&lid=$LINKSHELL_ID" -H 'Content-Type: application/json' --data-binary @- || true`;
|
|
1342
1342
|
const providers = this.options.agentProvider
|
|
1343
1343
|
? [normalizeAgentProvider(this.options.agentProvider)]
|
|
1344
1344
|
: detectAvailableProviders();
|