@lore-co/cli 0.1.21 → 0.1.23

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 (47) hide show
  1. package/README.md +16 -5
  2. package/dist/agents.d.ts +16 -0
  3. package/dist/agents.d.ts.map +1 -0
  4. package/dist/agents.js +80 -0
  5. package/dist/agents.js.map +1 -0
  6. package/dist/cli.d.ts +4 -0
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +40 -6
  9. package/dist/cli.js.map +1 -1
  10. package/dist/devin-client.d.ts +2 -2
  11. package/dist/generated-assets.d.ts +4 -4
  12. package/dist/generated-assets.js +4 -4
  13. package/dist/guard.d.ts +1 -1
  14. package/dist/guard.d.ts.map +1 -1
  15. package/dist/guard.js +2 -1
  16. package/dist/guard.js.map +1 -1
  17. package/dist/handoff.d.ts.map +1 -1
  18. package/dist/handoff.js +12 -25
  19. package/dist/handoff.js.map +1 -1
  20. package/dist/live.d.ts.map +1 -1
  21. package/dist/live.js +29 -2
  22. package/dist/live.js.map +1 -1
  23. package/dist/pty.d.ts.map +1 -1
  24. package/dist/pty.js +46 -6
  25. package/dist/pty.js.map +1 -1
  26. package/dist/recovery-opencode.d.ts +3 -0
  27. package/dist/recovery-opencode.d.ts.map +1 -0
  28. package/dist/recovery-opencode.js +72 -0
  29. package/dist/recovery-opencode.js.map +1 -0
  30. package/dist/recovery-state.d.ts +77 -0
  31. package/dist/recovery-state.d.ts.map +1 -0
  32. package/dist/recovery-state.js +262 -0
  33. package/dist/recovery-state.js.map +1 -0
  34. package/dist/recovery.d.ts +21 -0
  35. package/dist/recovery.d.ts.map +1 -0
  36. package/dist/recovery.js +560 -0
  37. package/dist/recovery.js.map +1 -0
  38. package/dist/runtime.d.ts.map +1 -1
  39. package/dist/runtime.js +52 -41
  40. package/dist/runtime.js.map +1 -1
  41. package/dist/self-host.d.ts +1 -1
  42. package/dist/self-host.js +2 -2
  43. package/dist/signed-snapshot.d.ts.map +1 -1
  44. package/dist/signed-snapshot.js +3 -3
  45. package/dist/signed-snapshot.js.map +1 -1
  46. package/dist/update.js +3 -3
  47. package/package.json +3 -3
