@lore-co/cli 0.1.27 → 0.1.29
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 +59 -9
- package/dist/agents.d.ts +3 -1
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +31 -7
- package/dist/agents.js.map +1 -1
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +182 -71
- package/dist/cli.js.map +1 -1
- package/dist/command-help.d.ts +34 -0
- package/dist/command-help.d.ts.map +1 -0
- package/dist/command-help.js +227 -0
- package/dist/command-help.js.map +1 -0
- package/dist/demo.d.ts.map +1 -1
- package/dist/demo.js +15 -2
- package/dist/demo.js.map +1 -1
- package/dist/generated-assets.d.ts +9 -4
- package/dist/generated-assets.d.ts.map +1 -1
- package/dist/generated-assets.js +5 -4
- package/dist/generated-assets.js.map +1 -1
- package/dist/guard.d.ts.map +1 -1
- package/dist/guard.js +4 -3
- package/dist/guard.js.map +1 -1
- package/dist/recovery-cloud-workspace.d.ts +11 -0
- package/dist/recovery-cloud-workspace.d.ts.map +1 -0
- package/dist/recovery-cloud-workspace.js +113 -0
- package/dist/recovery-cloud-workspace.js.map +1 -0
- package/dist/recovery-cloud.d.ts +31 -0
- package/dist/recovery-cloud.d.ts.map +1 -0
- package/dist/recovery-cloud.js +242 -0
- package/dist/recovery-cloud.js.map +1 -0
- package/dist/recovery-codex.d.ts +5 -0
- package/dist/recovery-codex.d.ts.map +1 -0
- package/dist/recovery-codex.js +111 -0
- package/dist/recovery-codex.js.map +1 -0
- package/dist/recovery-copilot.d.ts +14 -0
- package/dist/recovery-copilot.d.ts.map +1 -0
- package/dist/recovery-copilot.js +120 -0
- package/dist/recovery-copilot.js.map +1 -0
- package/dist/recovery-desktop.d.ts +7 -0
- package/dist/recovery-desktop.d.ts.map +1 -0
- package/dist/recovery-desktop.js +179 -0
- package/dist/recovery-desktop.js.map +1 -0
- package/dist/recovery-external.d.ts +61 -0
- package/dist/recovery-external.d.ts.map +1 -0
- package/dist/recovery-external.js +98 -0
- package/dist/recovery-external.js.map +1 -0
- package/dist/recovery-hooks.d.ts +5 -0
- package/dist/recovery-hooks.d.ts.map +1 -0
- package/dist/recovery-hooks.js +115 -0
- package/dist/recovery-hooks.js.map +1 -0
- package/dist/recovery-hosts.d.ts +13 -0
- package/dist/recovery-hosts.d.ts.map +1 -0
- package/dist/recovery-hosts.js +263 -0
- package/dist/recovery-hosts.js.map +1 -0
- package/dist/recovery-polytoken.d.ts +14 -0
- package/dist/recovery-polytoken.d.ts.map +1 -0
- package/dist/recovery-polytoken.js +194 -0
- package/dist/recovery-polytoken.js.map +1 -0
- package/dist/recovery-remote.d.ts +8 -0
- package/dist/recovery-remote.d.ts.map +1 -0
- package/dist/recovery-remote.js +135 -0
- package/dist/recovery-remote.js.map +1 -0
- package/dist/recovery-state.d.ts +25 -1
- package/dist/recovery-state.d.ts.map +1 -1
- package/dist/recovery-state.js +69 -15
- package/dist/recovery-state.js.map +1 -1
- package/dist/recovery-t3.d.ts +17 -0
- package/dist/recovery-t3.d.ts.map +1 -0
- package/dist/recovery-t3.js +58 -0
- package/dist/recovery-t3.js.map +1 -0
- package/dist/recovery-transfer.d.ts +22 -0
- package/dist/recovery-transfer.d.ts.map +1 -0
- package/dist/recovery-transfer.js +228 -0
- package/dist/recovery-transfer.js.map +1 -0
- package/dist/recovery.d.ts +9 -1
- package/dist/recovery.d.ts.map +1 -1
- package/dist/recovery.js +187 -47
- package/dist/recovery.js.map +1 -1
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +1 -0
- package/dist/runtime.js.map +1 -1
- package/dist/self-host.d.ts +1 -1
- package/dist/self-host.js +2 -2
- package/dist/uninstall.d.ts +19 -0
- package/dist/uninstall.d.ts.map +1 -0
- package/dist/uninstall.js +128 -0
- package/dist/uninstall.js.map +1 -0
- package/dist/update.js +3 -3
- package/package.json +3 -3
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { markRecoveryFailure, RecoveryRunSchema, recoveryRunKey, recoveryStore } from "./recovery-state.js";
|
|
3
|
+
/** Only structured protocol errors qualify. An answer mentioning limits does not. */
|
|
4
|
+
export function codexFailureReason(turn, expectedTurn) {
|
|
5
|
+
if (!turn || typeof turn !== "object")
|
|
6
|
+
return;
|
|
7
|
+
const value = turn;
|
|
8
|
+
if (value.id !== expectedTurn || value.status !== "failed" || !value.error)
|
|
9
|
+
return;
|
|
10
|
+
const info = value.error.codexErrorInfo;
|
|
11
|
+
if (info === "usageLimitExceeded")
|
|
12
|
+
return "rate_limit";
|
|
13
|
+
if (info && typeof info === "object" && "httpConnectionFailed" in info &&
|
|
14
|
+
info.httpConnectionFailed?.httpStatusCode === 429)
|
|
15
|
+
return "rate_limit";
|
|
16
|
+
return "agent_error";
|
|
17
|
+
}
|
|
18
|
+
/** Read persisted turns without resuming, subscribing to, or steering the job. */
|
|
19
|
+
export function observeCodexRecovery(home, runId, command, env = process.env) {
|
|
20
|
+
let stopped = false, busy = false, initialized = false, sequence = 0;
|
|
21
|
+
let child;
|
|
22
|
+
let buffer = "";
|
|
23
|
+
const pending = new Map();
|
|
24
|
+
const stop = () => {
|
|
25
|
+
stopped = true;
|
|
26
|
+
clearInterval(timer);
|
|
27
|
+
for (const request of pending.values()) {
|
|
28
|
+
clearTimeout(request.timer);
|
|
29
|
+
request.reject(new Error("Codex recovery observer stopped"));
|
|
30
|
+
}
|
|
31
|
+
pending.clear();
|
|
32
|
+
child?.kill();
|
|
33
|
+
const process = child;
|
|
34
|
+
if (process) {
|
|
35
|
+
const force = setTimeout(() => process.kill("SIGKILL"), 1000);
|
|
36
|
+
force.unref();
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const request = (method, params) => new Promise((resolve, reject) => {
|
|
40
|
+
const id = ++sequence;
|
|
41
|
+
const timeout = setTimeout(() => { pending.delete(id); reject(new Error("Codex recovery read timed out")); }, 4000);
|
|
42
|
+
pending.set(id, { resolve, reject, timer: timeout });
|
|
43
|
+
child.stdin.write(JSON.stringify({ id, method, params }) + "\n");
|
|
44
|
+
});
|
|
45
|
+
const poll = async () => {
|
|
46
|
+
if (busy || stopped)
|
|
47
|
+
return;
|
|
48
|
+
busy = true;
|
|
49
|
+
try {
|
|
50
|
+
const parsed = RecoveryRunSchema.safeParse(await recoveryStore(home).readState(recoveryRunKey(runId)));
|
|
51
|
+
if (!parsed.success || !parsed.data.turnPending || parsed.data.failure || !parsed.data.sessionId || !parsed.data.nativeTurnId)
|
|
52
|
+
return;
|
|
53
|
+
const run = parsed.data;
|
|
54
|
+
if (!child) {
|
|
55
|
+
child = spawn(command, ["app-server"], { env, stdio: ["pipe", "pipe", "ignore"] });
|
|
56
|
+
child.once("error", stop);
|
|
57
|
+
child.once("exit", stop);
|
|
58
|
+
child.stdin.on("error", stop);
|
|
59
|
+
child.stdout.on("data", chunk => {
|
|
60
|
+
buffer += String(chunk);
|
|
61
|
+
if (Buffer.byteLength(buffer) > 4 * 1024 * 1024) {
|
|
62
|
+
stop();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
let newline;
|
|
66
|
+
while ((newline = buffer.indexOf("\n")) >= 0) {
|
|
67
|
+
const line = buffer.slice(0, newline);
|
|
68
|
+
buffer = buffer.slice(newline + 1);
|
|
69
|
+
try {
|
|
70
|
+
const message = JSON.parse(line), waiting = pending.get(message.id);
|
|
71
|
+
if (!waiting)
|
|
72
|
+
continue;
|
|
73
|
+
clearTimeout(waiting.timer);
|
|
74
|
+
pending.delete(message.id);
|
|
75
|
+
if (message.error)
|
|
76
|
+
waiting.reject(new Error("Codex recovery read unavailable"));
|
|
77
|
+
else
|
|
78
|
+
waiting.resolve(message.result);
|
|
79
|
+
}
|
|
80
|
+
catch { /* Non-protocol output cannot trigger a handoff. */ }
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
if (!initialized) {
|
|
85
|
+
await request("initialize", { clientInfo: { name: "lore-recovery-reader", version: "1" }, capabilities: { experimentalApi: true } });
|
|
86
|
+
child.stdin.write(JSON.stringify({ method: "initialized" }) + "\n");
|
|
87
|
+
initialized = true;
|
|
88
|
+
}
|
|
89
|
+
let turns;
|
|
90
|
+
try {
|
|
91
|
+
const result = await request("thread/turns/list", { threadId: run.sessionId, limit: 1, sortDirection: "desc", itemsView: "notLoaded" });
|
|
92
|
+
turns = result.data ?? [];
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Older app servers expose the stable thread/read method only.
|
|
96
|
+
const result = await request("thread/read", { threadId: run.sessionId, includeTurns: true });
|
|
97
|
+
turns = result.thread?.turns?.slice(-1) ?? [];
|
|
98
|
+
}
|
|
99
|
+
const reason = codexFailureReason(turns[0], run.nativeTurnId);
|
|
100
|
+
if (reason)
|
|
101
|
+
await markRecoveryFailure(home, run, reason);
|
|
102
|
+
}
|
|
103
|
+
catch { /* Process-exit recovery remains available on older hosts. */ }
|
|
104
|
+
finally {
|
|
105
|
+
busy = false;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const timer = setInterval(() => { void poll(); }, 1000);
|
|
109
|
+
return stop;
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=recovery-codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-codex.js","sourceRoot":"","sources":["../src/recovery-codex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type RecoveryRun } from "./recovery-state.js";
|
|
2
|
+
/** Copilot 1.0.83 emits recoverable hooks during retries, then session.error
|
|
3
|
+
* after assistant.turn_end. Only that terminal event can trigger recovery.
|
|
4
|
+
* Bind it to the exact prompt hook, not matching prompt text or a guessed turn.
|
|
5
|
+
*/
|
|
6
|
+
export declare function copilotJournalFailure(text: string, run: RecoveryRun): {
|
|
7
|
+
reason: "rate_limit" | "agent_error";
|
|
8
|
+
messages: {
|
|
9
|
+
role: "user" | "assistant";
|
|
10
|
+
text: string;
|
|
11
|
+
}[];
|
|
12
|
+
} | undefined;
|
|
13
|
+
export declare function observeCopilotRecovery(home: string, id: string, env?: NodeJS.ProcessEnv): () => void;
|
|
14
|
+
//# sourceMappingURL=recovery-copilot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-copilot.d.ts","sourceRoot":"","sources":["../src/recovery-copilot.ts"],"names":[],"mappings":"AAGA,OAAO,EAA8F,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEnJ;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW;;;;;;cAmCnE;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,oBAAc,GAAG,MAAM,IAAI,CAoC9F"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { open, realpath } from "node:fs/promises";
|
|
3
|
+
import { resolve } from "node:path";
|
|
4
|
+
import { RecoveryRunSchema, recoveryRunKey, recoveryStore, recoveryMessageText, markRecoveryFailure } from "./recovery-state.js";
|
|
5
|
+
/** Copilot 1.0.83 emits recoverable hooks during retries, then session.error
|
|
6
|
+
* after assistant.turn_end. Only that terminal event can trigger recovery.
|
|
7
|
+
* Bind it to the exact prompt hook, not matching prompt text or a guessed turn.
|
|
8
|
+
*/
|
|
9
|
+
export function copilotJournalFailure(text, run) {
|
|
10
|
+
if (!run.sessionId || !run.nativeTurnId?.startsWith("hook:"))
|
|
11
|
+
return;
|
|
12
|
+
const events = [];
|
|
13
|
+
for (const line of text.split("\n").slice(0, -1)) {
|
|
14
|
+
try {
|
|
15
|
+
const value = JSON.parse(line);
|
|
16
|
+
if (value && typeof value === "object")
|
|
17
|
+
events.push(value);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return;
|
|
21
|
+
} // Incomplete final records are excluded; malformed journals fail closed.
|
|
22
|
+
}
|
|
23
|
+
const start = events[0];
|
|
24
|
+
if (start?.type !== "session.start" || start.data?.sessionId !== run.sessionId || start.data?.context?.cwd !== run.cwd)
|
|
25
|
+
return;
|
|
26
|
+
let bound = false, user, ended = false, failure;
|
|
27
|
+
const messages = [];
|
|
28
|
+
for (const event of events) {
|
|
29
|
+
const data = event.data;
|
|
30
|
+
if (!data || data.parentToolCallId || data.parentAgentId)
|
|
31
|
+
continue;
|
|
32
|
+
if (event.type === "hook.start" && data.hookType === "userPromptSubmitted") {
|
|
33
|
+
bound = data.input?.sessionId === run.sessionId && `hook:${data.input?.timestamp}` === run.nativeTurnId;
|
|
34
|
+
user = undefined;
|
|
35
|
+
ended = false;
|
|
36
|
+
failure = undefined;
|
|
37
|
+
}
|
|
38
|
+
else if (event.type === "user.message") {
|
|
39
|
+
if (typeof data.content === "string")
|
|
40
|
+
messages.push({ role: "user", text: recoveryMessageText(data.content) });
|
|
41
|
+
if (user)
|
|
42
|
+
bound = false; // A queued/subsequent message is not the inspected turn.
|
|
43
|
+
user = data;
|
|
44
|
+
ended = false;
|
|
45
|
+
failure = undefined;
|
|
46
|
+
}
|
|
47
|
+
else if (event.type === "assistant.message" && typeof data.content === "string") {
|
|
48
|
+
messages.push({ role: "assistant", text: recoveryMessageText(data.content) });
|
|
49
|
+
}
|
|
50
|
+
else if (event.type === "assistant.turn_start") {
|
|
51
|
+
ended = false;
|
|
52
|
+
failure = undefined;
|
|
53
|
+
}
|
|
54
|
+
else if (event.type === "assistant.turn_end") {
|
|
55
|
+
ended = bound && typeof user?.turnId === "string" && !!user.turnId && data.turnId === user.turnId;
|
|
56
|
+
}
|
|
57
|
+
else if (["abort", "session.resume"].includes(event.type)) {
|
|
58
|
+
bound = false;
|
|
59
|
+
failure = undefined;
|
|
60
|
+
}
|
|
61
|
+
else if (event.type === "session.error" && bound && ended) {
|
|
62
|
+
if (data.errorType === "rate_limit" || data.statusCode === 429)
|
|
63
|
+
failure = "rate_limit";
|
|
64
|
+
else if (["authentication", "model_call", "system"].includes(data.errorType))
|
|
65
|
+
failure = "agent_error";
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return failure && bound ? { reason: failure, messages: messages.slice(-20) } : undefined;
|
|
69
|
+
}
|
|
70
|
+
export function observeCopilotRecovery(home, id, env = process.env) {
|
|
71
|
+
let stopped = false, busy = false, lastRead = "";
|
|
72
|
+
const poll = async () => {
|
|
73
|
+
if (stopped || busy)
|
|
74
|
+
return;
|
|
75
|
+
busy = true;
|
|
76
|
+
try {
|
|
77
|
+
const store = recoveryStore(home), run = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
|
|
78
|
+
if (!run.turnPending || run.failure || !run.sessionId || !/^[a-zA-Z0-9-]{1,100}$/.test(run.sessionId))
|
|
79
|
+
return;
|
|
80
|
+
const root = await realpath(resolve(env.COPILOT_HOME || resolve(env.HOME || home, ".copilot"), "session-state"));
|
|
81
|
+
const directory = resolve(root, run.sessionId);
|
|
82
|
+
if (await realpath(directory) !== directory)
|
|
83
|
+
return;
|
|
84
|
+
const file = await open(resolve(directory, "events.jsonl"), constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
85
|
+
let text;
|
|
86
|
+
try {
|
|
87
|
+
const stat = await file.stat();
|
|
88
|
+
if (!stat.isFile() || stat.size > 8 * 1024 * 1024 || (process.getuid && stat.uid !== process.getuid()))
|
|
89
|
+
return;
|
|
90
|
+
const signature = `${run.sessionId}:${run.turn}:${stat.ino}:${stat.size}:${stat.mtimeMs}`;
|
|
91
|
+
if (signature === lastRead)
|
|
92
|
+
return;
|
|
93
|
+
const buffer = Buffer.alloc(stat.size);
|
|
94
|
+
const { bytesRead } = await file.read(buffer, 0, buffer.length, 0);
|
|
95
|
+
text = buffer.subarray(0, bytesRead).toString("utf8");
|
|
96
|
+
lastRead = signature;
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
await file.close();
|
|
100
|
+
}
|
|
101
|
+
const result = copilotJournalFailure(text, run);
|
|
102
|
+
if (!result || stopped)
|
|
103
|
+
return;
|
|
104
|
+
await store.updateState(recoveryRunKey(id), current => {
|
|
105
|
+
const latest = RecoveryRunSchema.parse(current);
|
|
106
|
+
if (latest.turn === run.turn && latest.sessionId === run.sessionId && latest.nativeTurnId === run.nativeTurnId && result.messages.length)
|
|
107
|
+
latest.messages = result.messages;
|
|
108
|
+
return latest;
|
|
109
|
+
});
|
|
110
|
+
await markRecoveryFailure(home, run, result.reason);
|
|
111
|
+
}
|
|
112
|
+
catch { /* Unsupported/missing journals cannot trigger a guessed handoff. */ }
|
|
113
|
+
finally {
|
|
114
|
+
busy = false;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const timer = setInterval(() => { void poll(); }, 350);
|
|
118
|
+
return () => { stopped = true; clearInterval(timer); };
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=recovery-copilot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-copilot.js","sourceRoot":"","sources":["../src/recovery-copilot.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RecoverySource } from "./agents.js";
|
|
2
|
+
/** An IDE hook has no parent PTY. Start a terminal that owns the confirmation. */
|
|
3
|
+
export declare function openRecoveryTerminal(home: string, id: string): Promise<void>;
|
|
4
|
+
export declare function offerDesktopRecovery(home: string, id: string, notify?: typeof openRecoveryTerminal): Promise<void>;
|
|
5
|
+
export declare function captureDesktopRecovery(home: string, agent: RecoverySource, value: unknown): Promise<string | undefined>;
|
|
6
|
+
export declare function runDesktopRecovery(args: readonly string[], home: string): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=recovery-desktop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-desktop.d.ts","sourceRoot":"","sources":["../src/recovery-desktop.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,cAAc,EAA+B,MAAM,aAAa,CAAC;AAc/E,kFAAkF;AAClF,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBlF;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,8BAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAajH;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAqB7H;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA4C7F"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { constants } from "node:fs";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { mkdir, open, realpath, unlink } from "node:fs/promises";
|
|
5
|
+
import { resolve } from "node:path";
|
|
6
|
+
import { createInterface } from "node:readline/promises";
|
|
7
|
+
import { z } from "zod";
|
|
8
|
+
import { AGENTS, findAgentExecutable } from "./agents.js";
|
|
9
|
+
import { captureRecoveryHook, createRecoveryRun, recoveryRunKey, RecoveryRunSchema, recoveryStore, recordRecoveryMetric } from "./recovery-state.js";
|
|
10
|
+
import { cliInvocation, launchRecoveredRun, recoveryRoute } from "./recovery.js";
|
|
11
|
+
import { shellQuote } from "./recovery-transfer.js";
|
|
12
|
+
import { observeCodexRecovery } from "./recovery-codex.js";
|
|
13
|
+
import { observePolytokenRecovery } from "./recovery-polytoken.js";
|
|
14
|
+
import { observeCopilotRecovery } from "./recovery-copilot.js";
|
|
15
|
+
function detached(home, args) {
|
|
16
|
+
const invocation = cliInvocation();
|
|
17
|
+
const child = spawn(invocation[0], [...invocation.slice(1), "recovery", ...args], { detached: true, stdio: "ignore", env: { ...process.env, LORE_HOME: home, BUN_OPTIONS: undefined, BUN_BE_BUN: undefined } });
|
|
18
|
+
child.once("error", () => { });
|
|
19
|
+
child.unref();
|
|
20
|
+
}
|
|
21
|
+
/** An IDE hook has no parent PTY. Start a terminal that owns the confirmation. */
|
|
22
|
+
export async function openRecoveryTerminal(home, id) {
|
|
23
|
+
z.uuid().parse(id);
|
|
24
|
+
if (process.platform !== "darwin" && !process.env.DISPLAY && !process.env.WAYLAND_DISPLAY)
|
|
25
|
+
throw new Error("Desktop recovery needs a graphical session; use the connected shell wrapper on a headless worker");
|
|
26
|
+
const folder = resolve(home, ".lore/recovery/offers");
|
|
27
|
+
await mkdir(folder, { recursive: true, mode: 0o700 });
|
|
28
|
+
const path = resolve(folder, `${id}.command`);
|
|
29
|
+
const file = await open(path, constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | constants.O_NOFOLLOW, 0o700);
|
|
30
|
+
try {
|
|
31
|
+
await file.writeFile(`#!/bin/sh\nexec env -u BUN_OPTIONS -u BUN_BE_BUN PATH=${shellQuote(process.env.PATH || "/usr/bin:/bin")} LORE_HOME=${shellQuote(home)} ${[...cliInvocation(), "recovery", "offer", id].map(shellQuote).join(" ")}\n`);
|
|
32
|
+
}
|
|
33
|
+
finally {
|
|
34
|
+
await file.close();
|
|
35
|
+
}
|
|
36
|
+
const command = process.platform === "darwin" ? "open" : "x-terminal-emulator";
|
|
37
|
+
const args = process.platform === "darwin" ? ["-a", "Terminal", path] : ["-e", "/bin/sh", path];
|
|
38
|
+
await new Promise((done, reject) => {
|
|
39
|
+
const child = spawn(command, args, { detached: true, stdio: "ignore" });
|
|
40
|
+
child.once("error", reject);
|
|
41
|
+
if (process.platform === "darwin")
|
|
42
|
+
child.once("exit", code => code === 0 ? done() : reject(new Error("Could not open the recovery terminal")));
|
|
43
|
+
else {
|
|
44
|
+
const timer = setTimeout(() => { child.unref(); done(); }, 500);
|
|
45
|
+
child.once("exit", code => { clearTimeout(timer); if (code === 0)
|
|
46
|
+
done();
|
|
47
|
+
else
|
|
48
|
+
reject(new Error("Could not open the recovery terminal")); });
|
|
49
|
+
child.once("error", () => clearTimeout(timer));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
export async function offerDesktopRecovery(home, id, notify = openRecoveryTerminal) {
|
|
54
|
+
const store = recoveryStore(home);
|
|
55
|
+
const run = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
|
|
56
|
+
if (await store.readState("disabled"))
|
|
57
|
+
throw new Error("Recovery is disabled");
|
|
58
|
+
if (!run.failure)
|
|
59
|
+
return;
|
|
60
|
+
let claim = false;
|
|
61
|
+
await store.updateState(`desktop-offer-${id}`, current => {
|
|
62
|
+
if (current && typeof current === "object" && "attempt" in current && current.attempt === run.failure.id)
|
|
63
|
+
return current;
|
|
64
|
+
claim = true;
|
|
65
|
+
return { attempt: run.failure.id };
|
|
66
|
+
});
|
|
67
|
+
if (!claim)
|
|
68
|
+
return;
|
|
69
|
+
try {
|
|
70
|
+
await notify(home, id);
|
|
71
|
+
}
|
|
72
|
+
catch (error) {
|
|
73
|
+
await store.deleteState(`desktop-offer-${id}`);
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export async function captureDesktopRecovery(home, agent, value) {
|
|
78
|
+
const input = z.object({ session_id: z.string().min(1).max(500), cwd: z.string(), hook_event_name: z.string() }).passthrough().safeParse(value);
|
|
79
|
+
if (!input.success)
|
|
80
|
+
return;
|
|
81
|
+
const route = await recoveryRoute(home, agent);
|
|
82
|
+
if (!route || route.agent === agent)
|
|
83
|
+
return;
|
|
84
|
+
const cwd = await realpath(input.data.cwd);
|
|
85
|
+
const key = `desktop-session-${createHash("sha256").update(JSON.stringify([agent, cwd, input.data.session_id])).digest("hex")}`;
|
|
86
|
+
const store = recoveryStore(home);
|
|
87
|
+
let saved = z.object({ id: z.uuid(), at: z.number() }).safeParse(await store.readState(key));
|
|
88
|
+
if (!saved.success || Date.now() - saved.data.at > 24 * 60 * 60 * 1000) {
|
|
89
|
+
if (input.data.hook_event_name !== "UserPromptSubmit")
|
|
90
|
+
return;
|
|
91
|
+
const run = await createRecoveryRun(home, cwd, agent, route.agent, route.remote);
|
|
92
|
+
const mapping = { id: run.id, at: Date.now() };
|
|
93
|
+
await store.writeState(key, mapping);
|
|
94
|
+
saved = { success: true, data: mapping };
|
|
95
|
+
}
|
|
96
|
+
const id = saved.data.id;
|
|
97
|
+
await captureRecoveryHook(home, id, input.data, agent);
|
|
98
|
+
const run = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
|
|
99
|
+
if (agent === "codex" && input.data.hook_event_name === "UserPromptSubmit")
|
|
100
|
+
detached(home, ["watch", id, String(run.turn)]);
|
|
101
|
+
if (agent === "polytoken" && input.data.hook_event_name === "UserPromptSubmit")
|
|
102
|
+
detached(home, ["watch-polytoken", id, String(run.turn)]);
|
|
103
|
+
if (agent === "copilot-cli" && input.data.hook_event_name === "UserPromptSubmit")
|
|
104
|
+
detached(home, ["watch-copilot", id, String(run.turn)]);
|
|
105
|
+
if (run.failure)
|
|
106
|
+
await offerDesktopRecovery(home, id);
|
|
107
|
+
return id;
|
|
108
|
+
}
|
|
109
|
+
export async function runDesktopRecovery(args, home) {
|
|
110
|
+
const id = z.uuid().parse(args[1]);
|
|
111
|
+
const store = recoveryStore(home);
|
|
112
|
+
if (args[0] === "watch" || args[0] === "watch-polytoken" || args[0] === "watch-copilot") {
|
|
113
|
+
const turn = z.coerce.number().int().nonnegative().parse(args[2]);
|
|
114
|
+
const stop = args[0] === "watch-polytoken" ? observePolytokenRecovery(home, id) : args[0] === "watch-copilot" ? observeCopilotRecovery(home, id) : observeCodexRecovery(home, id, await findAgentExecutable("codex"));
|
|
115
|
+
try {
|
|
116
|
+
const deadline = Date.now() + 24 * 60 * 60 * 1000;
|
|
117
|
+
while (Date.now() < deadline) {
|
|
118
|
+
const run = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
|
|
119
|
+
if (run.turn !== turn || !run.turnPending)
|
|
120
|
+
break;
|
|
121
|
+
if (run.failure) {
|
|
122
|
+
await offerDesktopRecovery(home, id);
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
await new Promise(done => setTimeout(done, 1000));
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
stop();
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const run = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
|
|
134
|
+
if (!run.failure || Date.now() - Date.parse(run.updatedAt) > 24 * 60 * 60 * 1000)
|
|
135
|
+
throw new Error("This recovery offer expired");
|
|
136
|
+
if (await store.readState("disabled"))
|
|
137
|
+
throw new Error("Recovery is disabled");
|
|
138
|
+
if (!process.stdin.isTTY || !process.stdout.isTTY)
|
|
139
|
+
throw new Error("Recovery confirmation requires an interactive terminal");
|
|
140
|
+
await store.writeState(`attempt-${id}`, run);
|
|
141
|
+
await recordRecoveryMetric(home, id, run.failure.id, "offered");
|
|
142
|
+
const fromEditor = args[0] === "launch-accepted";
|
|
143
|
+
if (fromEditor && (run.sourceHost !== "copilot-vscode" || args[2] !== run.failure.id))
|
|
144
|
+
throw new Error("The editor offer is no longer current");
|
|
145
|
+
const prompt = fromEditor ? undefined : createInterface({ input: process.stdin, output: process.stdout });
|
|
146
|
+
let answer;
|
|
147
|
+
try {
|
|
148
|
+
answer = prompt ? await prompt.question(`${run.sourceHost ?? AGENTS[run.sourceAgent].label} stopped${run.failure.reason === "rate_limit" ? " at a usage limit" : " with an error"}.\nContinue with ${AGENTS[run.targetAgent].label}${run.targetRemote ? ` on ${run.targetRemote.host}` : " locally"}? [Y/n] `) : "yes";
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
prompt?.close();
|
|
152
|
+
await unlink(resolve(home, ".lore/recovery/offers", `${id}.command`)).catch(() => { });
|
|
153
|
+
}
|
|
154
|
+
if (!["", "y", "yes"].includes(answer.trim().toLowerCase())) {
|
|
155
|
+
await recordRecoveryMetric(home, id, run.failure.id, "declined");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const current = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
|
|
159
|
+
if (await store.readState("disabled"))
|
|
160
|
+
throw new Error("Recovery was disabled while the offer was open");
|
|
161
|
+
if (current.failure?.id !== run.failure.id)
|
|
162
|
+
throw new Error("The source has moved on; this offer is no longer current");
|
|
163
|
+
if (current.sourceHost && Date.now() - Date.parse(current.updatedAt) > 10000)
|
|
164
|
+
throw new Error("The host observer is unavailable. Reconnect the host before accepting this handoff.");
|
|
165
|
+
if (current.sourceHost)
|
|
166
|
+
await (await import("./recovery-hosts.js")).validateExternalRecovery(home, current);
|
|
167
|
+
let accepted = false;
|
|
168
|
+
await store.updateState(`desktop-accepted-${id}`, prior => {
|
|
169
|
+
if (prior && typeof prior === "object" && "attempt" in prior && prior.attempt === run.failure.id)
|
|
170
|
+
return prior;
|
|
171
|
+
accepted = true;
|
|
172
|
+
return { attempt: run.failure.id };
|
|
173
|
+
});
|
|
174
|
+
if (!accepted)
|
|
175
|
+
throw new Error("This handoff was already accepted");
|
|
176
|
+
await recordRecoveryMetric(home, id, run.failure.id, "accepted");
|
|
177
|
+
await launchRecoveredRun(home, current);
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=recovery-desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-desktop.js","sourceRoot":"","sources":["../src/recovery-desktop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAuB,MAAM,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACrJ,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,SAAS,QAAQ,CAAC,IAAY,EAAE,IAAc;IAC5C,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAE,EAAE,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;IACjN,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAAC,KAAK,CAAC,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY,EAAE,EAAU;IACjE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnB,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,kGAAkG,CAAC,CAAC;IAC/M,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;IAAC,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7G,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;IAC9C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,OAAO,GAAG,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IACxH,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,SAAS,CAAC,yDAAyD,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,eAAe,CAAC,cAAc,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,aAAa,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9O,CAAC;YAAS,CAAC;QAAC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IAAC,CAAC;IACjC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC;IAC/E,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAChG,MAAM,IAAI,OAAO,CAAO,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QACvC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC5B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC,CAAC;aAC1I,CAAC;YACJ,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAChE,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,KAAK,CAAC;gBAAE,IAAI,EAAE,CAAC;;gBAAM,MAAM,CAAC,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7I,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC;QACjD,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAAY,EAAE,EAAU,EAAE,MAAM,GAAG,oBAAoB;IAChG,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,IAAI,MAAM,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC/E,IAAI,CAAC,GAAG,CAAC,OAAO;QAAE,OAAO;IACzB,IAAI,KAAK,GAAG,KAAK,CAAC;IAClB,MAAM,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE;QACvD,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,SAAS,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,KAAK,GAAG,CAAC,OAAQ,CAAC,EAAE;YAAE,OAAO,OAAO,CAAC;QAC1H,KAAK,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAQ,CAAC,EAAE,EAAE,CAAC;IACpD,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,KAAK;QAAE,OAAO;IACnB,IAAI,CAAC;QAAC,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAAC,CAAC;IAC/B,OAAO,KAAK,EAAE,CAAC;QAAC,MAAM,KAAK,CAAC,WAAW,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,IAAY,EAAE,KAAqB,EAAE,KAAc;IAC9F,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAChJ,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO;IAC3B,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAAC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK;QAAE,OAAO;IAC5F,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,mBAAmB,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAChI,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7F,IAAI,CAAC,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,CAAC;QACvE,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,kBAAkB;YAAE,OAAO;QAC9D,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACjF,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QAAC,MAAM,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAAC,KAAK,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACjI,CAAC;IACD,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;IACzB,MAAM,mBAAmB,CAAC,IAAI,EAAE,EAAE,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,kBAAkB;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC5H,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,kBAAkB;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1I,IAAI,KAAK,KAAK,aAAa,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,kBAAkB;QAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC1I,IAAI,GAAG,CAAC,OAAO;QAAE,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACtD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAuB,EAAE,IAAY;IAC5E,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAClC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,iBAAiB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,eAAe,EAAE,CAAC;QACxF,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;QAClE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,iBAAiB,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,eAAe,CAAC,CAAC,CAAC,sBAAsB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QACtN,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;YAClD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;gBAC7B,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBAC/E,IAAI,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW;oBAAE,MAAM;gBACjD,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;oBAAC,MAAM;gBAAC,CAAC;gBACjE,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;gBAAS,CAAC;YAAC,IAAI,EAAE,CAAC;QAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,GAAG,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjI,IAAI,MAAM,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC/E,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,wDAAwD,CAAC,CAAC;IAC7H,MAAM,KAAK,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,EAAE,GAAG,CAAC,CAAC;IAC7C,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,CAAC,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,iBAAiB,CAAC;IACjD,IAAI,UAAU,IAAI,CAAC,GAAG,CAAC,UAAU,KAAK,gBAAgB,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;IAChJ,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1G,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,GAAG,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,WAAW,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,YAAY,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,gBAAgB,oBAAoB,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,UAAU,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACzT,CAAC;YAAS,CAAC;QAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,uBAAuB,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAAC,CAAC;IACrH,IAAI,CAAC,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;QAAC,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAC1I,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnF,IAAI,MAAM,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACzG,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,KAAK,GAAG,CAAC,OAAO,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IACxH,IAAI,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,qFAAqF,CAAC,CAAC;IACrL,IAAI,OAAO,CAAC,UAAU;QAAE,MAAM,CAAC,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC,CAAC,wBAAwB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5G,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,KAAK,CAAC,WAAW,CAAC,oBAAoB,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE;QACxD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,SAAS,IAAI,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,GAAG,CAAC,OAAQ,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAChH,QAAQ,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAQ,CAAC,EAAE,EAAE,CAAC;IACvD,CAAC,CAAC,CAAC;IACH,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;IACpE,MAAM,oBAAoB,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,CAAC,CAAC;IACjE,MAAM,kBAAkB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const ExternalCheckpoint: z.ZodObject<{
|
|
3
|
+
host: z.ZodEnum<{
|
|
4
|
+
t3code: "t3code";
|
|
5
|
+
cowork: "cowork";
|
|
6
|
+
"copilot-vscode": "copilot-vscode";
|
|
7
|
+
}>;
|
|
8
|
+
sourceAgent: z.ZodEnum<{
|
|
9
|
+
claude: "claude";
|
|
10
|
+
codex: "codex";
|
|
11
|
+
opencode: "opencode";
|
|
12
|
+
devin: "devin";
|
|
13
|
+
cursor: "cursor";
|
|
14
|
+
"copilot-cli": "copilot-cli";
|
|
15
|
+
polytoken: "polytoken";
|
|
16
|
+
}>;
|
|
17
|
+
sessionId: z.ZodString;
|
|
18
|
+
turnId: z.ZodString;
|
|
19
|
+
cwd: z.ZodString;
|
|
20
|
+
goal: z.ZodString;
|
|
21
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
22
|
+
role: z.ZodEnum<{
|
|
23
|
+
user: "user";
|
|
24
|
+
assistant: "assistant";
|
|
25
|
+
}>;
|
|
26
|
+
text: z.ZodString;
|
|
27
|
+
}, z.core.$strip>>;
|
|
28
|
+
state: z.ZodEnum<{
|
|
29
|
+
failed: "failed";
|
|
30
|
+
running: "running";
|
|
31
|
+
completed: "completed";
|
|
32
|
+
cancelled: "cancelled";
|
|
33
|
+
}>;
|
|
34
|
+
reason: z.ZodOptional<z.ZodEnum<{
|
|
35
|
+
rate_limit: "rate_limit";
|
|
36
|
+
agent_error: "agent_error";
|
|
37
|
+
}>>;
|
|
38
|
+
observedAt: z.ZodNumber;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export type ExternalCheckpoint = z.infer<typeof ExternalCheckpoint>;
|
|
41
|
+
export declare const ExternalSettings: z.ZodObject<{
|
|
42
|
+
fallback: z.ZodEnum<{
|
|
43
|
+
claude: "claude";
|
|
44
|
+
codex: "codex";
|
|
45
|
+
opencode: "opencode";
|
|
46
|
+
devin: "devin";
|
|
47
|
+
cursor: "cursor";
|
|
48
|
+
"copilot-cli": "copilot-cli";
|
|
49
|
+
polytoken: "polytoken";
|
|
50
|
+
}>;
|
|
51
|
+
t3Database: z.ZodOptional<z.ZodString>;
|
|
52
|
+
coworkRoots: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
53
|
+
vscodeRoots: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
54
|
+
vscodeExtension: z.ZodOptional<z.ZodString>;
|
|
55
|
+
vscodeHookFiles: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
56
|
+
since: z.ZodNumber;
|
|
57
|
+
}, z.core.$strip>;
|
|
58
|
+
export declare function externalSessionKey(input: Pick<ExternalCheckpoint, "host" | "sessionId" | "cwd">): string;
|
|
59
|
+
/** Accept only host adapters' structured state. Text never determines failure. */
|
|
60
|
+
export declare function captureExternalRecovery(home: string, value: unknown, notify?: (home: string, id: string) => Promise<void>): Promise<string | undefined>;
|
|
61
|
+
//# sourceMappingURL=recovery-external.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recovery-external.d.ts","sourceRoot":"","sources":["../src/recovery-external.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAMxB,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAS7B,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AACpE,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;iBAQ3B,CAAC;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,IAAI,CAAC,kBAAkB,EAAE,MAAM,GAAG,WAAW,GAAG,KAAK,CAAC,GAAG,MAAM,CAExG;AAGD,kFAAkF;AAClF,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkD7J"}
|