@songsid/agend 2.1.7-beta.4 → 2.1.7-beta.6
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/README.md +2 -0
- package/README.zh-TW.md +2 -0
- package/dist/agent-cli-instructions.md +5 -0
- package/dist/agent-cli.js +13 -0
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +1 -0
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/backend/codex-session-lookup.d.ts +59 -0
- package/dist/backend/codex-session-lookup.js +139 -0
- package/dist/backend/codex-session-lookup.js.map +1 -0
- package/dist/backend/codex.d.ts +37 -9
- package/dist/backend/codex.js +204 -38
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok.js +51 -0
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/types.d.ts +12 -0
- package/dist/backend/types.js.map +1 -1
- package/dist/channel/mcp-tools.js +2 -0
- package/dist/channel/mcp-tools.js.map +1 -1
- package/dist/cli.js +137 -124
- package/dist/cli.js.map +1 -1
- package/dist/completion-install.d.ts +32 -0
- package/dist/completion-install.js +125 -1
- package/dist/completion-install.js.map +1 -1
- package/dist/config-validator.js +4 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/daemon.d.ts +12 -1
- package/dist/daemon.js +186 -27
- package/dist/daemon.js.map +1 -1
- package/dist/delivery-outbox.d.ts +199 -6
- package/dist/delivery-outbox.js +602 -44
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-outbox.test.js +268 -14
- package/dist/delivery-outbox.test.js.map +1 -1
- package/dist/delivery-queue-evidence.d.ts +15 -0
- package/dist/delivery-queue-evidence.js +35 -0
- package/dist/delivery-queue-evidence.js.map +1 -0
- package/dist/delivery-queue-evidence.test.d.ts +1 -0
- package/dist/delivery-queue-evidence.test.js +23 -0
- package/dist/delivery-queue-evidence.test.js.map +1 -0
- package/dist/delivery-reconciliation.d.ts +49 -0
- package/dist/delivery-reconciliation.js +296 -0
- package/dist/delivery-reconciliation.js.map +1 -0
- package/dist/delivery-reconciliation.test.d.ts +1 -0
- package/dist/delivery-reconciliation.test.js +411 -0
- package/dist/delivery-reconciliation.test.js.map +1 -0
- package/dist/fleet-manager.d.ts +10 -1
- package/dist/fleet-manager.js +109 -32
- package/dist/fleet-manager.js.map +1 -1
- package/dist/general-knowledge/skills/cross-instance-messaging/SKILL.md +10 -0
- package/dist/instance-lifecycle.d.ts +13 -0
- package/dist/instance-lifecycle.js +105 -21
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/instructions.d.ts +6 -0
- package/dist/instructions.js +9 -0
- package/dist/instructions.js.map +1 -1
- package/dist/locale.js +8 -0
- package/dist/locale.js.map +1 -1
- package/dist/ls-rows.d.ts +50 -0
- package/dist/ls-rows.js +152 -0
- package/dist/ls-rows.js.map +1 -0
- package/dist/outbound-handlers.d.ts +3 -0
- package/dist/outbound-handlers.js +38 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +8 -0
- package/dist/outbound-schemas.js +15 -0
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/pane-write-lock.d.ts +2 -0
- package/dist/pane-write-lock.js +19 -0
- package/dist/pane-write-lock.js.map +1 -1
- package/dist/quickstart.js +9 -3
- package/dist/quickstart.js.map +1 -1
- package/dist/remote-credential-check.d.ts +26 -7
- package/dist/remote-credential-check.js +157 -10
- package/dist/remote-credential-check.js.map +1 -1
- package/dist/scheduler/scheduler.d.ts +5 -1
- package/dist/scheduler/scheduler.js +60 -20
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/scheduler.test.js +41 -2
- package/dist/scheduler/scheduler.test.js.map +1 -1
- package/dist/scheduler/types.d.ts +1 -1
- package/dist/tmux-manager.d.ts +3 -3
- package/dist/tmux-manager.js +6 -6
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tool-permissions.js +6 -6
- package/dist/tool-permissions.js.map +1 -1
- package/dist/transcript-monitor.d.ts +3 -1
- package/dist/transcript-monitor.js +15 -0
- package/dist/transcript-monitor.js.map +1 -1
- package/dist/transcript-sources.d.ts +9 -0
- package/dist/transcript-sources.js +14 -0
- package/dist/transcript-sources.js.map +1 -1
- package/dist/types.d.ts +6 -0
- package/dist/ui/dashboard.html +7 -5
- package/dist/ui/view.html +138 -45
- package/dist/usage/usage-api.js +30 -0
- package/dist/usage/usage-api.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DurableSubmissionMode } from "./delivery-outbox.js";
|
|
2
|
+
/**
|
|
3
|
+
* Whether a CLI may restore an in-flight native queue item after its process
|
|
4
|
+
* exits and the same session is resumed. This is a versioned, fail-closed
|
|
5
|
+
* contract: a backend/version is eligible for `does_not_resume` only after a
|
|
6
|
+
* whole-CLI-process restart test proves that behavior.
|
|
7
|
+
*/
|
|
8
|
+
export type QueueResumePolicy = "not_applicable" | "unknown" | "may_resume" | "does_not_resume";
|
|
9
|
+
export declare function queueResumePolicyForAttempt(backend: string, backendVersion: string | null, submissionMode: DurableSubmissionMode): QueueResumePolicy;
|
|
10
|
+
/**
|
|
11
|
+
* A stable transcript without the marker is negative proof only when the
|
|
12
|
+
* attempt was not handed to a CLI-owned queue, or an exact CLI version has a
|
|
13
|
+
* validated contract that resume cannot replay that queue item.
|
|
14
|
+
*/
|
|
15
|
+
export declare function transcriptAbsenceCanProveNotSubmitted(submissionMode: DurableSubmissionMode | null, queueResumePolicy: QueueResumePolicy | null): boolean;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No shipped CLI version is allowlisted yet. Codex's PTY queue and Claude's
|
|
3
|
+
* interactive queued-input behavior have not been validated across a process
|
|
4
|
+
* exit/resume, so a missing or newly upgraded version stays `unknown`.
|
|
5
|
+
*/
|
|
6
|
+
const VERIFIED_QUEUE_RESUME_POLICIES = {
|
|
7
|
+
"claude-code": {},
|
|
8
|
+
codex: {},
|
|
9
|
+
muse: {},
|
|
10
|
+
"kiro-cli": {},
|
|
11
|
+
antigravity: {},
|
|
12
|
+
};
|
|
13
|
+
export function queueResumePolicyForAttempt(backend, backendVersion, submissionMode) {
|
|
14
|
+
if (submissionMode === "idle_submit")
|
|
15
|
+
return "not_applicable";
|
|
16
|
+
if (!backendVersion)
|
|
17
|
+
return "unknown";
|
|
18
|
+
return VERIFIED_QUEUE_RESUME_POLICIES[backend]?.[backendVersion] ?? "unknown";
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A stable transcript without the marker is negative proof only when the
|
|
22
|
+
* attempt was not handed to a CLI-owned queue, or an exact CLI version has a
|
|
23
|
+
* validated contract that resume cannot replay that queue item.
|
|
24
|
+
*/
|
|
25
|
+
export function transcriptAbsenceCanProveNotSubmitted(submissionMode, queueResumePolicy) {
|
|
26
|
+
if (submissionMode === "idle_submit")
|
|
27
|
+
return true;
|
|
28
|
+
if (submissionMode === "native_queue_handoff" || submissionMode === "steer") {
|
|
29
|
+
return queueResumePolicy === "does_not_resume";
|
|
30
|
+
}
|
|
31
|
+
// Old rows and unknown submission modes do not have enough evidence to
|
|
32
|
+
// authorize a replay.
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=delivery-queue-evidence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-queue-evidence.js","sourceRoot":"","sources":["../src/delivery-queue-evidence.ts"],"names":[],"mappings":"AAcA;;;;GAIG;AACH,MAAM,8BAA8B,GAA0E;IAC5G,aAAa,EAAE,EAAE;IACjB,KAAK,EAAE,EAAE;IACT,IAAI,EAAE,EAAE;IACR,UAAU,EAAE,EAAE;IACd,WAAW,EAAE,EAAE;CAChB,CAAC;AAEF,MAAM,UAAU,2BAA2B,CACzC,OAAe,EACf,cAA6B,EAC7B,cAAqC;IAErC,IAAI,cAAc,KAAK,aAAa;QAAE,OAAO,gBAAgB,CAAC;IAC9D,IAAI,CAAC,cAAc;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,8BAA8B,CAAC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;AAChF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,qCAAqC,CACnD,cAA4C,EAC5C,iBAA2C;IAE3C,IAAI,cAAc,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IAClD,IAAI,cAAc,KAAK,sBAAsB,IAAI,cAAc,KAAK,OAAO,EAAE,CAAC;QAC5E,OAAO,iBAAiB,KAAK,iBAAiB,CAAC;IACjD,CAAC;IACD,uEAAuE;IACvE,sBAAsB;IACtB,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { queueResumePolicyForAttempt, transcriptAbsenceCanProveNotSubmitted } from "./delivery-queue-evidence.js";
|
|
3
|
+
describe("durable native-queue recovery policy", () => {
|
|
4
|
+
it.each([
|
|
5
|
+
["Codex without a captured CLI version", "codex", null, "native_queue_handoff"],
|
|
6
|
+
["Codex at an unvalidated version", "codex", "0.157.0", "native_queue_handoff"],
|
|
7
|
+
["Claude steering at an unvalidated version", "claude-code", "2.1.99", "steer"],
|
|
8
|
+
["an unknown backend", "custom-backend", "1.0.0", "native_queue_handoff"],
|
|
9
|
+
])("defaults %s to an unknown resume contract", (_description, backend, version, mode) => {
|
|
10
|
+
expect(queueResumePolicyForAttempt(backend, version, mode)).toBe("unknown");
|
|
11
|
+
});
|
|
12
|
+
it("marks ordinary idle submissions as outside the CLI-owned queue contract", () => {
|
|
13
|
+
expect(queueResumePolicyForAttempt("codex", "0.157.0", "idle_submit")).toBe("not_applicable");
|
|
14
|
+
});
|
|
15
|
+
it("uses transcript absence as negative proof only when queue ownership cannot replay", () => {
|
|
16
|
+
expect(transcriptAbsenceCanProveNotSubmitted("idle_submit", "not_applicable")).toBe(true);
|
|
17
|
+
expect(transcriptAbsenceCanProveNotSubmitted("native_queue_handoff", "unknown")).toBe(false);
|
|
18
|
+
expect(transcriptAbsenceCanProveNotSubmitted("native_queue_handoff", "may_resume")).toBe(false);
|
|
19
|
+
expect(transcriptAbsenceCanProveNotSubmitted("steer", "does_not_resume")).toBe(true);
|
|
20
|
+
expect(transcriptAbsenceCanProveNotSubmitted(null, null)).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=delivery-queue-evidence.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-queue-evidence.test.js","sourceRoot":"","sources":["../src/delivery-queue-evidence.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,2BAA2B,EAAE,qCAAqC,EAAE,MAAM,8BAA8B,CAAC;AAElH,QAAQ,CAAC,sCAAsC,EAAE,GAAG,EAAE;IACpD,EAAE,CAAC,IAAI,CAAC;QACN,CAAC,sCAAsC,EAAE,OAAO,EAAE,IAAI,EAAE,sBAA+B,CAAC;QACxF,CAAC,iCAAiC,EAAE,OAAO,EAAE,SAAS,EAAE,sBAA+B,CAAC;QACxF,CAAC,2CAA2C,EAAE,aAAa,EAAE,QAAQ,EAAE,OAAgB,CAAC;QACxF,CAAC,oBAAoB,EAAE,gBAAgB,EAAE,OAAO,EAAE,sBAA+B,CAAC;KACnF,CAAC,CAAC,2CAA2C,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACvF,MAAM,CAAC,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,CAAC,2BAA2B,CAAC,OAAO,EAAE,SAAS,EAAE,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAChG,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,GAAG,EAAE;QAC3F,MAAM,CAAC,qCAAqC,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1F,MAAM,CAAC,qCAAqC,CAAC,sBAAsB,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7F,MAAM,CAAC,qCAAqC,CAAC,sBAAsB,EAAE,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChG,MAAM,CAAC,qCAAqC,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrF,MAAM,CAAC,qCAAqC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Logger } from "./logger.js";
|
|
2
|
+
import { DeliveryOutbox, type DeliveryReconciliationCandidate } from "./delivery-outbox.js";
|
|
3
|
+
export declare const RECONCILIATION_PANE_CAPTURE_TIMEOUT_MS = 2000;
|
|
4
|
+
export declare const RECONCILIATION_WRITE_DRAIN_TIMEOUT_MS = 15000;
|
|
5
|
+
export declare const RECONCILIATION_WINDOW_EXIT_TIMEOUT_MS = 15000;
|
|
6
|
+
export declare const RECONCILIATION_TRANSCRIPT_STABLE_TIMEOUT_MS = 10000;
|
|
7
|
+
export interface CapturedAttempt {
|
|
8
|
+
candidate: DeliveryReconciliationCandidate;
|
|
9
|
+
paneWindowId: string | null;
|
|
10
|
+
panePid: number | null;
|
|
11
|
+
pane: string | null;
|
|
12
|
+
paneCaptureError: string | null;
|
|
13
|
+
}
|
|
14
|
+
/** Split capture from retirement so an in-process Daemon.stop can own the kill. */
|
|
15
|
+
export interface CapturedTargetReconciliation {
|
|
16
|
+
targetInstance: string;
|
|
17
|
+
sessionName: string;
|
|
18
|
+
savedWindowId: string | null;
|
|
19
|
+
attempts: CapturedAttempt[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Capture the old pane before a stop/replacement startup can destroy it. This
|
|
23
|
+
* is per-target; callers do not gate unrelated daemon starts or dispatch lanes.
|
|
24
|
+
*/
|
|
25
|
+
export declare function capturePendingTargetReconciliation(outbox: DeliveryOutbox, targetInstance: string, instanceDir: string, sessionName?: string, logger?: Pick<Logger, "debug" | "warn">): Promise<CapturedTargetReconciliation>;
|
|
26
|
+
/** A unique marker counts only at the start of a persisted user-message body. */
|
|
27
|
+
export declare function transcriptDeltaHasDeliveryMarker(rawDelta: string, backend: string, deliveryId: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* After the old CLI is positively gone, classify the attempt. A committed
|
|
30
|
+
* Enter-start marker prevents composer-only negative proof from authorizing a
|
|
31
|
+
* replay. A stable transcript absence may retry an idle submit, but a native
|
|
32
|
+
* queue/steer handoff stays uncertain unless its exact CLI-version policy was
|
|
33
|
+
* validated not to replay that queue item after resume.
|
|
34
|
+
*/
|
|
35
|
+
export declare function finishTargetReconciliation(outbox: DeliveryOutbox, captured: CapturedTargetReconciliation, oldWindowGone: boolean, logger?: Pick<Logger, "debug" | "warn">): Promise<{
|
|
36
|
+
delivered: number;
|
|
37
|
+
retry: number;
|
|
38
|
+
uncertain: number;
|
|
39
|
+
safeToStart: boolean;
|
|
40
|
+
}>;
|
|
41
|
+
/** Retire and positively verify every captured old window after a Daemon.stop. */
|
|
42
|
+
export declare function retireCapturedTargetWindows(captured: CapturedTargetReconciliation): Promise<boolean>;
|
|
43
|
+
/** Startup path: capture first, retire the old Strategy-A window, verify exit, then read transcript. */
|
|
44
|
+
export declare function reconcileTargetBeforeStart(outbox: DeliveryOutbox, targetInstance: string, instanceDir: string, logger?: Pick<Logger, "debug" | "warn">): Promise<{
|
|
45
|
+
delivered: number;
|
|
46
|
+
retry: number;
|
|
47
|
+
uncertain: number;
|
|
48
|
+
safeToStart: boolean;
|
|
49
|
+
}>;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { open, stat } from "node:fs/promises";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { getTmuxSession } from "./config.js";
|
|
5
|
+
import { transcriptAbsenceCanProveNotSubmitted } from "./delivery-queue-evidence.js";
|
|
6
|
+
import { TmuxManager } from "./tmux-manager.js";
|
|
7
|
+
export const RECONCILIATION_PANE_CAPTURE_TIMEOUT_MS = 2_000;
|
|
8
|
+
export const RECONCILIATION_WRITE_DRAIN_TIMEOUT_MS = 15_000;
|
|
9
|
+
export const RECONCILIATION_WINDOW_EXIT_TIMEOUT_MS = 15_000;
|
|
10
|
+
export const RECONCILIATION_TRANSCRIPT_STABLE_TIMEOUT_MS = 10_000;
|
|
11
|
+
const TRANSCRIPT_MAX_DELTA_BYTES = 64 * 1024 * 1024;
|
|
12
|
+
const ENTER_MARKER = (deliveryId) => `[agend-delivery-id:${deliveryId}]`;
|
|
13
|
+
function readSavedWindowId(instanceDir) {
|
|
14
|
+
try {
|
|
15
|
+
return readFileSync(join(instanceDir, "window-id"), "utf-8").trim() || null;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
async function withTimeout(promise, ms, label) {
|
|
22
|
+
let timer;
|
|
23
|
+
try {
|
|
24
|
+
return await Promise.race([
|
|
25
|
+
promise,
|
|
26
|
+
new Promise((_resolve, reject) => {
|
|
27
|
+
timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
|
|
28
|
+
timer.unref?.();
|
|
29
|
+
}),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
if (timer)
|
|
34
|
+
clearTimeout(timer);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Capture the old pane before a stop/replacement startup can destroy it. This
|
|
39
|
+
* is per-target; callers do not gate unrelated daemon starts or dispatch lanes.
|
|
40
|
+
*/
|
|
41
|
+
export async function capturePendingTargetReconciliation(outbox, targetInstance, instanceDir, sessionName = getTmuxSession(), logger) {
|
|
42
|
+
const candidates = outbox.getReconciliationCandidates(targetInstance);
|
|
43
|
+
const savedWindowId = readSavedWindowId(instanceDir);
|
|
44
|
+
const uniqueWindowIds = [...new Set(candidates.map(item => item.attempt.windowId ?? savedWindowId).filter((id) => !!id))];
|
|
45
|
+
const paneByWindow = new Map();
|
|
46
|
+
await Promise.all(uniqueWindowIds.map(async (windowId) => {
|
|
47
|
+
const tmux = new TmuxManager(sessionName, windowId);
|
|
48
|
+
let panePid = null;
|
|
49
|
+
let pane = null;
|
|
50
|
+
let error = null;
|
|
51
|
+
try {
|
|
52
|
+
panePid = await TmuxManager.getPanePid(sessionName, windowId, RECONCILIATION_PANE_CAPTURE_TIMEOUT_MS);
|
|
53
|
+
pane = await tmux.capturePane(RECONCILIATION_PANE_CAPTURE_TIMEOUT_MS);
|
|
54
|
+
}
|
|
55
|
+
catch (err) {
|
|
56
|
+
error = err instanceof Error ? err.message : String(err);
|
|
57
|
+
logger?.debug({ targetInstance, windowId, err: error }, "Could not capture old pane before durable reconciliation");
|
|
58
|
+
}
|
|
59
|
+
paneByWindow.set(windowId, { pane, panePid, error });
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
targetInstance,
|
|
63
|
+
sessionName,
|
|
64
|
+
savedWindowId,
|
|
65
|
+
attempts: candidates.map(candidate => {
|
|
66
|
+
const paneWindowId = candidate.attempt.windowId ?? savedWindowId;
|
|
67
|
+
const captured = paneWindowId ? paneByWindow.get(paneWindowId) : undefined;
|
|
68
|
+
return {
|
|
69
|
+
candidate,
|
|
70
|
+
paneWindowId,
|
|
71
|
+
panePid: captured?.panePid ?? null,
|
|
72
|
+
pane: captured?.pane ?? null,
|
|
73
|
+
paneCaptureError: captured?.error ?? (paneWindowId ? "pane capture unavailable" : "old window id unavailable"),
|
|
74
|
+
};
|
|
75
|
+
}),
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
async function processHasExited(pid) {
|
|
79
|
+
if (!pid)
|
|
80
|
+
return true; // tmux's confirmed window removal is the remaining fence.
|
|
81
|
+
const deadline = Date.now() + RECONCILIATION_WINDOW_EXIT_TIMEOUT_MS;
|
|
82
|
+
while (Date.now() < deadline) {
|
|
83
|
+
try {
|
|
84
|
+
process.kill(pid, 0);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (err.code === "ESRCH")
|
|
88
|
+
return true;
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
92
|
+
}
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
async function readTranscriptDelta(candidate) {
|
|
96
|
+
const path = candidate.attempt.transcriptPath;
|
|
97
|
+
const offset = candidate.attempt.transcriptOffset;
|
|
98
|
+
if (!path || offset === null || !candidate.attempt.backend
|
|
99
|
+
|| !["claude-code", "codex"].includes(candidate.attempt.backend))
|
|
100
|
+
return "unavailable";
|
|
101
|
+
const deadline = Date.now() + RECONCILIATION_TRANSCRIPT_STABLE_TIMEOUT_MS;
|
|
102
|
+
let previousSize = -1;
|
|
103
|
+
let stableChecks = 0;
|
|
104
|
+
let size = 0;
|
|
105
|
+
while (Date.now() < deadline) {
|
|
106
|
+
try {
|
|
107
|
+
size = (await stat(path)).size;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return "unavailable";
|
|
111
|
+
}
|
|
112
|
+
if (size === previousSize)
|
|
113
|
+
stableChecks++;
|
|
114
|
+
else
|
|
115
|
+
stableChecks = 0;
|
|
116
|
+
if (stableChecks >= 2)
|
|
117
|
+
break;
|
|
118
|
+
previousSize = size;
|
|
119
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
120
|
+
}
|
|
121
|
+
if (stableChecks < 2 || size < offset || size - offset > TRANSCRIPT_MAX_DELTA_BYTES)
|
|
122
|
+
return "unavailable";
|
|
123
|
+
try {
|
|
124
|
+
const fh = await open(path, "r");
|
|
125
|
+
try {
|
|
126
|
+
const length = size - offset;
|
|
127
|
+
if (!length)
|
|
128
|
+
return "no-match";
|
|
129
|
+
const buffer = Buffer.alloc(length);
|
|
130
|
+
const { bytesRead } = await fh.read(buffer, 0, length, offset);
|
|
131
|
+
const found = transcriptDeltaHasDeliveryMarker(buffer.toString("utf8", 0, bytesRead), candidate.attempt.backend, candidate.deliveryId);
|
|
132
|
+
return found ? "matched" : "no-match";
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
await fh.close();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return "unavailable";
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function userTextsFromEntry(entry, backend) {
|
|
143
|
+
if (!entry || typeof entry !== "object")
|
|
144
|
+
return [];
|
|
145
|
+
const value = entry;
|
|
146
|
+
if (backend === "claude-code") {
|
|
147
|
+
const message = value.message;
|
|
148
|
+
if (value.type !== "user" || message?.role !== "user")
|
|
149
|
+
return [];
|
|
150
|
+
const content = message.content;
|
|
151
|
+
if (typeof content === "string")
|
|
152
|
+
return [content];
|
|
153
|
+
if (!Array.isArray(content))
|
|
154
|
+
return [];
|
|
155
|
+
return content.filter((item) => item?.type === "text" && typeof item.text === "string")
|
|
156
|
+
.map((item) => item.text);
|
|
157
|
+
}
|
|
158
|
+
if (backend === "codex") {
|
|
159
|
+
const payload = value.payload;
|
|
160
|
+
if (value.type !== "response_item" || payload?.type !== "message" || payload?.role !== "user")
|
|
161
|
+
return [];
|
|
162
|
+
if (!Array.isArray(payload.content))
|
|
163
|
+
return [];
|
|
164
|
+
return payload.content.filter((item) => item?.type === "input_text" && typeof item.text === "string")
|
|
165
|
+
.map((item) => item.text);
|
|
166
|
+
}
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
/** A unique marker counts only at the start of a persisted user-message body. */
|
|
170
|
+
export function transcriptDeltaHasDeliveryMarker(rawDelta, backend, deliveryId) {
|
|
171
|
+
const marker = ENTER_MARKER(deliveryId);
|
|
172
|
+
for (const line of rawDelta.split(/\r?\n/)) {
|
|
173
|
+
if (!line.trim())
|
|
174
|
+
continue;
|
|
175
|
+
try {
|
|
176
|
+
const entry = JSON.parse(line);
|
|
177
|
+
const firstUserText = userTextsFromEntry(entry, backend)[0];
|
|
178
|
+
if (firstUserText?.startsWith(marker))
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
catch { /* incomplete/malformed JSONL is not proof */ }
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* After the old CLI is positively gone, classify the attempt. A committed
|
|
187
|
+
* Enter-start marker prevents composer-only negative proof from authorizing a
|
|
188
|
+
* replay. A stable transcript absence may retry an idle submit, but a native
|
|
189
|
+
* queue/steer handoff stays uncertain unless its exact CLI-version policy was
|
|
190
|
+
* validated not to replay that queue item after resume.
|
|
191
|
+
*/
|
|
192
|
+
export async function finishTargetReconciliation(outbox, captured, oldWindowGone, logger) {
|
|
193
|
+
const result = {
|
|
194
|
+
delivered: 0,
|
|
195
|
+
retry: 0,
|
|
196
|
+
uncertain: 0,
|
|
197
|
+
safeToStart: captured.attempts.length === 0 || oldWindowGone,
|
|
198
|
+
};
|
|
199
|
+
for (const item of captured.attempts) {
|
|
200
|
+
const { candidate } = item;
|
|
201
|
+
// A missing window id is not evidence that the old CLI exited: there was
|
|
202
|
+
// no object to retire or verify. Keep this target fenced rather than
|
|
203
|
+
// letting Strategy A start a replacement beside an unverified process.
|
|
204
|
+
const processExited = oldWindowGone && !!item.paneWindowId
|
|
205
|
+
&& await processHasExited(item.panePid);
|
|
206
|
+
if (!processExited)
|
|
207
|
+
result.safeToStart = false;
|
|
208
|
+
const transcript = processExited ? await readTranscriptDelta(candidate) : "unavailable";
|
|
209
|
+
let outcome;
|
|
210
|
+
let proof;
|
|
211
|
+
if (transcript === "matched") {
|
|
212
|
+
outcome = "delivered";
|
|
213
|
+
proof = "cli-transcript-user-entry-marker";
|
|
214
|
+
}
|
|
215
|
+
else if (!candidate.attempt.enterStartedAt && processExited) {
|
|
216
|
+
// W1 is authoritative negative evidence for ordinary envelopes: this
|
|
217
|
+
// process cannot have sent Enter before the timestamp was committed.
|
|
218
|
+
// Raw paste additionally requires the exact bytes at the end of the
|
|
219
|
+
// pre-kill capture, where the active composer sits; a missing composer
|
|
220
|
+
// snapshot is ambiguous and must not silently turn into a replay.
|
|
221
|
+
const rawBytes = candidate.kind === "raw_paste" && typeof candidate.payload.content === "string"
|
|
222
|
+
? candidate.payload.content
|
|
223
|
+
: null;
|
|
224
|
+
const capturedTail = item.pane?.replace(/\r\n/g, "\n").replace(/\n$/, "") ?? "";
|
|
225
|
+
const rawComposerVisible = rawBytes !== null && rawBytes.length > 0 && !rawBytes.endsWith("\n")
|
|
226
|
+
&& capturedTail.endsWith(rawBytes);
|
|
227
|
+
if (candidate.kind !== "raw_paste" || rawComposerVisible) {
|
|
228
|
+
outcome = "retry_wait";
|
|
229
|
+
proof = candidate.kind === "raw_paste"
|
|
230
|
+
? "raw-composer-exact-bytes; enter-not-started; old-process-exited"
|
|
231
|
+
: item.paneCaptureError ? "enter-not-started; pane-capture-unavailable" : "enter-not-started; pre-kill-pane-captured";
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
outcome = "uncertain";
|
|
235
|
+
proof = "raw-composer-bytes-not-proven; enter-not-started; old-process-exited";
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
else if (item.panePid !== null && processExited && transcript === "no-match"
|
|
239
|
+
&& transcriptAbsenceCanProveNotSubmitted(candidate.attempt.submissionMode, candidate.attempt.queueResumePolicy)) {
|
|
240
|
+
// A complete, stable transcript is negative evidence for an ordinary
|
|
241
|
+
// idle submit. A native queue/steer entry can be absent because it is
|
|
242
|
+
// still owned by the CLI queue, so only an exact, persisted version
|
|
243
|
+
// policy that rules out resume replay can use absence for that mode.
|
|
244
|
+
outcome = "retry_wait";
|
|
245
|
+
proof = candidate.attempt.submissionMode === "idle_submit"
|
|
246
|
+
? "complete-transcript-no-marker; non-queued-submit"
|
|
247
|
+
: "complete-transcript-no-marker; queue-version-proven-no-resume";
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
outcome = "uncertain";
|
|
251
|
+
proof = !processExited
|
|
252
|
+
? "old-cli-exit-unconfirmed"
|
|
253
|
+
: transcript === "unavailable" ? "transcript-unavailable-or-unstable"
|
|
254
|
+
: candidate.attempt.submissionMode === "native_queue_handoff" || candidate.attempt.submissionMode === "steer"
|
|
255
|
+
? `queue-resume-policy-${candidate.attempt.queueResumePolicy ?? "unknown"}; transcript-marker-absent`
|
|
256
|
+
: "enter-may-have-started-without-transcript-marker";
|
|
257
|
+
}
|
|
258
|
+
if (outbox.reconcileAttempt(candidate.deliveryId, candidate.attempt.targetDaemonBootId, candidate.attempt.attemptNo, outcome, proof)) {
|
|
259
|
+
if (outcome === "retry_wait")
|
|
260
|
+
result.retry++;
|
|
261
|
+
else if (outcome === "delivered")
|
|
262
|
+
result.delivered++;
|
|
263
|
+
else
|
|
264
|
+
result.uncertain++;
|
|
265
|
+
}
|
|
266
|
+
logger?.[outcome === "uncertain" ? "warn" : "debug"]({ deliveryId: candidate.deliveryId, target: candidate.targetInstance, outcome, proof, submissionMode: candidate.attempt.submissionMode }, "Reconciled durable delivery after target generation ended");
|
|
267
|
+
}
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
/** Retire and positively verify every captured old window after a Daemon.stop. */
|
|
271
|
+
export async function retireCapturedTargetWindows(captured) {
|
|
272
|
+
const windowIds = [...new Set([
|
|
273
|
+
captured.savedWindowId,
|
|
274
|
+
...captured.attempts.map(item => item.paneWindowId),
|
|
275
|
+
].filter((id) => !!id))];
|
|
276
|
+
let gone = true;
|
|
277
|
+
for (const windowId of windowIds) {
|
|
278
|
+
const oldWindow = new TmuxManager(captured.sessionName, windowId);
|
|
279
|
+
const thisGone = await withTimeout(oldWindow.killWindowConfirmed(), RECONCILIATION_WINDOW_EXIT_TIMEOUT_MS, "old pane retirement").catch(() => false);
|
|
280
|
+
gone &&= thisGone;
|
|
281
|
+
}
|
|
282
|
+
return gone;
|
|
283
|
+
}
|
|
284
|
+
/** Startup path: capture first, retire the old Strategy-A window, verify exit, then read transcript. */
|
|
285
|
+
export async function reconcileTargetBeforeStart(outbox, targetInstance, instanceDir, logger) {
|
|
286
|
+
const captured = await capturePendingTargetReconciliation(outbox, targetInstance, instanceDir, getTmuxSession(), logger);
|
|
287
|
+
// Keep the historical Strategy-A best-effort cleanup for ordinary starts.
|
|
288
|
+
// A verified retirement barrier is required only when an in-flight durable
|
|
289
|
+
// submission needs pane/transcript reconciliation evidence.
|
|
290
|
+
if (captured.attempts.length === 0) {
|
|
291
|
+
return { delivered: 0, retry: 0, uncertain: 0, safeToStart: true };
|
|
292
|
+
}
|
|
293
|
+
const oldWindowGone = await retireCapturedTargetWindows(captured);
|
|
294
|
+
return finishTargetReconciliation(outbox, captured, oldWindowGone, logger);
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=delivery-reconciliation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delivery-reconciliation.js","sourceRoot":"","sources":["../src/delivery-reconciliation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|