@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.
Files changed (91) hide show
  1. package/README.md +59 -9
  2. package/dist/agents.d.ts +3 -1
  3. package/dist/agents.d.ts.map +1 -1
  4. package/dist/agents.js +31 -7
  5. package/dist/agents.js.map +1 -1
  6. package/dist/cli.d.ts +8 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +182 -71
  9. package/dist/cli.js.map +1 -1
  10. package/dist/command-help.d.ts +34 -0
  11. package/dist/command-help.d.ts.map +1 -0
  12. package/dist/command-help.js +227 -0
  13. package/dist/command-help.js.map +1 -0
  14. package/dist/demo.d.ts.map +1 -1
  15. package/dist/demo.js +15 -2
  16. package/dist/demo.js.map +1 -1
  17. package/dist/generated-assets.d.ts +9 -4
  18. package/dist/generated-assets.d.ts.map +1 -1
  19. package/dist/generated-assets.js +5 -4
  20. package/dist/generated-assets.js.map +1 -1
  21. package/dist/guard.d.ts.map +1 -1
  22. package/dist/guard.js +4 -3
  23. package/dist/guard.js.map +1 -1
  24. package/dist/recovery-cloud-workspace.d.ts +11 -0
  25. package/dist/recovery-cloud-workspace.d.ts.map +1 -0
  26. package/dist/recovery-cloud-workspace.js +113 -0
  27. package/dist/recovery-cloud-workspace.js.map +1 -0
  28. package/dist/recovery-cloud.d.ts +31 -0
  29. package/dist/recovery-cloud.d.ts.map +1 -0
  30. package/dist/recovery-cloud.js +242 -0
  31. package/dist/recovery-cloud.js.map +1 -0
  32. package/dist/recovery-codex.d.ts +5 -0
  33. package/dist/recovery-codex.d.ts.map +1 -0
  34. package/dist/recovery-codex.js +111 -0
  35. package/dist/recovery-codex.js.map +1 -0
  36. package/dist/recovery-copilot.d.ts +14 -0
  37. package/dist/recovery-copilot.d.ts.map +1 -0
  38. package/dist/recovery-copilot.js +120 -0
  39. package/dist/recovery-copilot.js.map +1 -0
  40. package/dist/recovery-desktop.d.ts +7 -0
  41. package/dist/recovery-desktop.d.ts.map +1 -0
  42. package/dist/recovery-desktop.js +179 -0
  43. package/dist/recovery-desktop.js.map +1 -0
  44. package/dist/recovery-external.d.ts +61 -0
  45. package/dist/recovery-external.d.ts.map +1 -0
  46. package/dist/recovery-external.js +98 -0
  47. package/dist/recovery-external.js.map +1 -0
  48. package/dist/recovery-hooks.d.ts +5 -0
  49. package/dist/recovery-hooks.d.ts.map +1 -0
  50. package/dist/recovery-hooks.js +115 -0
  51. package/dist/recovery-hooks.js.map +1 -0
  52. package/dist/recovery-hosts.d.ts +13 -0
  53. package/dist/recovery-hosts.d.ts.map +1 -0
  54. package/dist/recovery-hosts.js +263 -0
  55. package/dist/recovery-hosts.js.map +1 -0
  56. package/dist/recovery-polytoken.d.ts +14 -0
  57. package/dist/recovery-polytoken.d.ts.map +1 -0
  58. package/dist/recovery-polytoken.js +194 -0
  59. package/dist/recovery-polytoken.js.map +1 -0
  60. package/dist/recovery-remote.d.ts +8 -0
  61. package/dist/recovery-remote.d.ts.map +1 -0
  62. package/dist/recovery-remote.js +135 -0
  63. package/dist/recovery-remote.js.map +1 -0
  64. package/dist/recovery-state.d.ts +25 -1
  65. package/dist/recovery-state.d.ts.map +1 -1
  66. package/dist/recovery-state.js +69 -15
  67. package/dist/recovery-state.js.map +1 -1
  68. package/dist/recovery-t3.d.ts +17 -0
  69. package/dist/recovery-t3.d.ts.map +1 -0
  70. package/dist/recovery-t3.js +58 -0
  71. package/dist/recovery-t3.js.map +1 -0
  72. package/dist/recovery-transfer.d.ts +22 -0
  73. package/dist/recovery-transfer.d.ts.map +1 -0
  74. package/dist/recovery-transfer.js +228 -0
  75. package/dist/recovery-transfer.js.map +1 -0
  76. package/dist/recovery.d.ts +9 -1
  77. package/dist/recovery.d.ts.map +1 -1
  78. package/dist/recovery.js +187 -47
  79. package/dist/recovery.js.map +1 -1
  80. package/dist/runtime.d.ts +1 -0
  81. package/dist/runtime.d.ts.map +1 -1
  82. package/dist/runtime.js +1 -0
  83. package/dist/runtime.js.map +1 -1
  84. package/dist/self-host.d.ts +1 -1
  85. package/dist/self-host.js +2 -2
  86. package/dist/uninstall.d.ts +19 -0
  87. package/dist/uninstall.d.ts.map +1 -0
  88. package/dist/uninstall.js +128 -0
  89. package/dist/uninstall.js.map +1 -0
  90. package/dist/update.js +3 -3
  91. 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":"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"}
@@ -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"}