@lore-co/cli 0.1.28 → 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 (81) hide show
  1. package/README.md +44 -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 +97 -15
  9. package/dist/cli.js.map +1 -1
  10. package/dist/command-help.d.ts +2 -1
  11. package/dist/command-help.d.ts.map +1 -1
  12. package/dist/command-help.js +33 -6
  13. package/dist/command-help.js.map +1 -1
  14. package/dist/generated-assets.d.ts +9 -4
  15. package/dist/generated-assets.d.ts.map +1 -1
  16. package/dist/generated-assets.js +5 -4
  17. package/dist/generated-assets.js.map +1 -1
  18. package/dist/recovery-cloud-workspace.d.ts +11 -0
  19. package/dist/recovery-cloud-workspace.d.ts.map +1 -0
  20. package/dist/recovery-cloud-workspace.js +113 -0
  21. package/dist/recovery-cloud-workspace.js.map +1 -0
  22. package/dist/recovery-cloud.d.ts +31 -0
  23. package/dist/recovery-cloud.d.ts.map +1 -0
  24. package/dist/recovery-cloud.js +242 -0
  25. package/dist/recovery-cloud.js.map +1 -0
  26. package/dist/recovery-codex.d.ts +5 -0
  27. package/dist/recovery-codex.d.ts.map +1 -0
  28. package/dist/recovery-codex.js +111 -0
  29. package/dist/recovery-codex.js.map +1 -0
  30. package/dist/recovery-copilot.d.ts +14 -0
  31. package/dist/recovery-copilot.d.ts.map +1 -0
  32. package/dist/recovery-copilot.js +120 -0
  33. package/dist/recovery-copilot.js.map +1 -0
  34. package/dist/recovery-desktop.d.ts +7 -0
  35. package/dist/recovery-desktop.d.ts.map +1 -0
  36. package/dist/recovery-desktop.js +179 -0
  37. package/dist/recovery-desktop.js.map +1 -0
  38. package/dist/recovery-external.d.ts +61 -0
  39. package/dist/recovery-external.d.ts.map +1 -0
  40. package/dist/recovery-external.js +98 -0
  41. package/dist/recovery-external.js.map +1 -0
  42. package/dist/recovery-hooks.d.ts +5 -0
  43. package/dist/recovery-hooks.d.ts.map +1 -0
  44. package/dist/recovery-hooks.js +115 -0
  45. package/dist/recovery-hooks.js.map +1 -0
  46. package/dist/recovery-hosts.d.ts +13 -0
  47. package/dist/recovery-hosts.d.ts.map +1 -0
  48. package/dist/recovery-hosts.js +263 -0
  49. package/dist/recovery-hosts.js.map +1 -0
  50. package/dist/recovery-polytoken.d.ts +14 -0
  51. package/dist/recovery-polytoken.d.ts.map +1 -0
  52. package/dist/recovery-polytoken.js +194 -0
  53. package/dist/recovery-polytoken.js.map +1 -0
  54. package/dist/recovery-remote.d.ts +8 -0
  55. package/dist/recovery-remote.d.ts.map +1 -0
  56. package/dist/recovery-remote.js +135 -0
  57. package/dist/recovery-remote.js.map +1 -0
  58. package/dist/recovery-state.d.ts +25 -1
  59. package/dist/recovery-state.d.ts.map +1 -1
  60. package/dist/recovery-state.js +69 -15
  61. package/dist/recovery-state.js.map +1 -1
  62. package/dist/recovery-t3.d.ts +17 -0
  63. package/dist/recovery-t3.d.ts.map +1 -0
  64. package/dist/recovery-t3.js +58 -0
  65. package/dist/recovery-t3.js.map +1 -0
  66. package/dist/recovery-transfer.d.ts +22 -0
  67. package/dist/recovery-transfer.d.ts.map +1 -0
  68. package/dist/recovery-transfer.js +228 -0
  69. package/dist/recovery-transfer.js.map +1 -0
  70. package/dist/recovery.d.ts +9 -1
  71. package/dist/recovery.d.ts.map +1 -1
  72. package/dist/recovery.js +187 -47
  73. package/dist/recovery.js.map +1 -1
  74. package/dist/self-host.d.ts +1 -1
  75. package/dist/self-host.js +2 -2
  76. package/dist/uninstall.d.ts +19 -0
  77. package/dist/uninstall.d.ts.map +1 -0
  78. package/dist/uninstall.js +128 -0
  79. package/dist/uninstall.js.map +1 -0
  80. package/dist/update.js +3 -3
  81. package/package.json +3 -3