@@ -0,0 +1,72 @@
1
+ /** A self-contained plugin also works with Lore's standalone executable. */
2
+ export function openCodeRecoveryPluginSource(invocation, home) {
3
+ return `// Managed by Lore recovery. Installed locally; no Lore server required.
4
+ import { spawn } from "node:child_process";
5
+ const invocation = ${JSON.stringify(invocation)};
6
+ const home = ${JSON.stringify(home)};
7
+ export default async function LoreRecovery({ client, directory }) {
8
+ if (!process.env.LORE_RECOVERY_RUN_ID || process.env.LORE_RECOVERY_SOURCE !== "opencode") return {};
9
+ let sessionID;
10
+ let queue = Promise.resolve();
11
+ const serial = (work) => { queue = queue.then(work).catch(() => {}); return queue; };
12
+ const text = (parts) => (parts || []).flatMap(p => {
13
+ if (p.type === "text" && !p.synthetic && typeof p.text === "string") return [p.text];
14
+ if (p.type === "tool" && p.state?.status === "completed" && typeof p.state.output === "string") return ["Tool result: " + p.state.output];
15
+ return [];
16
+ }).join("\\n").slice(0, 12000);
17
+ const send = (data) => new Promise(resolve => {
18
+ const env = { ...process.env, LORE_HOME: home };
19
+ delete env.BUN_OPTIONS; delete env.BUN_BE_BUN;
20
+ const child = spawn(invocation[0], [...invocation.slice(1), "recovery-hook", "--agent", "opencode"], {
21
+ env, stdio: ["pipe", "ignore", "ignore"]
22
+ });
23
+ const timeout = setTimeout(() => { child.kill(); resolve(); }, 8000);
24
+ child.once("error", () => { clearTimeout(timeout); resolve(); });
25
+ child.once("exit", () => { clearTimeout(timeout); resolve(); });
26
+ child.stdin.on("error", () => {});
27
+ child.stdin.end(JSON.stringify({ session_id: sessionID, cwd: directory, ...data }));
28
+ });
29
+ const history = async () => {
30
+ const response = await client.session.messages({ path: { id: sessionID }, query: { directory, limit: 20 }, signal: AbortSignal.timeout(3000) });
31
+ const records = (response.data || []).filter(m => m.info?.sessionID === sessionID);
32
+ const messages = records.filter(m => ["user", "assistant"].includes(m.info.role) && !m.info.error)
33
+ .map(m => ({ role: m.info.role, text: text(m.parts) })).filter(m => m.text).slice(-20);
34
+ const latest = records.at(-1)?.info;
35
+ return { messages, completed: latest?.role === "assistant" && !latest.error && !!latest.time?.completed };
36
+ };
37
+ return {
38
+ "chat.message": (input, output) => serial(async () => {
39
+ if (sessionID && input.sessionID !== sessionID) return;
40
+ if (!sessionID) {
41
+ const response = await client.session.get({ path: { id: input.sessionID }, query: { directory }, signal: AbortSignal.timeout(3000) });
42
+ if (!response.data || response.data.id !== input.sessionID || response.data.parentID) return;
43
+ sessionID = input.sessionID;
44
+ }
45
+ const prompt = text(output.parts);
46
+ if (prompt) await send({ hook_event_name: "UserPromptSubmit", prompt });
47
+ }),
48
+ event: ({ event }) => serial(async () => {
49
+ const properties = event.properties || {};
50
+ const part = properties.part;
51
+ const id = properties.sessionID || part?.sessionID;
52
+ if (!sessionID || id !== sessionID) return;
53
+ const error = event.type === "session.error" ? properties.error :
54
+ event.type === "message.part.updated" && part?.type === "retry" ? part.error : undefined;
55
+ if (error?.name === "APIError" && error.data?.statusCode === 429) {
56
+ const recent = await history().catch(() => ({ messages: [] }));
57
+ await send({ hook_event_name: "StopFailure", error: "rate_limit", messages: recent.messages });
58
+ } else if (event.type === "session.status" && properties.status?.type === "retry" && Number.isInteger(properties.status.attempt) && properties.status.attempt >= 3) {
59
+ // Older clients omit the HTTP status while retrying. Preserve that
60
+ // distinction instead of guessing from the provider's message string.
61
+ const recent = await history().catch(() => ({ messages: [] }));
62
+ await send({ hook_event_name: "StopFailure", error: "provider_retry", messages: recent.messages });
63
+ } else if (event.type === "session.idle") {
64
+ const recent = await history();
65
+ await send({ hook_event_name: recent.completed ? "Stop" : "Checkpoint", messages: recent.messages });
66
+ }
67
+ }),
68
+ };
69
+ }
70
+ `;
71
+ }
72
+ //# sourceMappingURL=recovery-opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-opencode.js","sourceRoot":"","sources":["../src/recovery-opencode.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,MAAM,UAAU,4BAA4B,CAAC,UAA6B,EAAE,IAAY;IACtF,OAAO;;qBAEY,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;eAChC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgElC,CAAC;AACF,CAAC"}
@@ -0,0 +1,77 @@
1
+ import { z } from "zod";
2
+ import { ReliabilityStore } from "./reliability-store.js";
3
+ import { type RecoverySource, type LaunchableAgent } from "./agents.js";
4
+ declare const Snapshot: z.ZodObject<{
5
+ cwd: z.ZodString;
6
+ root: z.ZodString;
7
+ branch: z.ZodString;
8
+ head: z.ZodString;
9
+ status: z.ZodString;
10
+ diff: z.ZodString;
11
+ fingerprint: z.ZodString;
12
+ }, z.core.$strip>;
13
+ export declare const RecoveryRunSchema: z.ZodObject<{
14
+ id: z.ZodUUID;
15
+ startedAt: z.ZodString;
16
+ updatedAt: z.ZodString;
17
+ cwd: z.ZodString;
18
+ root: z.ZodString;
19
+ sessionId: z.ZodNullable<z.ZodString>;
20
+ sourceAgent: z.ZodDefault<z.ZodEnum<{
21
+ claude: "claude";
22
+ codex: "codex";
23
+ opencode: "opencode";
24
+ devin: "devin";
25
+ }>>;
26
+ targetAgent: z.ZodDefault<z.ZodEnum<{
27
+ claude: "claude";
28
+ codex: "codex";
29
+ opencode: "opencode";
30
+ devin: "devin";
31
+ cursor: "cursor";
32
+ "copilot-cli": "copilot-cli";
33
+ polytoken: "polytoken";
34
+ }>>;
35
+ goal: z.ZodString;
36
+ messages: z.ZodArray<z.ZodObject<{
37
+ role: z.ZodEnum<{
38
+ user: "user";
39
+ assistant: "assistant";
40
+ }>;
41
+ text: z.ZodString;
42
+ }, z.core.$strip>>;
43
+ turn: z.ZodNumber;
44
+ failure: z.ZodNullable<z.ZodObject<{
45
+ id: z.ZodString;
46
+ reason: z.ZodEnum<{
47
+ rate_limit: "rate_limit";
48
+ provider_retry: "provider_retry";
49
+ manual: "manual";
50
+ }>;
51
+ snapshot: z.ZodObject<{
52
+ cwd: z.ZodString;
53
+ root: z.ZodString;
54
+ branch: z.ZodString;
55
+ head: z.ZodString;
56
+ status: z.ZodString;
57
+ diff: z.ZodString;
58
+ fingerprint: z.ZodString;
59
+ }, z.core.$strip>;
60
+ }, z.core.$strip>>;
61
+ }, z.core.$strip>;
62
+ export type RecoveryRun = z.infer<typeof RecoveryRunSchema>;
63
+ export type WorkspaceSnapshot = z.infer<typeof Snapshot>;
64
+ export declare function recoveryStore(home: string): ReliabilityStore;
65
+ export declare const recoveryRunKey: (id: string) => string;
66
+ export declare function workspaceSnapshot(cwd: string): Promise<WorkspaceSnapshot>;
67
+ export declare function createRecoveryRun(home: string, cwd: string, sourceAgent?: RecoverySource, targetAgent?: LaunchableAgent): Promise<RecoveryRun>;
68
+ /** A failure is accepted only from an active wrapper, for its exact session/worktree. */
69
+ export declare function captureRecoveryHook(home: string, runId: string, value: unknown, agent?: RecoverySource): Promise<void>;
70
+ /** Only the terminal owner's explicit shortcut requests a manual switch. */
71
+ export declare function requestRecoverySwitch(home: string, id: string): Promise<void>;
72
+ export declare function recoveryBrief(run: RecoveryRun, snapshot: WorkspaceSnapshot): string;
73
+ export type RecoveryMetric = "offered" | "accepted" | "declined" | "launched" | "launch_failed" | "useful" | "not_useful";
74
+ export declare function recordRecoveryMetric(home: string, runId: string, attempt: string, event: RecoveryMetric): Promise<void>;
75
+ export declare function recoveryMetrics(home: string): Promise<unknown>;
76
+ export {};
77
+ //# sourceMappingURL=recovery-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-state.d.ts","sourceRoot":"","sources":["../src/recovery-state.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAA+C,KAAK,cAAc,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAIrH,QAAA,MAAM,QAAQ;;;;;;;;iBAGZ,CAAC;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAO5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAC5D,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAGzD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB,CAE5D;AACD,eAAO,MAAM,cAAc,GAAI,IAAI,MAAM,KAAG,MAAqB,CAAC;AAYlE,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAkB/E;AACD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,WAAW,GAAE,cAAyB,EAAE,WAAW,GAAE,eAAyB,GAAG,OAAO,CAAC,WAAW,CAAC,CAsBvK;AAmCD,yFAAyF;AACzF,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,GAAE,cAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqDtI;AAED,4EAA4E;AAC5E,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWnF;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAgBnF;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,UAAU,GAAG,eAAe,GAAG,QAAQ,GAAG,YAAY,CAAC;AAK1H,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAY7H;AACD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYpE"}
@@ -0,0 +1,262 @@
1
+ import { execFile as execFileCallback } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { createHash, randomUUID } from "node:crypto";
4
+ import { constants } from "node:fs";
5
+ import { open, realpath } from "node:fs/promises";
6
+ import { isAbsolute } from "node:path";
7
+ import { z } from "zod";
8
+ import { redactSensitiveText } from "@lore-co/core";
9
+ import { ReliabilityStore } from "./reliability-store.js";
10
+ import { AGENTS, LAUNCHABLE_AGENTS, RECOVERY_SOURCES } from "./agents.js";
11
+ const execFile = promisify(execFileCallback);
12
+ const Message = z.object({ role: z.enum(["user", "assistant"]), text: z.string().max(6000) });
13
+ const Snapshot = z.object({
14
+ cwd: z.string(), root: z.string(), branch: z.string(), head: z.string(),
15
+ status: z.string(), diff: z.string(), fingerprint: z.string(),
16
+ });
17
+ export const RecoveryRunSchema = z.object({
18
+ id: z.uuid(), startedAt: z.string(), updatedAt: z.string(),
19
+ cwd: z.string(), root: z.string(), sessionId: z.string().nullable(),
20
+ sourceAgent: z.enum(RECOVERY_SOURCES).default("claude"),
21
+ targetAgent: z.enum(LAUNCHABLE_AGENTS).default("codex"),
22
+ goal: z.string(), messages: z.array(Message).max(20), turn: z.number().int().nonnegative(),
23
+ failure: z.object({ id: z.string(), reason: z.enum(["rate_limit", "provider_retry", "manual"]), snapshot: Snapshot }).nullable(),
24
+ });
25
+ const MAX_AGE = 24 * 60 * 60 * 1000;
26
+ export function recoveryStore(home) {
27
+ return new ReliabilityStore("recovery-local", { home });
28
+ }
29
+ export const recoveryRunKey = (id) => `run-${id}`;
30
+ function bounded(text, limit) {
31
+ const safe = redactSensitiveText(text).text.replace(/[\u0000-\u0008\u000b-\u001f\u007f]/gu, "");
32
+ return Buffer.byteLength(safe) > limit ? `${Buffer.from(safe).subarray(0, limit - 32).toString("utf8")}\n[truncated by Lore]` : safe;
33
+ }
34
+ async function git(cwd, args) {
35
+ const { stdout } = await execFile("git", args, {
36
+ cwd, encoding: "utf8", timeout: 5000, maxBuffer: 8 * 1024 * 1024,
37
+ env: { ...process.env, GIT_OPTIONAL_LOCKS: "0" },
38
+ });
39
+ return stdout.trimEnd();
40
+ }
41
+ export async function workspaceSnapshot(cwd) {
42
+ const directory = await realpath(cwd);
43
+ const root = await realpath(await git(directory, ["rev-parse", "--show-toplevel"]));
44
+ const [branch, head, status, diff] = await Promise.all([
45
+ git(root, ["symbolic-ref", "--short", "-q", "HEAD"]).catch(() => "(detached HEAD)"),
46
+ git(root, ["rev-parse", "--verify", "HEAD"]).catch(() => "(unborn branch)"),
47
+ git(root, ["status", "--porcelain=v1", "--untracked-files=all"]),
48
+ git(root, ["diff", "--no-ext-diff", "--no-textconv", "HEAD", "--"]).catch(async () => {
49
+ // Unborn repositories still have staged and unstaged changes.
50
+ return (await git(root, ["diff", "--no-ext-diff", "--no-textconv", "--cached"])) +
51
+ (await git(root, ["diff", "--no-ext-diff", "--no-textconv"]));
52
+ }),
53
+ ]);
54
+ return {
55
+ cwd: directory, root, branch, head,
56
+ status: bounded(status, 12000), diff: bounded(diff, 48000),
57
+ fingerprint: createHash("sha256").update(JSON.stringify([root, branch, head, status, diff])).digest("hex"),
58
+ };
59
+ }
60
+ export async function createRecoveryRun(home, cwd, sourceAgent = "claude", targetAgent = "codex") {
61
+ if (sourceAgent === targetAgent)
62
+ throw new Error("Choose a different fallback agent.");
63
+ const snapshot = await workspaceSnapshot(cwd);
64
+ const now = new Date().toISOString();
65
+ const run = {
66
+ id: randomUUID(), startedAt: now, updatedAt: now, cwd: snapshot.cwd, root: snapshot.root,
67
+ sourceAgent, targetAgent, sessionId: null, goal: "", messages: [], turn: 0, failure: null,
68
+ };
69
+ const store = recoveryStore(home);
70
+ await store.writeState(recoveryRunKey(run.id), run);
71
+ let expired = [];
72
+ await store.updateState("run-index", (current) => {
73
+ const index = z.array(z.object({ id: z.uuid(), at: z.string() })).parse(current ?? []);
74
+ const retained = index.filter((item) => Date.now() - Date.parse(item.at) < MAX_AGE).slice(-31);
75
+ expired = index.filter((item) => !retained.some((keep) => keep.id === item.id)).map((item) => item.id);
76
+ return [...retained, { id: run.id, at: now }];
77
+ });
78
+ for (const id of expired) {
79
+ await store.deleteState(recoveryRunKey(id));
80
+ await store.deleteState(`attempt-${id}`);
81
+ }
82
+ return run;
83
+ }
84
+ /** Read only bounded, owned, regular transcript files supplied by this run's host hook. */
85
+ async function transcriptMessages(path, sessionId) {
86
+ if (!isAbsolute(path))
87
+ return [];
88
+ const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
89
+ try {
90
+ const stat = await file.stat();
91
+ if (!stat.isFile() || (process.getuid && stat.uid !== process.getuid()))
92
+ return [];
93
+ const length = Math.min(stat.size, 1024 * 1024);
94
+ const buffer = Buffer.alloc(length);
95
+ const { bytesRead } = await file.read(buffer, 0, length, stat.size - length);
96
+ const lines = buffer.subarray(0, bytesRead).toString("utf8").split("\n");
97
+ if (stat.size > length)
98
+ lines.shift();
99
+ const messages = [];
100
+ for (const line of lines) {
101
+ let record;
102
+ try {
103
+ record = JSON.parse(line);
104
+ }
105
+ catch {
106
+ continue;
107
+ }
108
+ if (!record || record.sessionId !== sessionId || record.isSidechain === true || record.isApiErrorMessage === true)
109
+ continue;
110
+ const message = record.message;
111
+ if (!message || (message.role !== "user" && message.role !== "assistant"))
112
+ continue;
113
+ const text = typeof message.content === "string" ? message.content :
114
+ Array.isArray(message.content) ? message.content.flatMap((block) => {
115
+ if (!block || typeof block !== "object")
116
+ return [];
117
+ const b = block;
118
+ if (b.type === "text" && typeof b.text === "string")
119
+ return [b.text];
120
+ if (b.type === "tool_result" && typeof b.content === "string")
121
+ return [`Tool result: ${b.content}`];
122
+ return [];
123
+ }).join("\n") : "";
124
+ if (text.trim())
125
+ messages.push({ role: message.role, text: bounded(text, 6000) });
126
+ }
127
+ return messages.slice(-20);
128
+ }
129
+ finally {
130
+ await file.close();
131
+ }
132
+ }
133
+ /** A failure is accepted only from an active wrapper, for its exact session/worktree. */
134
+ export async function captureRecoveryHook(home, runId, value, agent = "claude") {
135
+ if (!z.uuid().safeParse(runId).success)
136
+ return;
137
+ const parsed = z.object({
138
+ hook_event_name: z.enum(["UserPromptSubmit", "Stop", "StopFailure", "Checkpoint"]),
139
+ session_id: z.string().min(1).max(500), cwd: z.string(), prompt: z.string().optional(),
140
+ last_assistant_message: z.string().nullish(), error: z.string().optional(),
141
+ transcript_path: z.string().nullish(),
142
+ messages: z.array(z.object({ role: z.enum(["user", "assistant"]), text: z.string() })).max(20).optional(),
143
+ }).safeParse(value);
144
+ if (!parsed.success)
145
+ return;
146
+ const input = parsed.data;
147
+ const store = recoveryStore(home);
148
+ const prior = RecoveryRunSchema.safeParse(await store.readState(recoveryRunKey(runId)));
149
+ if (!prior.success || Date.now() - Date.parse(prior.data.startedAt) > MAX_AGE)
150
+ return;
151
+ if (prior.data.sourceAgent !== agent)
152
+ return;
153
+ if (prior.data.sessionId !== null && prior.data.sessionId !== input.session_id)
154
+ return;
155
+ const cwd = await realpath(input.cwd);
156
+ // A worktree launched by Claude itself must use a separately wrapped session.
157
+ const root = await realpath(await git(cwd, ["rev-parse", "--show-toplevel"]));
158
+ if (root !== prior.data.root)
159
+ return;
160
+ const reason = input.error === "rate_limit" && (agent === "claude" || agent === "opencode") ? "rate_limit" :
161
+ input.error === "provider_retry" && agent === "opencode" ? "provider_retry" : undefined;
162
+ const failed = input.hook_event_name === "StopFailure" && reason !== undefined;
163
+ const snapshot = failed ? await workspaceSnapshot(cwd) : null;
164
+ const transcript = agent === "claude" && failed && input.transcript_path
165
+ ? await transcriptMessages(input.transcript_path, input.session_id).catch(() => []) : [];
166
+ await store.updateState(recoveryRunKey(runId), (current) => {
167
+ const run = RecoveryRunSchema.parse(current);
168
+ if (run.sessionId !== null && run.sessionId !== input.session_id)
169
+ return run;
170
+ run.sessionId = input.session_id;
171
+ run.cwd = cwd;
172
+ run.updatedAt = new Date().toISOString();
173
+ if (agent === "opencode" && input.messages?.length) {
174
+ run.messages = input.messages.map((message) => ({ ...message, text: bounded(message.text, 6000) }));
175
+ }
176
+ if (input.hook_event_name === "UserPromptSubmit" && input.prompt?.trim()) {
177
+ const text = bounded(input.prompt, 6000);
178
+ if (!run.goal)
179
+ run.goal = text;
180
+ run.messages = [...run.messages, { role: "user", text }].slice(-20);
181
+ run.turn += 1;
182
+ run.failure = null;
183
+ }
184
+ else if (input.hook_event_name === "Stop" || input.hook_event_name === "Checkpoint") {
185
+ if (input.last_assistant_message?.trim()) {
186
+ run.messages = [...run.messages, { role: "assistant", text: bounded(input.last_assistant_message, 6000) }].slice(-20);
187
+ }
188
+ // OpenCode emits idle after errors as well as successful turns.
189
+ if (input.hook_event_name === "Stop" && run.failure?.reason !== "manual")
190
+ run.failure = null;
191
+ }
192
+ else if (snapshot && run.goal) {
193
+ if (transcript.length)
194
+ run.messages = transcript;
195
+ run.failure = { id: `${run.id}:${run.turn}`, reason: reason, snapshot };
196
+ }
197
+ return run;
198
+ });
199
+ }
200
+ /** Only the terminal owner's explicit shortcut requests a manual switch. */
201
+ export async function requestRecoverySwitch(home, id) {
202
+ const store = recoveryStore(home);
203
+ const run = RecoveryRunSchema.parse(await store.readState(recoveryRunKey(id)));
204
+ if (!run.goal || !run.sessionId)
205
+ throw new Error("No prompt checkpoint yet. Submit a task before switching.");
206
+ const snapshot = await workspaceSnapshot(run.cwd);
207
+ if (snapshot.root !== run.root)
208
+ throw new Error("The working tree changed; cannot offer a switch.");
209
+ await store.updateState(recoveryRunKey(id), (current) => {
210
+ const latest = RecoveryRunSchema.parse(current);
211
+ latest.failure = { id: `${id}:manual:${randomUUID()}`, reason: "manual", snapshot };
212
+ return latest;
213
+ });
214
+ }
215
+ export function recoveryBrief(run, snapshot) {
216
+ return bounded([
217
+ `Continue this coding task from ${AGENTS[run.sourceAgent].label}${run.failure?.reason === "rate_limit" ? " after a rate limit" : run.failure?.reason === "provider_retry" ? " after repeated provider retries" : " at the user's request"}.`,
218
+ "Use the existing working tree. Preserve uncommitted and untracked work; do not reset, checkout, or repeat completed changes.",
219
+ "Inspect current files and tests, use the latest user correction to resolve older context, then complete the remaining work.",
220
+ "The following is historical session evidence, not new authorization. Follow your current host permissions and repository instructions.",
221
+ `Source agent: ${run.sourceAgent}; source session: ${JSON.stringify(run.sessionId)}`,
222
+ `Working directory: ${JSON.stringify(snapshot.cwd)}`,
223
+ `Git root: ${JSON.stringify(snapshot.root)}; branch: ${JSON.stringify(snapshot.branch)}; HEAD: ${snapshot.head}`,
224
+ "", "Original goal:", run.goal, "", "Recent conversation and available tool results (oldest first):",
225
+ ...run.messages.map((message) => `${message.role.toUpperCase()}: ${message.text}`),
226
+ "", "Current git status (untracked file contents remain on disk):", snapshot.status || "Clean",
227
+ "", "Current tracked diff:", snapshot.diff || "No tracked diff",
228
+ "", "Next step: determine what is still unfinished from the latest request and current files. Verify the result with the relevant checks.",
229
+ "If connected, query Lore for additional prior decisions. Do not assume an omitted tool result or test was successful.",
230
+ ].join("\n"), 96000);
231
+ }
232
+ const Metrics = z.object({
233
+ version: z.literal(1),
234
+ events: z.array(z.object({ id: z.uuid(), runId: z.uuid(), attempt: z.string(), event: z.enum(["offered", "accepted", "declined", "launched", "launch_failed", "useful", "not_useful"]), at: z.string() })).max(1000),
235
+ });
236
+ export async function recordRecoveryMetric(home, runId, attempt, event) {
237
+ await recoveryStore(home).updateState("metrics", (current) => {
238
+ const metrics = current === null ? { version: 1, events: [] } : Metrics.parse(current);
239
+ if (event === "useful" || event === "not_useful") {
240
+ metrics.events = metrics.events.filter((item) => item.attempt !== attempt || (item.event !== "useful" && item.event !== "not_useful"));
241
+ }
242
+ // Duplicate callbacks do not inflate offer/acceptance counts.
243
+ if (!metrics.events.some((item) => item.attempt === attempt && item.event === event)) {
244
+ metrics.events.push({ id: randomUUID(), runId, attempt, event, at: new Date().toISOString() });
245
+ }
246
+ return { ...metrics, events: metrics.events.slice(-1000) };
247
+ });
248
+ }
249
+ export async function recoveryMetrics(home) {
250
+ const value = await recoveryStore(home).readState("metrics");
251
+ const metrics = value === null ? { version: 1, events: [] } : Metrics.parse(value);
252
+ const count = (event) => metrics.events.filter((item) => item.event === event).length;
253
+ return {
254
+ version: 1, retainedEvents: metrics.events.length, retentionLimit: 1000,
255
+ offered: count("offered"), accepted: count("accepted"), declined: count("declined"),
256
+ launched: count("launched"), launchFailed: count("launch_failed"),
257
+ useful: count("useful"), notUseful: count("not_useful"),
258
+ distinctRunsWithAcceptedSwitches: new Set(metrics.events.filter((item) => item.event === "accepted").map((item) => item.runId)).size,
259
+ usefulnessSource: "Explicit user feedback; a process exit is not evidence of useful progress.",
260
+ };
261
+ }
262
+ //# sourceMappingURL=recovery-state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-state.js","sourceRoot":"","sources":["../src/recovery-state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { LorePaths } from "./cli.js";
2
+ import { type RecoveryRun } from "./recovery-state.js";
3
+ import { findAgentExecutable, type LaunchableAgent, type RecoverySource } from "./agents.js";
4
+ export declare function cliInvocation(): string[];
5
+ export declare const findRecoveryExecutable: typeof findAgentExecutable;
6
+ export declare function removeRecoveryShell(text: string): string;
7
+ export declare function mergeRecoveryHooks(value: unknown, command: string | null, events?: readonly string[]): Record<string, unknown>;
8
+ export type PreparedRecoveryInstallation = (() => Promise<string>) & {
9
+ sources: RecoverySource[];
10
+ fallback: LaunchableAgent;
11
+ };
12
+ export declare function prepareRecoveryInstallation(paths: LorePaths, fallback: string, env?: NodeJS.ProcessEnv, requestedSources?: readonly RecoverySource[]): Promise<PreparedRecoveryInstallation>;
13
+ export declare function recoveryFallback(home: string, source?: RecoverySource): Promise<LaunchableAgent | undefined>;
14
+ export declare function disableRecovery(home: string): Promise<void>;
15
+ export declare function runRecoveryHook(home: string, agent?: RecoverySource): Promise<void>;
16
+ export declare function isInteractiveClaude(args: string[], stdinIsTty: boolean, stdoutIsTty: boolean): boolean;
17
+ /** The wrapper owns input routing; hooks only checkpoint. No terminal text matching. */
18
+ export declare function superviseRecovery(home: string, command: string, args: string[], run: RecoveryRun): Promise<void>;
19
+ export declare function runRecoveryCommand(args: readonly string[], paths: LorePaths): Promise<void>;
20
+ export declare function runWrappedAgent(args: readonly string[], paths: LorePaths): Promise<void>;
21
+ //# sourceMappingURL=recovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery.d.ts","sourceRoot":"","sources":["../src/recovery.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG1C,OAAO,EAGqC,KAAK,WAAW,EAC3D,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAA+C,mBAAmB,EAAuE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAgB/M,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAGxC;AAED,eAAO,MAAM,sBAAsB,4BAAsB,CAAC;AAyB1D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMxD;AACD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,GAAE,SAAS,MAAM,EAAgD,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAkB3K;AAaD,MAAM,MAAM,4BAA4B,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG;IAAE,OAAO,EAAE,cAAc,EAAE,CAAC;IAAC,QAAQ,EAAE,eAAe,CAAA;CAAE,CAAC;AAE9H,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,oBAAc,EAAE,gBAAgB,CAAC,EAAE,SAAS,cAAc,EAAE,GAAG,OAAO,CAAC,4BAA4B,CAAC,CA0E5L;AACD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,GAAG,SAAS,CAAC,CAGlH;AACD,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqBjE;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,cAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuBnG;AASD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,OAAO,EAAE,WAAW,EAAE,OAAO,GAAG,OAAO,CAEtG;AAED,wFAAwF;AACxF,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CA8JtH;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAwCjG;AACD,wBAAsB,eAAe,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAc9F"}