acpx 0.1.8 → 0.1.10
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.d.ts +1 -1
- package/dist/cli.js +471 -266
- package/package.json +1 -1
package/dist/cli.d.ts
CHANGED
package/dist/cli.js
CHANGED
|
@@ -11,7 +11,7 @@ import { findSkillsRoot, maybeHandleSkillflag } from "skillflag";
|
|
|
11
11
|
// src/agent-registry.ts
|
|
12
12
|
var AGENT_REGISTRY = {
|
|
13
13
|
codex: "npx @zed-industries/codex-acp",
|
|
14
|
-
claude: "npx @zed-industries/claude-agent-acp",
|
|
14
|
+
claude: "npx -y @zed-industries/claude-agent-acp",
|
|
15
15
|
gemini: "gemini",
|
|
16
16
|
opencode: "npx opencode-ai",
|
|
17
17
|
pi: "npx pi-acp"
|
|
@@ -388,6 +388,117 @@ var PermissionPromptUnavailableError = class extends AcpxOperationalError {
|
|
|
388
388
|
}
|
|
389
389
|
};
|
|
390
390
|
|
|
391
|
+
// src/acp-error-shapes.ts
|
|
392
|
+
var RESOURCE_NOT_FOUND_ACP_CODES = /* @__PURE__ */ new Set([-32001, -32002]);
|
|
393
|
+
function asRecord(value) {
|
|
394
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
395
|
+
return void 0;
|
|
396
|
+
}
|
|
397
|
+
return value;
|
|
398
|
+
}
|
|
399
|
+
function toAcpErrorPayload(value) {
|
|
400
|
+
const record = asRecord(value);
|
|
401
|
+
if (!record) {
|
|
402
|
+
return void 0;
|
|
403
|
+
}
|
|
404
|
+
if (typeof record.code !== "number" || !Number.isFinite(record.code)) {
|
|
405
|
+
return void 0;
|
|
406
|
+
}
|
|
407
|
+
if (typeof record.message !== "string" || record.message.length === 0) {
|
|
408
|
+
return void 0;
|
|
409
|
+
}
|
|
410
|
+
return {
|
|
411
|
+
code: record.code,
|
|
412
|
+
message: record.message,
|
|
413
|
+
data: record.data
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
function extractAcpErrorInternal(value, depth) {
|
|
417
|
+
if (depth > 5) {
|
|
418
|
+
return void 0;
|
|
419
|
+
}
|
|
420
|
+
const direct = toAcpErrorPayload(value);
|
|
421
|
+
if (direct) {
|
|
422
|
+
return direct;
|
|
423
|
+
}
|
|
424
|
+
const record = asRecord(value);
|
|
425
|
+
if (!record) {
|
|
426
|
+
return void 0;
|
|
427
|
+
}
|
|
428
|
+
if ("error" in record) {
|
|
429
|
+
const nested = extractAcpErrorInternal(record.error, depth + 1);
|
|
430
|
+
if (nested) {
|
|
431
|
+
return nested;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if ("cause" in record) {
|
|
435
|
+
const nested = extractAcpErrorInternal(record.cause, depth + 1);
|
|
436
|
+
if (nested) {
|
|
437
|
+
return nested;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return void 0;
|
|
441
|
+
}
|
|
442
|
+
function formatUnknownErrorMessage(error) {
|
|
443
|
+
if (error instanceof Error) {
|
|
444
|
+
return error.message;
|
|
445
|
+
}
|
|
446
|
+
if (error && typeof error === "object") {
|
|
447
|
+
const maybeMessage = error.message;
|
|
448
|
+
if (typeof maybeMessage === "string" && maybeMessage.length > 0) {
|
|
449
|
+
return maybeMessage;
|
|
450
|
+
}
|
|
451
|
+
try {
|
|
452
|
+
return JSON.stringify(error);
|
|
453
|
+
} catch {
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return String(error);
|
|
457
|
+
}
|
|
458
|
+
function isSessionNotFoundText(value) {
|
|
459
|
+
if (typeof value !== "string") {
|
|
460
|
+
return false;
|
|
461
|
+
}
|
|
462
|
+
const normalized = value.toLowerCase();
|
|
463
|
+
return normalized.includes("resource_not_found") || normalized.includes("resource not found") || normalized.includes("session not found") || normalized.includes("unknown session");
|
|
464
|
+
}
|
|
465
|
+
function hasSessionNotFoundHint(value, depth = 0) {
|
|
466
|
+
if (depth > 4) {
|
|
467
|
+
return false;
|
|
468
|
+
}
|
|
469
|
+
if (isSessionNotFoundText(value)) {
|
|
470
|
+
return true;
|
|
471
|
+
}
|
|
472
|
+
if (Array.isArray(value)) {
|
|
473
|
+
return value.some((entry) => hasSessionNotFoundHint(entry, depth + 1));
|
|
474
|
+
}
|
|
475
|
+
const record = asRecord(value);
|
|
476
|
+
if (!record) {
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
return Object.values(record).some(
|
|
480
|
+
(entry) => hasSessionNotFoundHint(entry, depth + 1)
|
|
481
|
+
);
|
|
482
|
+
}
|
|
483
|
+
function extractAcpError(error) {
|
|
484
|
+
return extractAcpErrorInternal(error, 0);
|
|
485
|
+
}
|
|
486
|
+
function isAcpResourceNotFoundError(error) {
|
|
487
|
+
const acp = extractAcpError(error);
|
|
488
|
+
if (acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code)) {
|
|
489
|
+
return true;
|
|
490
|
+
}
|
|
491
|
+
if (acp) {
|
|
492
|
+
if (isSessionNotFoundText(acp.message)) {
|
|
493
|
+
return true;
|
|
494
|
+
}
|
|
495
|
+
if (hasSessionNotFoundHint(acp.data)) {
|
|
496
|
+
return true;
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
return isSessionNotFoundText(formatUnknownErrorMessage(error));
|
|
500
|
+
}
|
|
501
|
+
|
|
391
502
|
// src/types.ts
|
|
392
503
|
var EXIT_CODES = {
|
|
393
504
|
SUCCESS: 0,
|
|
@@ -412,9 +523,8 @@ var OUTPUT_ERROR_CODES = [
|
|
|
412
523
|
var OUTPUT_ERROR_ORIGINS = ["cli", "runtime", "queue", "acp"];
|
|
413
524
|
|
|
414
525
|
// src/error-normalization.ts
|
|
415
|
-
var RESOURCE_NOT_FOUND_ACP_CODES = /* @__PURE__ */ new Set([-32001, -32002]);
|
|
416
526
|
var AUTH_REQUIRED_ACP_CODES = /* @__PURE__ */ new Set([-32e3]);
|
|
417
|
-
function
|
|
527
|
+
function asRecord2(value) {
|
|
418
528
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
419
529
|
return void 0;
|
|
420
530
|
}
|
|
@@ -437,7 +547,7 @@ function isAcpAuthRequiredPayload(acp) {
|
|
|
437
547
|
if (isAuthRequiredMessage(acp.message)) {
|
|
438
548
|
return true;
|
|
439
549
|
}
|
|
440
|
-
const data =
|
|
550
|
+
const data = asRecord2(acp.data);
|
|
441
551
|
if (!data) {
|
|
442
552
|
return false;
|
|
443
553
|
}
|
|
@@ -461,7 +571,7 @@ function isOutputErrorOrigin(value) {
|
|
|
461
571
|
return typeof value === "string" && OUTPUT_ERROR_ORIGINS.includes(value);
|
|
462
572
|
}
|
|
463
573
|
function readOutputErrorMeta(error) {
|
|
464
|
-
const record =
|
|
574
|
+
const record = asRecord2(error);
|
|
465
575
|
if (!record) {
|
|
466
576
|
return {};
|
|
467
577
|
}
|
|
@@ -469,7 +579,7 @@ function readOutputErrorMeta(error) {
|
|
|
469
579
|
const detailCode = typeof record.detailCode === "string" && record.detailCode.trim().length > 0 ? record.detailCode : void 0;
|
|
470
580
|
const origin = isOutputErrorOrigin(record.origin) ? record.origin : void 0;
|
|
471
581
|
const retryable = typeof record.retryable === "boolean" ? record.retryable : void 0;
|
|
472
|
-
const acp =
|
|
582
|
+
const acp = toAcpErrorPayload2(record.acp);
|
|
473
583
|
return {
|
|
474
584
|
outputCode,
|
|
475
585
|
detailCode,
|
|
@@ -478,8 +588,8 @@ function readOutputErrorMeta(error) {
|
|
|
478
588
|
acp
|
|
479
589
|
};
|
|
480
590
|
}
|
|
481
|
-
function
|
|
482
|
-
const record =
|
|
591
|
+
function toAcpErrorPayload2(value) {
|
|
592
|
+
const record = asRecord2(value);
|
|
483
593
|
if (!record) {
|
|
484
594
|
return void 0;
|
|
485
595
|
}
|
|
@@ -495,32 +605,6 @@ function toAcpErrorPayload(value) {
|
|
|
495
605
|
data: record.data
|
|
496
606
|
};
|
|
497
607
|
}
|
|
498
|
-
function extractAcpErrorInternal(value, depth) {
|
|
499
|
-
if (depth > 5) {
|
|
500
|
-
return void 0;
|
|
501
|
-
}
|
|
502
|
-
const direct = toAcpErrorPayload(value);
|
|
503
|
-
if (direct) {
|
|
504
|
-
return direct;
|
|
505
|
-
}
|
|
506
|
-
const record = asRecord(value);
|
|
507
|
-
if (!record) {
|
|
508
|
-
return void 0;
|
|
509
|
-
}
|
|
510
|
-
if ("error" in record) {
|
|
511
|
-
const nested = extractAcpErrorInternal(record.error, depth + 1);
|
|
512
|
-
if (nested) {
|
|
513
|
-
return nested;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
if ("cause" in record) {
|
|
517
|
-
const nested = extractAcpErrorInternal(record.cause, depth + 1);
|
|
518
|
-
if (nested) {
|
|
519
|
-
return nested;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
return void 0;
|
|
523
|
-
}
|
|
524
608
|
function isTimeoutLike(error) {
|
|
525
609
|
return error instanceof Error && error.name === "TimeoutError";
|
|
526
610
|
}
|
|
@@ -531,7 +615,7 @@ function isUsageLike(error) {
|
|
|
531
615
|
if (!(error instanceof Error)) {
|
|
532
616
|
return false;
|
|
533
617
|
}
|
|
534
|
-
return error.name === "CommanderError" || error.name === "InvalidArgumentError" ||
|
|
618
|
+
return error.name === "CommanderError" || error.name === "InvalidArgumentError" || asRecord2(error)?.code === "commander.invalidArgument";
|
|
535
619
|
}
|
|
536
620
|
function formatErrorMessage(error) {
|
|
537
621
|
if (error instanceof Error) {
|
|
@@ -549,17 +633,6 @@ function formatErrorMessage(error) {
|
|
|
549
633
|
}
|
|
550
634
|
return String(error);
|
|
551
635
|
}
|
|
552
|
-
function extractAcpError(error) {
|
|
553
|
-
return extractAcpErrorInternal(error, 0);
|
|
554
|
-
}
|
|
555
|
-
function isAcpResourceNotFoundError(error) {
|
|
556
|
-
const acp = extractAcpError(error);
|
|
557
|
-
if (acp && RESOURCE_NOT_FOUND_ACP_CODES.has(acp.code)) {
|
|
558
|
-
return true;
|
|
559
|
-
}
|
|
560
|
-
const message = formatErrorMessage(error).toLowerCase();
|
|
561
|
-
return message.includes("resource_not_found") || message.includes("resource not found") || message.includes("session not found") || message.includes("unknown session");
|
|
562
|
-
}
|
|
563
636
|
function mapErrorCode(error) {
|
|
564
637
|
if (error instanceof PermissionPromptUnavailableError) {
|
|
565
638
|
return "PERMISSION_PROMPT_UNAVAILABLE";
|
|
@@ -658,7 +731,7 @@ function toStatusLabel(status) {
|
|
|
658
731
|
return "running";
|
|
659
732
|
}
|
|
660
733
|
}
|
|
661
|
-
function
|
|
734
|
+
function asRecord3(value) {
|
|
662
735
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
663
736
|
return void 0;
|
|
664
737
|
}
|
|
@@ -752,7 +825,7 @@ function summarizeToolInput(rawInput) {
|
|
|
752
825
|
if (typeof rawInput === "string" || typeof rawInput === "number" || typeof rawInput === "boolean") {
|
|
753
826
|
return toInline(String(rawInput));
|
|
754
827
|
}
|
|
755
|
-
const record =
|
|
828
|
+
const record = asRecord3(rawInput);
|
|
756
829
|
if (record) {
|
|
757
830
|
const command = readFirstString(record, ["command", "cmd", "program"]);
|
|
758
831
|
const args = readFirstStringArray(record, ["args", "arguments"]);
|
|
@@ -886,7 +959,7 @@ function extractOutputText(value, depth = 0, seen = /* @__PURE__ */ new Set()) {
|
|
|
886
959
|
}
|
|
887
960
|
return dedupeStrings(parts).join("\n");
|
|
888
961
|
}
|
|
889
|
-
const record =
|
|
962
|
+
const record = asRecord3(value);
|
|
890
963
|
if (!record) {
|
|
891
964
|
return void 0;
|
|
892
965
|
}
|
|
@@ -1715,14 +1788,9 @@ function classifyPermissionDecision(params, response) {
|
|
|
1715
1788
|
return "denied";
|
|
1716
1789
|
}
|
|
1717
1790
|
|
|
1718
|
-
// src/
|
|
1719
|
-
var
|
|
1720
|
-
|
|
1721
|
-
"providerSessionId",
|
|
1722
|
-
"codexSessionId",
|
|
1723
|
-
"claudeSessionId"
|
|
1724
|
-
];
|
|
1725
|
-
function normalizeRuntimeSessionId(value) {
|
|
1791
|
+
// src/agent-session-id.ts
|
|
1792
|
+
var AGENT_SESSION_ID_META_KEYS = ["agentSessionId", "sessionId"];
|
|
1793
|
+
function normalizeAgentSessionId(value) {
|
|
1726
1794
|
if (typeof value !== "string") {
|
|
1727
1795
|
return void 0;
|
|
1728
1796
|
}
|
|
@@ -1735,13 +1803,13 @@ function asMetaRecord(meta) {
|
|
|
1735
1803
|
}
|
|
1736
1804
|
return meta;
|
|
1737
1805
|
}
|
|
1738
|
-
function
|
|
1806
|
+
function extractAgentSessionId(meta) {
|
|
1739
1807
|
const record = asMetaRecord(meta);
|
|
1740
1808
|
if (!record) {
|
|
1741
1809
|
return void 0;
|
|
1742
1810
|
}
|
|
1743
|
-
for (const key of
|
|
1744
|
-
const normalized =
|
|
1811
|
+
for (const key of AGENT_SESSION_ID_META_KEYS) {
|
|
1812
|
+
const normalized = normalizeAgentSessionId(record[key]);
|
|
1745
1813
|
if (normalized) {
|
|
1746
1814
|
return normalized;
|
|
1747
1815
|
}
|
|
@@ -2091,6 +2159,9 @@ var TerminalManager = class {
|
|
|
2091
2159
|
var REPLAY_IDLE_MS = 80;
|
|
2092
2160
|
var REPLAY_DRAIN_TIMEOUT_MS = 5e3;
|
|
2093
2161
|
var DRAIN_POLL_INTERVAL_MS = 20;
|
|
2162
|
+
var AGENT_CLOSE_AFTER_STDIN_END_MS = 100;
|
|
2163
|
+
var AGENT_CLOSE_TERM_GRACE_MS = 1500;
|
|
2164
|
+
var AGENT_CLOSE_KILL_GRACE_MS = 1e3;
|
|
2094
2165
|
function shouldSuppressSdkConsoleError(args) {
|
|
2095
2166
|
if (args.length === 0) {
|
|
2096
2167
|
return false;
|
|
@@ -2126,6 +2197,38 @@ function waitForSpawn2(child) {
|
|
|
2126
2197
|
child.once("error", onError);
|
|
2127
2198
|
});
|
|
2128
2199
|
}
|
|
2200
|
+
function isChildProcessRunning(child) {
|
|
2201
|
+
return child.exitCode == null && child.signalCode == null;
|
|
2202
|
+
}
|
|
2203
|
+
function waitForChildExit(child, timeoutMs) {
|
|
2204
|
+
if (!isChildProcessRunning(child)) {
|
|
2205
|
+
return Promise.resolve(true);
|
|
2206
|
+
}
|
|
2207
|
+
return new Promise((resolve) => {
|
|
2208
|
+
let settled = false;
|
|
2209
|
+
const timer = setTimeout(
|
|
2210
|
+
() => {
|
|
2211
|
+
finish(false);
|
|
2212
|
+
},
|
|
2213
|
+
Math.max(0, timeoutMs)
|
|
2214
|
+
);
|
|
2215
|
+
const finish = (value) => {
|
|
2216
|
+
if (settled) {
|
|
2217
|
+
return;
|
|
2218
|
+
}
|
|
2219
|
+
settled = true;
|
|
2220
|
+
child.off("close", onExitLike);
|
|
2221
|
+
child.off("exit", onExitLike);
|
|
2222
|
+
clearTimeout(timer);
|
|
2223
|
+
resolve(value);
|
|
2224
|
+
};
|
|
2225
|
+
const onExitLike = () => {
|
|
2226
|
+
finish(true);
|
|
2227
|
+
};
|
|
2228
|
+
child.once("close", onExitLike);
|
|
2229
|
+
child.once("exit", onExitLike);
|
|
2230
|
+
});
|
|
2231
|
+
}
|
|
2129
2232
|
function splitCommandLine(value) {
|
|
2130
2233
|
const parts = [];
|
|
2131
2234
|
let current = "";
|
|
@@ -2409,7 +2512,7 @@ var AcpClient = class {
|
|
|
2409
2512
|
});
|
|
2410
2513
|
return {
|
|
2411
2514
|
sessionId: result.sessionId,
|
|
2412
|
-
|
|
2515
|
+
agentSessionId: extractAgentSessionId(result._meta)
|
|
2413
2516
|
};
|
|
2414
2517
|
}
|
|
2415
2518
|
async loadSession(sessionId, cwd = this.options.cwd) {
|
|
@@ -2435,7 +2538,7 @@ var AcpClient = class {
|
|
|
2435
2538
|
this.suppressSessionUpdates = previousSuppression;
|
|
2436
2539
|
}
|
|
2437
2540
|
return {
|
|
2438
|
-
|
|
2541
|
+
agentSessionId: extractAgentSessionId(response?._meta)
|
|
2439
2542
|
};
|
|
2440
2543
|
}
|
|
2441
2544
|
async prompt(sessionId, text) {
|
|
@@ -2547,8 +2650,8 @@ var AcpClient = class {
|
|
|
2547
2650
|
async close() {
|
|
2548
2651
|
this.closing = true;
|
|
2549
2652
|
await this.terminalManager.shutdown();
|
|
2550
|
-
if (this.agent
|
|
2551
|
-
this.agent
|
|
2653
|
+
if (this.agent) {
|
|
2654
|
+
await this.terminateAgentProcess(this.agent);
|
|
2552
2655
|
}
|
|
2553
2656
|
this.sessionUpdateChain = Promise.resolve();
|
|
2554
2657
|
this.observedSessionUpdates = 0;
|
|
@@ -2560,6 +2663,44 @@ var AcpClient = class {
|
|
|
2560
2663
|
this.connection = void 0;
|
|
2561
2664
|
this.agent = void 0;
|
|
2562
2665
|
}
|
|
2666
|
+
async terminateAgentProcess(child) {
|
|
2667
|
+
if (!child.stdin.destroyed) {
|
|
2668
|
+
try {
|
|
2669
|
+
child.stdin.end();
|
|
2670
|
+
} catch {
|
|
2671
|
+
}
|
|
2672
|
+
}
|
|
2673
|
+
let exited = await waitForChildExit(child, AGENT_CLOSE_AFTER_STDIN_END_MS);
|
|
2674
|
+
if (!exited && isChildProcessRunning(child)) {
|
|
2675
|
+
try {
|
|
2676
|
+
child.kill("SIGTERM");
|
|
2677
|
+
} catch {
|
|
2678
|
+
}
|
|
2679
|
+
exited = await waitForChildExit(child, AGENT_CLOSE_TERM_GRACE_MS);
|
|
2680
|
+
}
|
|
2681
|
+
if (!exited && isChildProcessRunning(child)) {
|
|
2682
|
+
this.log(
|
|
2683
|
+
`agent did not exit after ${AGENT_CLOSE_TERM_GRACE_MS}ms; forcing SIGKILL`
|
|
2684
|
+
);
|
|
2685
|
+
try {
|
|
2686
|
+
child.kill("SIGKILL");
|
|
2687
|
+
} catch {
|
|
2688
|
+
}
|
|
2689
|
+
exited = await waitForChildExit(child, AGENT_CLOSE_KILL_GRACE_MS);
|
|
2690
|
+
}
|
|
2691
|
+
if (!child.stdin.destroyed) {
|
|
2692
|
+
child.stdin.destroy();
|
|
2693
|
+
}
|
|
2694
|
+
if (!child.stdout.destroyed) {
|
|
2695
|
+
child.stdout.destroy();
|
|
2696
|
+
}
|
|
2697
|
+
if (!child.stderr.destroyed) {
|
|
2698
|
+
child.stderr.destroy();
|
|
2699
|
+
}
|
|
2700
|
+
if (!exited) {
|
|
2701
|
+
child.unref();
|
|
2702
|
+
}
|
|
2703
|
+
}
|
|
2563
2704
|
getConnection() {
|
|
2564
2705
|
if (!this.connection) {
|
|
2565
2706
|
throw new Error("ACP client not started");
|
|
@@ -2884,7 +3025,7 @@ import os2 from "os";
|
|
|
2884
3025
|
import path4 from "path";
|
|
2885
3026
|
|
|
2886
3027
|
// src/queue-messages.ts
|
|
2887
|
-
function
|
|
3028
|
+
function asRecord4(value) {
|
|
2888
3029
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
2889
3030
|
return void 0;
|
|
2890
3031
|
}
|
|
@@ -2903,7 +3044,7 @@ function isOutputErrorOrigin2(value) {
|
|
|
2903
3044
|
return typeof value === "string" && OUTPUT_ERROR_ORIGINS.includes(value);
|
|
2904
3045
|
}
|
|
2905
3046
|
function parseAcpError(value) {
|
|
2906
|
-
const record =
|
|
3047
|
+
const record = asRecord4(value);
|
|
2907
3048
|
if (!record) {
|
|
2908
3049
|
return void 0;
|
|
2909
3050
|
}
|
|
@@ -2920,7 +3061,7 @@ function parseAcpError(value) {
|
|
|
2920
3061
|
};
|
|
2921
3062
|
}
|
|
2922
3063
|
function parseQueueRequest(raw) {
|
|
2923
|
-
const request =
|
|
3064
|
+
const request = asRecord4(raw);
|
|
2924
3065
|
if (!request) {
|
|
2925
3066
|
return null;
|
|
2926
3067
|
}
|
|
@@ -2978,15 +3119,15 @@ function parseQueueRequest(raw) {
|
|
|
2978
3119
|
return null;
|
|
2979
3120
|
}
|
|
2980
3121
|
function parseSessionSendResult(raw) {
|
|
2981
|
-
const result =
|
|
3122
|
+
const result = asRecord4(raw);
|
|
2982
3123
|
if (!result) {
|
|
2983
3124
|
return null;
|
|
2984
3125
|
}
|
|
2985
3126
|
if (typeof result.stopReason !== "string" || typeof result.sessionId !== "string" || typeof result.resumed !== "boolean") {
|
|
2986
3127
|
return null;
|
|
2987
3128
|
}
|
|
2988
|
-
const permissionStats =
|
|
2989
|
-
const record =
|
|
3129
|
+
const permissionStats = asRecord4(result.permissionStats);
|
|
3130
|
+
const record = asRecord4(result.record);
|
|
2990
3131
|
if (!permissionStats || !record) {
|
|
2991
3132
|
return null;
|
|
2992
3133
|
}
|
|
@@ -3001,7 +3142,7 @@ function parseSessionSendResult(raw) {
|
|
|
3001
3142
|
return result;
|
|
3002
3143
|
}
|
|
3003
3144
|
function parseQueueOwnerMessage(raw) {
|
|
3004
|
-
const message =
|
|
3145
|
+
const message = asRecord4(raw);
|
|
3005
3146
|
if (!message || typeof message.type !== "string") {
|
|
3006
3147
|
return null;
|
|
3007
3148
|
}
|
|
@@ -3026,7 +3167,7 @@ function parseQueueOwnerMessage(raw) {
|
|
|
3026
3167
|
};
|
|
3027
3168
|
}
|
|
3028
3169
|
if (message.type === "client_operation") {
|
|
3029
|
-
const operation =
|
|
3170
|
+
const operation = asRecord4(message.operation);
|
|
3030
3171
|
if (!operation || typeof operation.method !== "string" || typeof operation.status !== "string" || typeof operation.summary !== "string" || typeof operation.timestamp !== "string") {
|
|
3031
3172
|
return null;
|
|
3032
3173
|
}
|
|
@@ -3081,7 +3222,7 @@ function parseQueueOwnerMessage(raw) {
|
|
|
3081
3222
|
};
|
|
3082
3223
|
}
|
|
3083
3224
|
if (message.type === "set_config_option_result") {
|
|
3084
|
-
const response =
|
|
3225
|
+
const response = asRecord4(message.response);
|
|
3085
3226
|
if (!response || !Array.isArray(response.configOptions)) {
|
|
3086
3227
|
return null;
|
|
3087
3228
|
}
|
|
@@ -4244,7 +4385,7 @@ function parseSessionRecord(raw) {
|
|
|
4244
4385
|
return null;
|
|
4245
4386
|
}
|
|
4246
4387
|
const record = raw;
|
|
4247
|
-
const
|
|
4388
|
+
const agentSessionId = normalizeAgentSessionId(record.agentSessionId);
|
|
4248
4389
|
const name = record.name == null ? void 0 : typeof record.name === "string" && record.name.trim().length > 0 ? record.name.trim() : null;
|
|
4249
4390
|
const pid = record.pid == null ? void 0 : Number.isInteger(record.pid) && record.pid > 0 ? record.pid : null;
|
|
4250
4391
|
const closed = record.closed == null ? false : typeof record.closed === "boolean" ? record.closed : null;
|
|
@@ -4267,7 +4408,7 @@ function parseSessionRecord(raw) {
|
|
|
4267
4408
|
...record,
|
|
4268
4409
|
id: record.id,
|
|
4269
4410
|
sessionId: record.sessionId,
|
|
4270
|
-
|
|
4411
|
+
agentSessionId,
|
|
4271
4412
|
agentCommand: record.agentCommand,
|
|
4272
4413
|
cwd: record.cwd,
|
|
4273
4414
|
name,
|
|
@@ -4445,11 +4586,196 @@ async function findSessionByDirectoryWalk(options) {
|
|
|
4445
4586
|
}
|
|
4446
4587
|
}
|
|
4447
4588
|
|
|
4589
|
+
// src/session-runtime-history.ts
|
|
4590
|
+
var SESSION_HISTORY_MAX_ENTRIES = 500;
|
|
4591
|
+
var SESSION_HISTORY_PREVIEW_CHARS = 220;
|
|
4592
|
+
function collapseWhitespace2(value) {
|
|
4593
|
+
return value.replace(/\s+/g, " ").trim();
|
|
4594
|
+
}
|
|
4595
|
+
function toPreviewText(value) {
|
|
4596
|
+
const collapsed = collapseWhitespace2(value);
|
|
4597
|
+
if (collapsed.length <= SESSION_HISTORY_PREVIEW_CHARS) {
|
|
4598
|
+
return collapsed;
|
|
4599
|
+
}
|
|
4600
|
+
if (SESSION_HISTORY_PREVIEW_CHARS <= 3) {
|
|
4601
|
+
return collapsed.slice(0, SESSION_HISTORY_PREVIEW_CHARS);
|
|
4602
|
+
}
|
|
4603
|
+
return `${collapsed.slice(0, SESSION_HISTORY_PREVIEW_CHARS - 3)}...`;
|
|
4604
|
+
}
|
|
4605
|
+
function textFromContent(content) {
|
|
4606
|
+
if (content.type === "text") {
|
|
4607
|
+
return content.text;
|
|
4608
|
+
}
|
|
4609
|
+
if (content.type === "resource_link") {
|
|
4610
|
+
return content.title ?? content.name ?? content.uri;
|
|
4611
|
+
}
|
|
4612
|
+
if (content.type === "resource") {
|
|
4613
|
+
if ("text" in content.resource && typeof content.resource.text === "string") {
|
|
4614
|
+
return content.resource.text;
|
|
4615
|
+
}
|
|
4616
|
+
return content.resource.uri;
|
|
4617
|
+
}
|
|
4618
|
+
return void 0;
|
|
4619
|
+
}
|
|
4620
|
+
function toHistoryEntryFromUpdate(notification) {
|
|
4621
|
+
const update = notification.update;
|
|
4622
|
+
if (update.sessionUpdate !== "user_message_chunk" && update.sessionUpdate !== "agent_message_chunk") {
|
|
4623
|
+
return void 0;
|
|
4624
|
+
}
|
|
4625
|
+
const text = textFromContent(update.content);
|
|
4626
|
+
if (!text) {
|
|
4627
|
+
return void 0;
|
|
4628
|
+
}
|
|
4629
|
+
const textPreview = toPreviewText(text);
|
|
4630
|
+
if (!textPreview) {
|
|
4631
|
+
return void 0;
|
|
4632
|
+
}
|
|
4633
|
+
return {
|
|
4634
|
+
role: update.sessionUpdate === "user_message_chunk" ? "user" : "assistant",
|
|
4635
|
+
timestamp: isoNow2(),
|
|
4636
|
+
textPreview
|
|
4637
|
+
};
|
|
4638
|
+
}
|
|
4639
|
+
function appendHistoryEntries(current, entries) {
|
|
4640
|
+
const base = current ? [...current] : [];
|
|
4641
|
+
for (const entry of entries) {
|
|
4642
|
+
if (!entry.textPreview.trim()) {
|
|
4643
|
+
continue;
|
|
4644
|
+
}
|
|
4645
|
+
base.push(entry);
|
|
4646
|
+
}
|
|
4647
|
+
if (base.length <= SESSION_HISTORY_MAX_ENTRIES) {
|
|
4648
|
+
return base;
|
|
4649
|
+
}
|
|
4650
|
+
return base.slice(base.length - SESSION_HISTORY_MAX_ENTRIES);
|
|
4651
|
+
}
|
|
4652
|
+
|
|
4653
|
+
// src/session-runtime-lifecycle.ts
|
|
4654
|
+
function applyLifecycleSnapshotToRecord(record, snapshot) {
|
|
4655
|
+
record.pid = snapshot.pid;
|
|
4656
|
+
record.agentStartedAt = snapshot.startedAt;
|
|
4657
|
+
if (snapshot.lastExit) {
|
|
4658
|
+
record.lastAgentExitCode = snapshot.lastExit.exitCode;
|
|
4659
|
+
record.lastAgentExitSignal = snapshot.lastExit.signal;
|
|
4660
|
+
record.lastAgentExitAt = snapshot.lastExit.exitedAt;
|
|
4661
|
+
record.lastAgentDisconnectReason = snapshot.lastExit.reason;
|
|
4662
|
+
return;
|
|
4663
|
+
}
|
|
4664
|
+
record.lastAgentExitCode = void 0;
|
|
4665
|
+
record.lastAgentExitSignal = void 0;
|
|
4666
|
+
record.lastAgentExitAt = void 0;
|
|
4667
|
+
record.lastAgentDisconnectReason = void 0;
|
|
4668
|
+
}
|
|
4669
|
+
function reconcileAgentSessionId(record, agentSessionId) {
|
|
4670
|
+
const normalized = normalizeAgentSessionId(agentSessionId);
|
|
4671
|
+
if (!normalized) {
|
|
4672
|
+
return;
|
|
4673
|
+
}
|
|
4674
|
+
record.agentSessionId = normalized;
|
|
4675
|
+
}
|
|
4676
|
+
|
|
4677
|
+
// src/session-runtime-reconnect.ts
|
|
4678
|
+
function loadSessionCandidates(record) {
|
|
4679
|
+
const candidates = [normalizeAgentSessionId(record.agentSessionId), record.sessionId];
|
|
4680
|
+
const unique = [];
|
|
4681
|
+
for (const candidate of candidates) {
|
|
4682
|
+
if (!candidate || unique.includes(candidate)) {
|
|
4683
|
+
continue;
|
|
4684
|
+
}
|
|
4685
|
+
unique.push(candidate);
|
|
4686
|
+
}
|
|
4687
|
+
return unique;
|
|
4688
|
+
}
|
|
4689
|
+
async function connectAndLoadSession(options) {
|
|
4690
|
+
const record = options.record;
|
|
4691
|
+
const client = options.client;
|
|
4692
|
+
const storedProcessAlive = isProcessAlive(record.pid);
|
|
4693
|
+
const shouldReconnect = Boolean(record.pid) && !storedProcessAlive;
|
|
4694
|
+
if (options.verbose) {
|
|
4695
|
+
if (storedProcessAlive) {
|
|
4696
|
+
process.stderr.write(
|
|
4697
|
+
`[acpx] saved session pid ${record.pid} is running; reconnecting with loadSession
|
|
4698
|
+
`
|
|
4699
|
+
);
|
|
4700
|
+
} else if (shouldReconnect) {
|
|
4701
|
+
process.stderr.write(
|
|
4702
|
+
`[acpx] saved session pid ${record.pid} is dead; respawning agent and attempting session/load
|
|
4703
|
+
`
|
|
4704
|
+
);
|
|
4705
|
+
}
|
|
4706
|
+
}
|
|
4707
|
+
await options.withTimeout(client.start(), options.timeoutMs);
|
|
4708
|
+
options.onClientAvailable?.(options.activeController);
|
|
4709
|
+
applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());
|
|
4710
|
+
record.closed = false;
|
|
4711
|
+
record.closedAt = void 0;
|
|
4712
|
+
options.onConnectedRecord?.(record);
|
|
4713
|
+
await writeSessionRecord(record);
|
|
4714
|
+
let resumed = false;
|
|
4715
|
+
let loadError;
|
|
4716
|
+
let sessionId = record.sessionId;
|
|
4717
|
+
if (client.supportsLoadSession()) {
|
|
4718
|
+
const candidates = loadSessionCandidates(record);
|
|
4719
|
+
for (const candidate of candidates) {
|
|
4720
|
+
if (options.verbose && candidates.length > 1) {
|
|
4721
|
+
process.stderr.write(`[acpx] attempting session/load with ${candidate}
|
|
4722
|
+
`);
|
|
4723
|
+
}
|
|
4724
|
+
try {
|
|
4725
|
+
const loadResult = await options.withTimeout(
|
|
4726
|
+
client.loadSessionWithOptions(candidate, record.cwd, {
|
|
4727
|
+
suppressReplayUpdates: true
|
|
4728
|
+
}),
|
|
4729
|
+
options.timeoutMs
|
|
4730
|
+
);
|
|
4731
|
+
reconcileAgentSessionId(record, loadResult.agentSessionId);
|
|
4732
|
+
resumed = true;
|
|
4733
|
+
sessionId = candidate;
|
|
4734
|
+
loadError = void 0;
|
|
4735
|
+
break;
|
|
4736
|
+
} catch (error) {
|
|
4737
|
+
loadError = formatErrorMessage(error);
|
|
4738
|
+
if (!options.shouldFallbackToNewSession(error)) {
|
|
4739
|
+
throw error;
|
|
4740
|
+
}
|
|
4741
|
+
if (options.verbose) {
|
|
4742
|
+
process.stderr.write(
|
|
4743
|
+
`[acpx] session/load failed for ${candidate}: ${loadError}
|
|
4744
|
+
`
|
|
4745
|
+
);
|
|
4746
|
+
}
|
|
4747
|
+
}
|
|
4748
|
+
}
|
|
4749
|
+
if (!resumed) {
|
|
4750
|
+
const createdSession = await options.withTimeout(
|
|
4751
|
+
client.createSession(record.cwd),
|
|
4752
|
+
options.timeoutMs
|
|
4753
|
+
);
|
|
4754
|
+
sessionId = createdSession.sessionId;
|
|
4755
|
+
record.sessionId = sessionId;
|
|
4756
|
+
reconcileAgentSessionId(record, createdSession.agentSessionId);
|
|
4757
|
+
}
|
|
4758
|
+
} else {
|
|
4759
|
+
const createdSession = await options.withTimeout(
|
|
4760
|
+
client.createSession(record.cwd),
|
|
4761
|
+
options.timeoutMs
|
|
4762
|
+
);
|
|
4763
|
+
sessionId = createdSession.sessionId;
|
|
4764
|
+
record.sessionId = sessionId;
|
|
4765
|
+
reconcileAgentSessionId(record, createdSession.agentSessionId);
|
|
4766
|
+
}
|
|
4767
|
+
options.onSessionIdResolved?.(sessionId);
|
|
4768
|
+
return {
|
|
4769
|
+
sessionId,
|
|
4770
|
+
agentSessionId: record.agentSessionId,
|
|
4771
|
+
resumed,
|
|
4772
|
+
loadError
|
|
4773
|
+
};
|
|
4774
|
+
}
|
|
4775
|
+
|
|
4448
4776
|
// src/session-runtime.ts
|
|
4449
4777
|
var DEFAULT_QUEUE_OWNER_TTL_MS = 3e5;
|
|
4450
4778
|
var INTERRUPT_CANCEL_WAIT_MS = 2500;
|
|
4451
|
-
var SESSION_HISTORY_MAX_ENTRIES = 500;
|
|
4452
|
-
var SESSION_HISTORY_PREVIEW_CHARS = 220;
|
|
4453
4779
|
var TimeoutError = class extends Error {
|
|
4454
4780
|
constructor(timeoutMs) {
|
|
4455
4781
|
super(`Timed out after ${timeoutMs}ms`);
|
|
@@ -4585,162 +4911,12 @@ function normalizeQueueOwnerTtlMs(ttlMs) {
|
|
|
4585
4911
|
}
|
|
4586
4912
|
return Math.round(ttlMs);
|
|
4587
4913
|
}
|
|
4588
|
-
function collapseWhitespace2(value) {
|
|
4589
|
-
return value.replace(/\s+/g, " ").trim();
|
|
4590
|
-
}
|
|
4591
|
-
function toPreviewText(value) {
|
|
4592
|
-
const collapsed = collapseWhitespace2(value);
|
|
4593
|
-
if (collapsed.length <= SESSION_HISTORY_PREVIEW_CHARS) {
|
|
4594
|
-
return collapsed;
|
|
4595
|
-
}
|
|
4596
|
-
if (SESSION_HISTORY_PREVIEW_CHARS <= 3) {
|
|
4597
|
-
return collapsed.slice(0, SESSION_HISTORY_PREVIEW_CHARS);
|
|
4598
|
-
}
|
|
4599
|
-
return `${collapsed.slice(0, SESSION_HISTORY_PREVIEW_CHARS - 3)}...`;
|
|
4600
|
-
}
|
|
4601
|
-
function textFromContent(content) {
|
|
4602
|
-
if (content.type === "text") {
|
|
4603
|
-
return content.text;
|
|
4604
|
-
}
|
|
4605
|
-
if (content.type === "resource_link") {
|
|
4606
|
-
return content.title ?? content.name ?? content.uri;
|
|
4607
|
-
}
|
|
4608
|
-
if (content.type === "resource") {
|
|
4609
|
-
if ("text" in content.resource && typeof content.resource.text === "string") {
|
|
4610
|
-
return content.resource.text;
|
|
4611
|
-
}
|
|
4612
|
-
return content.resource.uri;
|
|
4613
|
-
}
|
|
4614
|
-
return void 0;
|
|
4615
|
-
}
|
|
4616
|
-
function toHistoryEntryFromUpdate(notification) {
|
|
4617
|
-
const update = notification.update;
|
|
4618
|
-
if (update.sessionUpdate !== "user_message_chunk" && update.sessionUpdate !== "agent_message_chunk") {
|
|
4619
|
-
return void 0;
|
|
4620
|
-
}
|
|
4621
|
-
const text = textFromContent(update.content);
|
|
4622
|
-
if (!text) {
|
|
4623
|
-
return void 0;
|
|
4624
|
-
}
|
|
4625
|
-
const textPreview = toPreviewText(text);
|
|
4626
|
-
if (!textPreview) {
|
|
4627
|
-
return void 0;
|
|
4628
|
-
}
|
|
4629
|
-
return {
|
|
4630
|
-
role: update.sessionUpdate === "user_message_chunk" ? "user" : "assistant",
|
|
4631
|
-
timestamp: isoNow2(),
|
|
4632
|
-
textPreview
|
|
4633
|
-
};
|
|
4634
|
-
}
|
|
4635
|
-
function appendHistoryEntries(current, entries) {
|
|
4636
|
-
const base = current ? [...current] : [];
|
|
4637
|
-
for (const entry of entries) {
|
|
4638
|
-
if (!entry.textPreview.trim()) {
|
|
4639
|
-
continue;
|
|
4640
|
-
}
|
|
4641
|
-
base.push(entry);
|
|
4642
|
-
}
|
|
4643
|
-
if (base.length <= SESSION_HISTORY_MAX_ENTRIES) {
|
|
4644
|
-
return base;
|
|
4645
|
-
}
|
|
4646
|
-
return base.slice(base.length - SESSION_HISTORY_MAX_ENTRIES);
|
|
4647
|
-
}
|
|
4648
|
-
function applyLifecycleSnapshotToRecord(record, snapshot) {
|
|
4649
|
-
record.pid = snapshot.pid;
|
|
4650
|
-
record.agentStartedAt = snapshot.startedAt;
|
|
4651
|
-
if (snapshot.lastExit) {
|
|
4652
|
-
record.lastAgentExitCode = snapshot.lastExit.exitCode;
|
|
4653
|
-
record.lastAgentExitSignal = snapshot.lastExit.signal;
|
|
4654
|
-
record.lastAgentExitAt = snapshot.lastExit.exitedAt;
|
|
4655
|
-
record.lastAgentDisconnectReason = snapshot.lastExit.reason;
|
|
4656
|
-
return;
|
|
4657
|
-
}
|
|
4658
|
-
record.lastAgentExitCode = void 0;
|
|
4659
|
-
record.lastAgentExitSignal = void 0;
|
|
4660
|
-
record.lastAgentExitAt = void 0;
|
|
4661
|
-
record.lastAgentDisconnectReason = void 0;
|
|
4662
|
-
}
|
|
4663
|
-
function reconcileRuntimeSessionId(record, runtimeSessionId) {
|
|
4664
|
-
const normalized = normalizeRuntimeSessionId(runtimeSessionId);
|
|
4665
|
-
if (!normalized) {
|
|
4666
|
-
return;
|
|
4667
|
-
}
|
|
4668
|
-
record.runtimeSessionId = normalized;
|
|
4669
|
-
}
|
|
4670
4914
|
function shouldFallbackToNewSession(error) {
|
|
4671
4915
|
if (error instanceof TimeoutError || error instanceof InterruptedError) {
|
|
4672
4916
|
return false;
|
|
4673
4917
|
}
|
|
4674
4918
|
return isAcpResourceNotFoundError(error);
|
|
4675
4919
|
}
|
|
4676
|
-
async function connectAndLoadSession(options) {
|
|
4677
|
-
const record = options.record;
|
|
4678
|
-
const client = options.client;
|
|
4679
|
-
const storedProcessAlive = isProcessAlive(record.pid);
|
|
4680
|
-
const shouldReconnect = Boolean(record.pid) && !storedProcessAlive;
|
|
4681
|
-
if (options.verbose) {
|
|
4682
|
-
if (storedProcessAlive) {
|
|
4683
|
-
process.stderr.write(
|
|
4684
|
-
`[acpx] saved session pid ${record.pid} is running; reconnecting with loadSession
|
|
4685
|
-
`
|
|
4686
|
-
);
|
|
4687
|
-
} else if (shouldReconnect) {
|
|
4688
|
-
process.stderr.write(
|
|
4689
|
-
`[acpx] saved session pid ${record.pid} is dead; respawning agent and attempting session/load
|
|
4690
|
-
`
|
|
4691
|
-
);
|
|
4692
|
-
}
|
|
4693
|
-
}
|
|
4694
|
-
await withTimeout(client.start(), options.timeoutMs);
|
|
4695
|
-
options.onClientAvailable?.(options.activeController);
|
|
4696
|
-
applyLifecycleSnapshotToRecord(record, client.getAgentLifecycleSnapshot());
|
|
4697
|
-
record.closed = false;
|
|
4698
|
-
record.closedAt = void 0;
|
|
4699
|
-
options.onConnectedRecord?.(record);
|
|
4700
|
-
await writeSessionRecord(record);
|
|
4701
|
-
let resumed = false;
|
|
4702
|
-
let loadError;
|
|
4703
|
-
let sessionId = record.sessionId;
|
|
4704
|
-
if (client.supportsLoadSession()) {
|
|
4705
|
-
try {
|
|
4706
|
-
const loadResult = await withTimeout(
|
|
4707
|
-
client.loadSessionWithOptions(record.sessionId, record.cwd, {
|
|
4708
|
-
suppressReplayUpdates: true
|
|
4709
|
-
}),
|
|
4710
|
-
options.timeoutMs
|
|
4711
|
-
);
|
|
4712
|
-
reconcileRuntimeSessionId(record, loadResult.runtimeSessionId);
|
|
4713
|
-
resumed = true;
|
|
4714
|
-
} catch (error) {
|
|
4715
|
-
loadError = formatErrorMessage(error);
|
|
4716
|
-
if (!shouldFallbackToNewSession(error)) {
|
|
4717
|
-
throw error;
|
|
4718
|
-
}
|
|
4719
|
-
const createdSession = await withTimeout(
|
|
4720
|
-
client.createSession(record.cwd),
|
|
4721
|
-
options.timeoutMs
|
|
4722
|
-
);
|
|
4723
|
-
sessionId = createdSession.sessionId;
|
|
4724
|
-
record.sessionId = sessionId;
|
|
4725
|
-
reconcileRuntimeSessionId(record, createdSession.runtimeSessionId);
|
|
4726
|
-
}
|
|
4727
|
-
} else {
|
|
4728
|
-
const createdSession = await withTimeout(
|
|
4729
|
-
client.createSession(record.cwd),
|
|
4730
|
-
options.timeoutMs
|
|
4731
|
-
);
|
|
4732
|
-
sessionId = createdSession.sessionId;
|
|
4733
|
-
record.sessionId = sessionId;
|
|
4734
|
-
reconcileRuntimeSessionId(record, createdSession.runtimeSessionId);
|
|
4735
|
-
}
|
|
4736
|
-
options.onSessionIdResolved?.(sessionId);
|
|
4737
|
-
return {
|
|
4738
|
-
sessionId,
|
|
4739
|
-
runtimeSessionId: record.runtimeSessionId,
|
|
4740
|
-
resumed,
|
|
4741
|
-
loadError
|
|
4742
|
-
};
|
|
4743
|
-
}
|
|
4744
4920
|
async function runQueuedTask(sessionRecordId, task, options) {
|
|
4745
4921
|
const outputFormatter = task.waitForCompletion ? new QueueTaskOutputFormatter(task) : DISCARD_OUTPUT_FORMATTER;
|
|
4746
4922
|
try {
|
|
@@ -4847,6 +5023,8 @@ async function runSessionPrompt(options) {
|
|
|
4847
5023
|
timeoutMs: options.timeoutMs,
|
|
4848
5024
|
verbose: options.verbose,
|
|
4849
5025
|
activeController,
|
|
5026
|
+
withTimeout,
|
|
5027
|
+
shouldFallbackToNewSession,
|
|
4850
5028
|
onClientAvailable: (controller) => {
|
|
4851
5029
|
options.onClientAvailable?.(controller);
|
|
4852
5030
|
notifiedClientAvailable = true;
|
|
@@ -4981,6 +5159,8 @@ async function withConnectedSession(options) {
|
|
|
4981
5159
|
timeoutMs: options.timeoutMs,
|
|
4982
5160
|
verbose: options.verbose,
|
|
4983
5161
|
activeController,
|
|
5162
|
+
withTimeout,
|
|
5163
|
+
shouldFallbackToNewSession,
|
|
4984
5164
|
onClientAvailable: (controller) => {
|
|
4985
5165
|
options.onClientAvailable?.(controller);
|
|
4986
5166
|
notifiedClientAvailable = true;
|
|
@@ -5139,7 +5319,7 @@ async function createSession(options) {
|
|
|
5139
5319
|
const record = {
|
|
5140
5320
|
id: sessionId,
|
|
5141
5321
|
sessionId,
|
|
5142
|
-
|
|
5322
|
+
agentSessionId: createdSession.agentSessionId,
|
|
5143
5323
|
agentCommand: options.agentCommand,
|
|
5144
5324
|
cwd: absolutePath(options.cwd),
|
|
5145
5325
|
name: normalizeName(options.name),
|
|
@@ -5717,8 +5897,22 @@ function resolveAgentInvocation(explicitAgentName, globalFlags, config) {
|
|
|
5717
5897
|
}
|
|
5718
5898
|
function printSessionsByFormat(sessions, format) {
|
|
5719
5899
|
if (format === "json") {
|
|
5720
|
-
process.stdout.write(
|
|
5721
|
-
|
|
5900
|
+
process.stdout.write(
|
|
5901
|
+
`${JSON.stringify(
|
|
5902
|
+
sessions.map((session) => {
|
|
5903
|
+
const { id, sessionId, agentSessionId, ...rest } = session;
|
|
5904
|
+
return {
|
|
5905
|
+
...rest,
|
|
5906
|
+
...canonicalSessionIdentity({
|
|
5907
|
+
id,
|
|
5908
|
+
sessionId,
|
|
5909
|
+
agentSessionId
|
|
5910
|
+
})
|
|
5911
|
+
};
|
|
5912
|
+
})
|
|
5913
|
+
)}
|
|
5914
|
+
`
|
|
5915
|
+
);
|
|
5722
5916
|
return;
|
|
5723
5917
|
}
|
|
5724
5918
|
if (format === "quiet") {
|
|
@@ -5746,8 +5940,7 @@ function printClosedSessionByFormat(record, format) {
|
|
|
5746
5940
|
process.stdout.write(
|
|
5747
5941
|
`${JSON.stringify({
|
|
5748
5942
|
type: "session_closed",
|
|
5749
|
-
|
|
5750
|
-
sessionId: record.sessionId,
|
|
5943
|
+
...canonicalSessionIdentity(record),
|
|
5751
5944
|
name: record.name
|
|
5752
5945
|
})}
|
|
5753
5946
|
`
|
|
@@ -5760,23 +5953,22 @@ function printClosedSessionByFormat(record, format) {
|
|
|
5760
5953
|
process.stdout.write(`${record.id}
|
|
5761
5954
|
`);
|
|
5762
5955
|
}
|
|
5763
|
-
function
|
|
5764
|
-
const
|
|
5765
|
-
|
|
5766
|
-
|
|
5767
|
-
|
|
5768
|
-
|
|
5956
|
+
function canonicalSessionIdentity(record) {
|
|
5957
|
+
const normalizedAgentSessionId = normalizeAgentSessionId(record.agentSessionId);
|
|
5958
|
+
return {
|
|
5959
|
+
acpxRecordId: record.id,
|
|
5960
|
+
acpxSessionId: record.sessionId,
|
|
5961
|
+
...normalizedAgentSessionId ? { agentSessionId: normalizedAgentSessionId } : {}
|
|
5962
|
+
};
|
|
5769
5963
|
}
|
|
5770
5964
|
function printNewSessionByFormat(record, replaced, format) {
|
|
5771
5965
|
if (format === "json") {
|
|
5772
5966
|
process.stdout.write(
|
|
5773
5967
|
`${JSON.stringify({
|
|
5774
5968
|
type: "session_created",
|
|
5775
|
-
|
|
5776
|
-
sessionId: record.sessionId,
|
|
5969
|
+
...canonicalSessionIdentity(record),
|
|
5777
5970
|
name: record.name,
|
|
5778
|
-
|
|
5779
|
-
...runtimeSessionIdPayload(record.runtimeSessionId)
|
|
5971
|
+
...replaced ? { replacedAcpxRecordId: replaced.id } : {}
|
|
5780
5972
|
})}
|
|
5781
5973
|
`
|
|
5782
5974
|
);
|
|
@@ -5800,11 +5992,9 @@ function printEnsuredSessionByFormat(record, created, format) {
|
|
|
5800
5992
|
process.stdout.write(
|
|
5801
5993
|
`${JSON.stringify({
|
|
5802
5994
|
type: "session_ensured",
|
|
5803
|
-
|
|
5804
|
-
sessionId: record.sessionId,
|
|
5995
|
+
...canonicalSessionIdentity(record),
|
|
5805
5996
|
name: record.name,
|
|
5806
|
-
created
|
|
5807
|
-
...runtimeSessionIdPayload(record.runtimeSessionId)
|
|
5997
|
+
created
|
|
5808
5998
|
})}
|
|
5809
5999
|
`
|
|
5810
6000
|
);
|
|
@@ -5824,7 +6014,7 @@ function printQueuedPromptByFormat(result, format) {
|
|
|
5824
6014
|
process.stdout.write(
|
|
5825
6015
|
`${JSON.stringify({
|
|
5826
6016
|
type: "queued",
|
|
5827
|
-
|
|
6017
|
+
acpxRecordId: result.sessionId,
|
|
5828
6018
|
requestId: result.requestId
|
|
5829
6019
|
})}
|
|
5830
6020
|
`
|
|
@@ -5981,8 +6171,13 @@ async function handleExec(explicitAgentName, promptParts, flags, command, config
|
|
|
5981
6171
|
}
|
|
5982
6172
|
function printCancelResultByFormat(result, format) {
|
|
5983
6173
|
if (format === "json") {
|
|
5984
|
-
process.stdout.write(
|
|
5985
|
-
|
|
6174
|
+
process.stdout.write(
|
|
6175
|
+
`${JSON.stringify({
|
|
6176
|
+
acpxRecordId: result.sessionId || null,
|
|
6177
|
+
cancelled: result.cancelled
|
|
6178
|
+
})}
|
|
6179
|
+
`
|
|
6180
|
+
);
|
|
5986
6181
|
return;
|
|
5987
6182
|
}
|
|
5988
6183
|
if (result.cancelled) {
|
|
@@ -5995,7 +6190,7 @@ function printSetModeResultByFormat(modeId, result, format) {
|
|
|
5995
6190
|
if (format === "json") {
|
|
5996
6191
|
process.stdout.write(
|
|
5997
6192
|
`${JSON.stringify({
|
|
5998
|
-
|
|
6193
|
+
...canonicalSessionIdentity(result.record),
|
|
5999
6194
|
modeId,
|
|
6000
6195
|
resumed: result.resumed
|
|
6001
6196
|
})}
|
|
@@ -6015,7 +6210,7 @@ function printSetConfigOptionResultByFormat(configId, value, result, format) {
|
|
|
6015
6210
|
if (format === "json") {
|
|
6016
6211
|
process.stdout.write(
|
|
6017
6212
|
`${JSON.stringify({
|
|
6018
|
-
|
|
6213
|
+
...canonicalSessionIdentity(result.record),
|
|
6019
6214
|
configId,
|
|
6020
6215
|
value,
|
|
6021
6216
|
resumed: result.resumed,
|
|
@@ -6207,8 +6402,18 @@ async function handleSessionsEnsure(explicitAgentName, flags, command, config) {
|
|
|
6207
6402
|
}
|
|
6208
6403
|
function printSessionDetailsByFormat(record, format) {
|
|
6209
6404
|
if (format === "json") {
|
|
6210
|
-
|
|
6211
|
-
|
|
6405
|
+
const { id, sessionId, agentSessionId, ...rest } = record;
|
|
6406
|
+
process.stdout.write(
|
|
6407
|
+
`${JSON.stringify({
|
|
6408
|
+
...rest,
|
|
6409
|
+
...canonicalSessionIdentity({
|
|
6410
|
+
id,
|
|
6411
|
+
sessionId,
|
|
6412
|
+
agentSessionId
|
|
6413
|
+
})
|
|
6414
|
+
})}
|
|
6415
|
+
`
|
|
6416
|
+
);
|
|
6212
6417
|
return;
|
|
6213
6418
|
}
|
|
6214
6419
|
if (format === "quiet") {
|
|
@@ -6216,11 +6421,11 @@ function printSessionDetailsByFormat(record, format) {
|
|
|
6216
6421
|
`);
|
|
6217
6422
|
return;
|
|
6218
6423
|
}
|
|
6219
|
-
process.stdout.write(`
|
|
6424
|
+
process.stdout.write(`acpxRecordId: ${record.id}
|
|
6220
6425
|
`);
|
|
6221
|
-
process.stdout.write(`
|
|
6426
|
+
process.stdout.write(`acpxSessionId: ${record.sessionId}
|
|
6222
6427
|
`);
|
|
6223
|
-
process.stdout.write(`
|
|
6428
|
+
process.stdout.write(`agentSessionId: ${record.agentSessionId ?? "-"}
|
|
6224
6429
|
`);
|
|
6225
6430
|
process.stdout.write(`agent: ${record.agentCommand}
|
|
6226
6431
|
`);
|
|
@@ -6261,8 +6466,7 @@ function printSessionHistoryByFormat(record, limit, format) {
|
|
|
6261
6466
|
if (format === "json") {
|
|
6262
6467
|
process.stdout.write(
|
|
6263
6468
|
`${JSON.stringify({
|
|
6264
|
-
|
|
6265
|
-
sessionId: record.sessionId,
|
|
6469
|
+
...canonicalSessionIdentity(record),
|
|
6266
6470
|
limit,
|
|
6267
6471
|
count: visible.length,
|
|
6268
6472
|
entries: visible
|
|
@@ -6348,7 +6552,9 @@ async function handleStatus(explicitAgentName, flags, command, config) {
|
|
|
6348
6552
|
});
|
|
6349
6553
|
if (!record) {
|
|
6350
6554
|
const payload2 = {
|
|
6351
|
-
|
|
6555
|
+
acpxRecordId: null,
|
|
6556
|
+
acpxSessionId: null,
|
|
6557
|
+
agentSessionId: null,
|
|
6352
6558
|
agentCommand: agent.agentCommand,
|
|
6353
6559
|
pid: null,
|
|
6354
6560
|
status: "no-session",
|
|
@@ -6382,15 +6588,14 @@ async function handleStatus(explicitAgentName, flags, command, config) {
|
|
|
6382
6588
|
}
|
|
6383
6589
|
const running = isProcessAlive(record.pid);
|
|
6384
6590
|
const payload = {
|
|
6385
|
-
|
|
6591
|
+
...canonicalSessionIdentity(record),
|
|
6386
6592
|
agentCommand: record.agentCommand,
|
|
6387
6593
|
pid: record.pid ?? null,
|
|
6388
6594
|
status: running ? "running" : "dead",
|
|
6389
6595
|
uptime: running ? formatUptime(record.agentStartedAt) ?? null : null,
|
|
6390
6596
|
lastPromptTime: record.lastPromptAt ?? null,
|
|
6391
6597
|
exitCode: running ? null : record.lastAgentExitCode ?? null,
|
|
6392
|
-
signal: running ? null : record.lastAgentExitSignal ?? null
|
|
6393
|
-
...runtimeSessionIdPayload(record.runtimeSessionId)
|
|
6598
|
+
signal: running ? null : record.lastAgentExitSignal ?? null
|
|
6394
6599
|
};
|
|
6395
6600
|
if (globalFlags.format === "json") {
|
|
6396
6601
|
process.stdout.write(`${JSON.stringify(payload)}
|
|
@@ -6402,12 +6607,12 @@ async function handleStatus(explicitAgentName, flags, command, config) {
|
|
|
6402
6607
|
`);
|
|
6403
6608
|
return;
|
|
6404
6609
|
}
|
|
6405
|
-
process.stdout.write(`
|
|
6610
|
+
process.stdout.write(`acpxRecordId: ${payload.acpxRecordId}
|
|
6406
6611
|
`);
|
|
6407
|
-
|
|
6408
|
-
|
|
6612
|
+
process.stdout.write(`acpxSessionId: ${payload.acpxSessionId}
|
|
6613
|
+
`);
|
|
6614
|
+
process.stdout.write(`agentSessionId: ${payload.agentSessionId ?? "-"}
|
|
6409
6615
|
`);
|
|
6410
|
-
}
|
|
6411
6616
|
process.stdout.write(`agent: ${payload.agentCommand}
|
|
6412
6617
|
`);
|
|
6413
6618
|
process.stdout.write(`pid: ${payload.pid ?? "-"}
|