@@ -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"}
@@ -0,0 +1,98 @@
1
+ import { createHash } from "node:crypto";
2
+ import { realpath } from "node:fs/promises";
3
+ import { z } from "zod";
4
+ import { LAUNCHABLE_AGENTS, RECOVERY_SOURCES, findAgentExecutable } from "./agents.js";
5
+ import { createRecoveryRun, markRecoveryFailure, RecoveryRunSchema, recoveryRunKey, recoveryStore, recoveryMessageText } from "./recovery-state.js";
6
+ import { recoveryRoute } from "./recovery.js";
7
+ import { offerDesktopRecovery } from "./recovery-desktop.js";
8
+ export const ExternalCheckpoint = z.object({
9
+ host: z.enum(["t3code", "copilot-vscode", "cowork"]),
10
+ sourceAgent: z.enum(RECOVERY_SOURCES),
11
+ sessionId: z.string().min(1).max(500), turnId: z.string().min(1).max(500),
12
+ cwd: z.string().min(1), goal: z.string().min(1).max(24000),
13
+ messages: z.array(z.object({ role: z.enum(["user", "assistant"]), text: z.string().max(24000) })).max(20),
14
+ state: z.enum(["running", "completed", "failed", "cancelled"]),
15
+ reason: z.enum(["rate_limit", "agent_error"]).optional(),
16
+ observedAt: z.number(),
17
+ });
18
+ export const ExternalSettings = z.object({
19
+ fallback: z.enum(LAUNCHABLE_AGENTS),
20
+ t3Database: z.string().optional(),
21
+ coworkRoots: z.array(z.string()).default([]),
22
+ vscodeRoots: z.array(z.string()).default([]),
23
+ vscodeExtension: z.string().optional(),
24
+ vscodeHookFiles: z.array(z.string()).default([]),
25
+ since: z.number(),
26
+ });
27
+ export function externalSessionKey(input) {
28
+ return `external-${createHash("sha256").update(JSON.stringify([input.host, input.sessionId, input.cwd])).digest("hex")}`;
29
+ }
30
+ const safeText = recoveryMessageText;
31
+ /** Accept only host adapters' structured state. Text never determines failure. */
32
+ export async function captureExternalRecovery(home, value, notify) {
33
+ const parsed = ExternalCheckpoint.safeParse(value);
34
+ if (!parsed.success || Date.now() - parsed.data.observedAt > 30000 || parsed.data.observedAt > Date.now() + 5000)
35
+ return;
36
+ const store = recoveryStore(home);
37
+ if (await store.readState("disabled"))
38
+ return;
39
+ const settings = ExternalSettings.safeParse(await store.readState("external-settings"));
40
+ if (!settings.success)
41
+ return;
42
+ const input = parsed.data;
43
+ input.cwd = await realpath(input.cwd);
44
+ if (input.host === "cowork" && !settings.data.coworkRoots.includes(input.cwd))
45
+ return;
46
+ if (input.host === "copilot-vscode" && !settings.data.vscodeRoots.includes(input.cwd))
47
+ return;
48
+ const key = externalSessionKey(input);
49
+ const mapping = z.object({ id: z.uuid() }).safeParse(await store.readState(key));
50
+ let run = mapping.success ? RecoveryRunSchema.safeParse(await store.readState(recoveryRunKey(mapping.data.id))) : undefined;
51
+ if (run?.success && run.data.sourceAgent !== input.sourceAgent) {
52
+ await store.updateState(recoveryRunKey(run.data.id), current => ({ ...RecoveryRunSchema.parse(current), failure: null, turnPending: false }));
53
+ run = undefined;
54
+ }
55
+ if (!run?.success || Date.now() - Date.parse(run.data.startedAt) > 24 * 60 * 60 * 1000) {
56
+ // A resumed observer must not produce a handoff for an old completed chat.
57
+ if (input.state === "completed" || input.state === "cancelled")
58
+ return;
59
+ const route = await recoveryRoute(home, input.sourceAgent);
60
+ const fallback = route?.agent ?? settings.data.fallback;
61
+ if (fallback === input.sourceAgent)
62
+ return;
63
+ if (!route?.remote)
64
+ await findAgentExecutable(fallback);
65
+ const created = await createRecoveryRun(home, input.cwd, input.sourceAgent, fallback, route?.remote);
66
+ await store.writeState(key, { id: created.id });
67
+ run = { success: true, data: created };
68
+ }
69
+ const id = run.data.id;
70
+ await store.updateState(recoveryRunKey(id), current => {
71
+ const latest = RecoveryRunSchema.parse(current);
72
+ if (latest.sourceAgent !== input.sourceAgent)
73
+ return latest;
74
+ if (latest.supersededTurnId === input.turnId)
75
+ return latest;
76
+ if (latest.nativeTurnId !== input.turnId) {
77
+ latest.turn += 1;
78
+ latest.failure = null;
79
+ delete latest.supersededTurnId;
80
+ }
81
+ latest.sessionId = input.sessionId;
82
+ latest.nativeTurnId = input.turnId;
83
+ latest.goal = safeText(input.goal);
84
+ latest.messages = input.messages.map(m => ({ ...m, text: safeText(m.text) }));
85
+ latest.turnPending = input.state === "running" || input.state === "failed";
86
+ if (input.state !== "failed")
87
+ latest.failure = null;
88
+ latest.updatedAt = new Date().toISOString();
89
+ latest.sourceHost = input.host;
90
+ return latest;
91
+ });
92
+ if (input.state === "failed") {
93
+ await markRecoveryFailure(home, RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id))), input.reason ?? "agent_error");
94
+ await offerDesktopRecovery(home, id, notify);
95
+ }
96
+ return id;
97
+ }
98
+ //# sourceMappingURL=recovery-external.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-external.js","sourceRoot":"","sources":["../src/recovery-external.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { RecoverySource } from "./agents.js";
2
+ /** Native event fields, never text scraped from the agent's answer or terminal. */
3
+ export declare function normalizeRecoveryHook(agent: RecoverySource, value: unknown, env?: NodeJS.ProcessEnv): unknown;
4
+ export declare function mergeNativeRecoveryHooks(agent: "cursor" | "copilot-cli" | "polytoken", value: unknown, command: string | null): unknown;
5
+ //# sourceMappingURL=recovery-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-hooks.d.ts","sourceRoot":"","sources":["../src/recovery-hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,mFAAmF;AACnF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,cAAc,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,oBAAc,GAAG,OAAO,CAmDvG;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,QAAQ,GAAG,aAAa,GAAG,WAAW,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CA2BvI"}
@@ -0,0 +1,115 @@
1
+ const OWNER = "--owner lore-recovery";
2
+ const isCore = (command) => typeof command === "string" && /--owner\s+lore(?:\s|$)/u.test(command);
3
+ /** Native event fields, never text scraped from the agent's answer or terminal. */
4
+ export function normalizeRecoveryHook(agent, value, env = process.env) {
5
+ if (!value || typeof value !== "object" || Array.isArray(value))
6
+ return null;
7
+ const input = { ...value };
8
+ if (input.agent_id || input.isSidechain || input.parent_session_id)
9
+ return null;
10
+ if (agent === "cursor") {
11
+ input.session_id = input.conversation_id;
12
+ input.cwd ??= Array.isArray(input.workspace_roots) && input.workspace_roots.length === 1 ? input.workspace_roots[0] : undefined;
13
+ input.turn_id = input.generation_id;
14
+ if (input.hook_event_name === "beforeSubmitPrompt")
15
+ input.hook_event_name = "UserPromptSubmit";
16
+ else if (input.hook_event_name === "afterAgentResponse") {
17
+ input.hook_event_name = "Checkpoint";
18
+ input.last_assistant_message = input.text;
19
+ }
20
+ else if (input.hook_event_name === "stop") {
21
+ input.hook_event_name = input.status === "error" ? "StopFailure" : "Stop";
22
+ if (input.status === "error")
23
+ input.error = "agent_error";
24
+ }
25
+ }
26
+ else if (agent === "copilot-cli") {
27
+ input.session_id = input.sessionId;
28
+ input.hook_event_name ??= env.LORE_RECOVERY_EVENT;
29
+ if (input.hook_event_name === "userPromptSubmitted") {
30
+ input.hook_event_name = "UserPromptSubmit";
31
+ // The events journal records this same native hook timestamp before user.message.
32
+ if (Number.isSafeInteger(input.timestamp))
33
+ input.turn_id = `hook:${input.timestamp}`;
34
+ }
35
+ else if (input.hook_event_name === "agentStop") {
36
+ input.hook_event_name = "Stop";
37
+ input.last_assistant_message = input.response;
38
+ }
39
+ else if (input.hook_event_name === "errorOccurred") {
40
+ if (input.recoverable !== false || !["model_call", "system"].includes(input.errorContext))
41
+ return null;
42
+ input.hook_event_name = "StopFailure";
43
+ input.error = "agent_error";
44
+ }
45
+ }
46
+ else if (agent === "polytoken") {
47
+ input.hook_event_name ??= input.event ?? env.POLYTOKEN_HOOK_EVENT;
48
+ input.session_id ??= env.POLYTOKEN_SESSION_ID;
49
+ input.cwd ??= env.POLYTOKEN_PROJECT_DIR ?? env.POLYTOKEN_PROJECT_PATH;
50
+ input.turn_id ??= input.prompt_id;
51
+ if (input.hook_event_name === "pre_user_prompt") {
52
+ input.hook_event_name = "UserPromptSubmit";
53
+ input.prompt ??= input.user_prompt ?? input.message?.content;
54
+ }
55
+ else if (input.hook_event_name === "post_model_turn") {
56
+ input.hook_event_name = "Checkpoint";
57
+ input.last_assistant_message ??= input.assistant_message ?? input.response ?? input.text ?? input.message?.content;
58
+ }
59
+ else if (input.hook_event_name === "pre_model_turn")
60
+ input.hook_event_name = "Checkpoint";
61
+ else if (input.hook_event_name === "stop")
62
+ input.hook_event_name = "Stop";
63
+ else
64
+ return null;
65
+ }
66
+ else if (agent === "devin") {
67
+ input.cwd ??= env.DEVIN_PROJECT_DIR ?? process.cwd();
68
+ if (["PostToolUse", "PostCompaction"].includes(input.hook_event_name)) {
69
+ input.hook_event_name = "Checkpoint";
70
+ input.last_assistant_message = input.summary ?? `Tool ${String(input.tool_name ?? "result")}: ${JSON.stringify(input.tool_response ?? {})}`;
71
+ }
72
+ }
73
+ return input;
74
+ }
75
+ export function mergeNativeRecoveryHooks(agent, value, command) {
76
+ if (agent === "polytoken") {
77
+ if (!Array.isArray(value))
78
+ throw new Error("Invalid Polytoken hooks: expected an array.");
79
+ const hooks = value.filter(hook => typeof hook?.handler?.bash !== "string" || !hook.handler.bash.includes(OWNER));
80
+ if (command)
81
+ for (const event of ["pre_user_prompt", "pre_model_turn", "post_model_turn", "stop"]) {
82
+ const core = hooks.findIndex(hook => isCore(hook?.handler?.bash));
83
+ hooks.splice(core < 0 ? hooks.length : core, 0, { name: `Lore recovery ${event}`, event, handler: { bash: command } });
84
+ }
85
+ return hooks;
86
+ }
87
+ if (!value || typeof value !== "object" || Array.isArray(value))
88
+ throw new Error(`Invalid ${agent} hooks.`);
89
+ const result = structuredClone(value);
90
+ if (result.hooks !== undefined && (!result.hooks || typeof result.hooks !== "object" || Array.isArray(result.hooks)))
91
+ throw new Error(`Invalid ${agent} hooks.`);
92
+ const hooks = result.hooks ?? {};
93
+ const events = agent === "cursor" ? ["beforeSubmitPrompt", "afterAgentResponse", "stop"] : ["userPromptSubmitted", "agentStop", "errorOccurred"];
94
+ for (const event of events) {
95
+ if (hooks[event] !== undefined && !Array.isArray(hooks[event]))
96
+ throw new Error(`Invalid ${agent} ${event} hooks.`);
97
+ const remaining = (hooks[event] ?? []).filter((hook) => !String(agent === "cursor" ? hook.command ?? "" : hook.bash ?? "").includes(OWNER));
98
+ if (command) {
99
+ const core = remaining.findIndex((hook) => isCore(agent === "cursor" ? hook.command : hook.bash));
100
+ remaining.splice(core < 0 ? remaining.length : core, 0, agent === "cursor" ? { command, timeout: 10 } : { type: "command", bash: `LORE_RECOVERY_EVENT=${event} ${command}`, timeoutSec: 10 });
101
+ }
102
+ if (remaining.length)
103
+ hooks[event] = remaining;
104
+ else
105
+ delete hooks[event];
106
+ }
107
+ if (Object.keys(hooks).length) {
108
+ result.hooks = hooks;
109
+ result.version ??= 1;
110
+ }
111
+ else
112
+ delete result.hooks;
113
+ return result;
114
+ }
115
+ //# sourceMappingURL=recovery-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-hooks.js","sourceRoot":"","sources":["../src/recovery-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { LorePaths } from "./cli.js";
2
+ import { type RecoveryRun } from "./recovery-state.js";
3
+ export declare function readOwnedJson(path: string, max?: number): Promise<any>;
4
+ export declare function installExternalRecovery(paths: LorePaths, hosts: readonly string[], cwd: string, fallback?: string, start?: boolean): Promise<string[]>;
5
+ export declare function installRecoveryMonitor(home: string, start?: boolean): Promise<void>;
6
+ export declare function disableExternalRecovery(home: string): Promise<void>;
7
+ export declare function pollExternalRecovery(home: string, notify?: (home: string, id: string) => Promise<void>): Promise<void>;
8
+ export declare function runExternalMonitor(home: string): Promise<void>;
9
+ export declare function externalCheckpointCommand(home: string): Promise<void>;
10
+ /** Stop offering the old saved result immediately when the editor starts a new prompt. */
11
+ export declare function invalidateEditorRecovery(home: string, value: unknown): Promise<void>;
12
+ export declare function validateExternalRecovery(home: string, run: RecoveryRun): Promise<void>;
13
+ //# sourceMappingURL=recovery-hosts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-hosts.d.ts","sourceRoot":"","sources":["../src/recovery-hosts.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,EAA0E,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAa/H,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAc,GAAG,OAAO,CAAC,GAAG,CAAC,CAOjF;AAMD,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,UAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA0CzJ;AAED,wBAAsB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,UAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAYtF;AAED,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBzE;AAED,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B5H;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBpE;AAED,wBAAsB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU3E;AAED,0FAA0F;AAC1F,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAY1F;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAW5F"}