@tryglen/cli 0.24.10 → 0.26.1

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 (86) hide show
  1. package/README.md +55 -28
  2. package/dist/_utils/cli-error.d.ts +1 -0
  3. package/dist/_utils/cli-error.js.map +1 -1
  4. package/dist/_utils/config.d.ts +7 -0
  5. package/dist/_utils/config.js +7 -0
  6. package/dist/_utils/config.js.map +1 -1
  7. package/dist/_utils/parse-cursor-db.js +2 -0
  8. package/dist/_utils/parse-cursor-db.js.map +1 -1
  9. package/dist/_utils/refresh-control-state.d.ts +3 -0
  10. package/dist/_utils/refresh-control-state.js +24 -0
  11. package/dist/_utils/refresh-control-state.js.map +1 -0
  12. package/dist/_utils/sync-mode-from-server.d.ts +1 -2
  13. package/dist/_utils/sync-mode-from-server.js +28 -13
  14. package/dist/_utils/sync-mode-from-server.js.map +1 -1
  15. package/dist/bin.js +10 -0
  16. package/dist/bin.js.map +1 -1
  17. package/dist/commands/ingest.js +8 -4
  18. package/dist/commands/ingest.js.map +1 -1
  19. package/dist/commands/org.js +51 -4
  20. package/dist/commands/org.js.map +1 -1
  21. package/dist/commands/session-start.js +5 -1
  22. package/dist/commands/session-start.js.map +1 -1
  23. package/dist/commands/set-mode.d.ts +3 -4
  24. package/dist/commands/set-mode.js +20 -15
  25. package/dist/commands/set-mode.js.map +1 -1
  26. package/dist/commands/takeover/_utils/agent-paths.d.ts +6 -0
  27. package/dist/commands/takeover/_utils/agent-paths.js +23 -0
  28. package/dist/commands/takeover/_utils/agent-paths.js.map +1 -0
  29. package/dist/commands/takeover/_utils/archive-codex-desktop-thread.d.ts +5 -0
  30. package/dist/commands/takeover/_utils/archive-codex-desktop-thread.js +63 -0
  31. package/dist/commands/takeover/_utils/archive-codex-desktop-thread.js.map +1 -0
  32. package/dist/commands/takeover/_utils/canonical-digest.d.ts +5 -0
  33. package/dist/commands/takeover/_utils/canonical-digest.js +4 -0
  34. package/dist/commands/takeover/_utils/canonical-digest.js.map +1 -0
  35. package/dist/commands/takeover/_utils/codex-desktop-recovery.d.ts +16 -0
  36. package/dist/commands/takeover/_utils/codex-desktop-recovery.js +102 -0
  37. package/dist/commands/takeover/_utils/codex-desktop-recovery.js.map +1 -0
  38. package/dist/commands/takeover/_utils/context-fit.d.ts +18 -0
  39. package/dist/commands/takeover/_utils/context-fit.js +30 -0
  40. package/dist/commands/takeover/_utils/context-fit.js.map +1 -0
  41. package/dist/commands/takeover/_utils/cursor-store.d.ts +49 -0
  42. package/dist/commands/takeover/_utils/cursor-store.js +359 -0
  43. package/dist/commands/takeover/_utils/cursor-store.js.map +1 -0
  44. package/dist/commands/takeover/_utils/import-codex-desktop-thread.d.ts +14 -0
  45. package/dist/commands/takeover/_utils/import-codex-desktop-thread.js +293 -0
  46. package/dist/commands/takeover/_utils/import-codex-desktop-thread.js.map +1 -0
  47. package/dist/commands/takeover/_utils/launch-desktop-url.d.ts +4 -0
  48. package/dist/commands/takeover/_utils/launch-desktop-url.js +40 -0
  49. package/dist/commands/takeover/_utils/launch-desktop-url.js.map +1 -0
  50. package/dist/commands/takeover/_utils/native-file.d.ts +14 -0
  51. package/dist/commands/takeover/_utils/native-file.js +105 -0
  52. package/dist/commands/takeover/_utils/native-file.js.map +1 -0
  53. package/dist/commands/takeover/_utils/probe-agent.d.ts +20 -0
  54. package/dist/commands/takeover/_utils/probe-agent.js +37 -0
  55. package/dist/commands/takeover/_utils/probe-agent.js.map +1 -0
  56. package/dist/commands/takeover/_utils/provenance-context.d.ts +7 -0
  57. package/dist/commands/takeover/_utils/provenance-context.js +12 -0
  58. package/dist/commands/takeover/_utils/provenance-context.js.map +1 -0
  59. package/dist/commands/takeover/_utils/staged-session.d.ts +64 -0
  60. package/dist/commands/takeover/_utils/staged-session.js +30 -0
  61. package/dist/commands/takeover/_utils/staged-session.js.map +1 -0
  62. package/dist/commands/takeover/_utils/write-claude-desktop-session.d.ts +47 -0
  63. package/dist/commands/takeover/_utils/write-claude-desktop-session.js +24 -0
  64. package/dist/commands/takeover/_utils/write-claude-desktop-session.js.map +1 -0
  65. package/dist/commands/takeover/_utils/write-claude-session.d.ts +53 -0
  66. package/dist/commands/takeover/_utils/write-claude-session.js +132 -0
  67. package/dist/commands/takeover/_utils/write-claude-session.js.map +1 -0
  68. package/dist/commands/takeover/_utils/write-codex-desktop-session.d.ts +96 -0
  69. package/dist/commands/takeover/_utils/write-codex-desktop-session.js +272 -0
  70. package/dist/commands/takeover/_utils/write-codex-desktop-session.js.map +1 -0
  71. package/dist/commands/takeover/_utils/write-codex-session.d.ts +52 -0
  72. package/dist/commands/takeover/_utils/write-codex-session.js +117 -0
  73. package/dist/commands/takeover/_utils/write-codex-session.js.map +1 -0
  74. package/dist/commands/takeover/_utils/write-cursor-session.d.ts +57 -0
  75. package/dist/commands/takeover/_utils/write-cursor-session.js +174 -0
  76. package/dist/commands/takeover/_utils/write-cursor-session.js.map +1 -0
  77. package/dist/commands/takeover/_utils/write-pi-session.d.ts +52 -0
  78. package/dist/commands/takeover/_utils/write-pi-session.js +173 -0
  79. package/dist/commands/takeover/_utils/write-pi-session.js.map +1 -0
  80. package/dist/commands/takeover/index.d.ts +21 -0
  81. package/dist/commands/takeover/index.js +201 -0
  82. package/dist/commands/takeover/index.js.map +1 -0
  83. package/dist/commands/takeover/takeover.schema.d.ts +24 -0
  84. package/dist/commands/takeover/takeover.schema.js +66 -0
  85. package/dist/commands/takeover/takeover.schema.js.map +1 -0
  86. package/package.json +1 -1
@@ -0,0 +1,293 @@
1
+ import { spawn } from "node:child_process";
2
+ import { cliErr } from "../../../_utils/cli-error.js";
3
+ import { err, ok } from "../../../_utils/result.js";
4
+ import { cliVersion } from "../../../_utils/version.js";
5
+ import { archiveCodexDesktopThread } from "./archive-codex-desktop-thread.js";
6
+ const TIMEOUT_MS = 15_000;
7
+ const IMPORT_MARKER = "<EXTERNAL SESSION IMPORTED>";
8
+ const transcriptMessage = (role, content) => ({
9
+ role,
10
+ content,
11
+ });
12
+ const visibleMessages = (value) => {
13
+ const turns = value && typeof value === "object" && "thread" in value
14
+ ? value.thread?.turns
15
+ : null;
16
+ if (!Array.isArray(turns))
17
+ return [];
18
+ return turns.flatMap((turn) => {
19
+ const items = turn && typeof turn === "object" && "items" in turn
20
+ ? turn.items
21
+ : null;
22
+ if (!Array.isArray(items))
23
+ return [];
24
+ return items.flatMap((item) => {
25
+ if (!item || typeof item !== "object" || !("type" in item))
26
+ return [];
27
+ const typed = item;
28
+ if (typed.type === "agentMessage")
29
+ return typeof typed.text === "string" && typed.text !== IMPORT_MARKER
30
+ ? [transcriptMessage("assistant", typed.text)]
31
+ : [];
32
+ if (typed.type !== "userMessage" || !Array.isArray(typed.content))
33
+ return [];
34
+ const text = typed.content
35
+ .flatMap((part) => part &&
36
+ typeof part === "object" &&
37
+ "type" in part &&
38
+ part.type === "text" &&
39
+ "text" in part &&
40
+ typeof part.text === "string"
41
+ ? [part.text]
42
+ : [])
43
+ .join("");
44
+ return [transcriptMessage("user", text)];
45
+ });
46
+ });
47
+ };
48
+ const importCodexDesktopThread = (input) => new Promise((resolve) => {
49
+ const child = spawn(input.binary, ["app-server"], {
50
+ stdio: ["pipe", "pipe", "ignore"],
51
+ });
52
+ const state = {
53
+ buffer: "",
54
+ importId: null,
55
+ threadId: null,
56
+ archiveQueue: [],
57
+ pendingError: null,
58
+ finished: false,
59
+ };
60
+ const finish = (result, cleanupPartialThread = false) => {
61
+ if (state.finished)
62
+ return;
63
+ state.finished = true;
64
+ clearTimeout(timer);
65
+ child.kill();
66
+ const cleanupIds = cleanupPartialThread
67
+ ? [state.threadId, ...state.archiveQueue].flatMap((threadId) => threadId ? [threadId] : [])
68
+ : [];
69
+ const uniqueCleanupIds = [...new Set(cleanupIds)];
70
+ const cleanup = Promise.all(uniqueCleanupIds.map((threadId) => archiveCodexDesktopThread({
71
+ binary: input.binary,
72
+ threadId,
73
+ })));
74
+ void cleanup.then((archived) => resolve(archived.some((didArchive) => !didArchive)
75
+ ? err(cliErr({
76
+ what: "Codex Desktop left partial imported tasks behind",
77
+ why: `could not archive ${uniqueCleanupIds.join(", ")}`,
78
+ remedy: `archive tasks ${uniqueCleanupIds.join(", ")} in Codex Desktop, then retry`,
79
+ }))
80
+ : result));
81
+ };
82
+ const failure = (why) => cliErr({
83
+ what: "Codex Desktop could not import the verified transcript",
84
+ why,
85
+ remedy: "update Glen and Codex Desktop, then retry; no takeover was completed",
86
+ });
87
+ const write = (message) => {
88
+ if (state.finished)
89
+ return;
90
+ child.stdin.write(`${JSON.stringify({ jsonrpc: "2.0", ...message })}\n`);
91
+ };
92
+ const archiveNext = () => {
93
+ const threadId = state.archiveQueue[0];
94
+ if (!threadId) {
95
+ const pendingError = state.pendingError;
96
+ finish(err(pendingError ??
97
+ failure("imported task cleanup finished without an error")));
98
+ return;
99
+ }
100
+ write({
101
+ id: 6,
102
+ method: "thread/archive",
103
+ params: { threadId },
104
+ });
105
+ };
106
+ const rejectImportedThreads = (error, threadIds) => {
107
+ const uniqueThreadIds = [...new Set(threadIds)];
108
+ if (uniqueThreadIds.length === 0) {
109
+ finish(err(error));
110
+ return;
111
+ }
112
+ state.pendingError = error;
113
+ state.archiveQueue = uniqueThreadIds;
114
+ archiveNext();
115
+ };
116
+ const rejectImportedThread = (error) => {
117
+ rejectImportedThreads(error, state.threadId ? [state.threadId] : []);
118
+ };
119
+ const timer = setTimeout(() => finish(err(failure("codex app-server timed out")), true), TIMEOUT_MS);
120
+ child.on("error", () => finish(err(failure("could not start codex app-server"))));
121
+ child.on("close", () => finish(err(failure("codex app-server exited before import completed")), true));
122
+ child.stdin.on("error", () => finish(err(failure("codex app-server input closed unexpectedly")), true));
123
+ child.stdout.on("data", (chunk) => {
124
+ state.buffer += chunk.toString();
125
+ const lines = state.buffer.split("\n");
126
+ state.buffer = lines.pop() ?? "";
127
+ for (const line of lines) {
128
+ if (!line.trim())
129
+ continue;
130
+ const message = (() => {
131
+ try {
132
+ return JSON.parse(line);
133
+ }
134
+ catch {
135
+ return null;
136
+ }
137
+ })();
138
+ if (!message)
139
+ continue;
140
+ if (message.method === "externalAgentConfig/import/completed") {
141
+ const params = message.params;
142
+ if (params?.importId !== state.importId)
143
+ continue;
144
+ const results = Array.isArray(params.itemTypeResults)
145
+ ? params.itemTypeResults
146
+ : [];
147
+ const sessionResult = results.find((result) => result &&
148
+ typeof result === "object" &&
149
+ "itemType" in result &&
150
+ result.itemType === "SESSIONS");
151
+ const failures = Array.isArray(sessionResult?.failures)
152
+ ? sessionResult.failures
153
+ : [];
154
+ const targets = (Array.isArray(sessionResult?.successes)
155
+ ? sessionResult.successes
156
+ : []).flatMap((success) => success &&
157
+ typeof success === "object" &&
158
+ "target" in success &&
159
+ typeof success.target === "string"
160
+ ? [success.target]
161
+ : []);
162
+ if (failures.length > 0) {
163
+ const reported = failures[0];
164
+ rejectImportedThreads(failure(typeof reported.message === "string"
165
+ ? reported.message
166
+ : "external session import failed"), targets);
167
+ continue;
168
+ }
169
+ if (targets.length !== 1) {
170
+ rejectImportedThreads(failure(targets.length === 0
171
+ ? "session import returned no task ID"
172
+ : "session import returned more than one task ID"), targets);
173
+ continue;
174
+ }
175
+ state.threadId = targets[0] ?? null;
176
+ write({
177
+ id: 3,
178
+ method: "thread/read",
179
+ params: { threadId: state.threadId, includeTurns: true },
180
+ });
181
+ continue;
182
+ }
183
+ if (typeof message.id !== "number")
184
+ continue;
185
+ if (message.error) {
186
+ const reported = typeof message.error.message === "string"
187
+ ? message.error.message
188
+ : "unknown app-server error";
189
+ const importedError = failure(reported);
190
+ if (message.id >= 3 && state.threadId) {
191
+ if (message.id === 6 && state.pendingError)
192
+ finish(err(state.pendingError), true);
193
+ else
194
+ rejectImportedThread(importedError);
195
+ }
196
+ else {
197
+ finish(err(importedError));
198
+ }
199
+ continue;
200
+ }
201
+ if (message.id === 1) {
202
+ write({ method: "initialized", params: {} });
203
+ write({
204
+ id: 2,
205
+ method: "externalAgentConfig/import",
206
+ params: {
207
+ source: "glen",
208
+ migrationItems: [
209
+ {
210
+ itemType: "SESSIONS",
211
+ description: "Import Glen takeover transcript",
212
+ cwd: input.workspace,
213
+ details: {
214
+ sessions: [
215
+ {
216
+ path: input.sessionPath,
217
+ cwd: input.workspace,
218
+ title: input.name,
219
+ },
220
+ ],
221
+ },
222
+ },
223
+ ],
224
+ },
225
+ });
226
+ continue;
227
+ }
228
+ if (message.id === 2) {
229
+ const importId = message.result?.importId;
230
+ if (typeof importId !== "string" || !importId) {
231
+ finish(err(failure("session import returned no import ID")));
232
+ continue;
233
+ }
234
+ state.importId = importId;
235
+ continue;
236
+ }
237
+ if (message.id === 3 && state.threadId) {
238
+ const importedMessages = visibleMessages(message.result);
239
+ if (JSON.stringify(importedMessages) !== JSON.stringify(input.messages)) {
240
+ rejectImportedThread(failure("imported task did not expose the canonical visible turns"));
241
+ continue;
242
+ }
243
+ write({
244
+ id: 4,
245
+ method: "thread/resume",
246
+ params: { threadId: state.threadId },
247
+ });
248
+ continue;
249
+ }
250
+ if (message.id === 4 && state.threadId) {
251
+ write({
252
+ id: 5,
253
+ method: "thread/inject_items",
254
+ params: {
255
+ threadId: state.threadId,
256
+ items: [input.provenanceItem],
257
+ },
258
+ });
259
+ continue;
260
+ }
261
+ if (message.id === 5 && state.threadId) {
262
+ if (input.name) {
263
+ write({
264
+ id: 7,
265
+ method: "thread/name/set",
266
+ params: { threadId: state.threadId, name: input.name },
267
+ });
268
+ }
269
+ else {
270
+ finish(ok(state.threadId));
271
+ }
272
+ }
273
+ if (message.id === 6 && state.pendingError) {
274
+ state.archiveQueue = state.archiveQueue.slice(1);
275
+ archiveNext();
276
+ }
277
+ if (message.id === 7 && state.threadId)
278
+ finish(ok(state.threadId));
279
+ }
280
+ });
281
+ queueMicrotask(() => {
282
+ write({
283
+ id: 1,
284
+ method: "initialize",
285
+ params: {
286
+ clientInfo: { name: "glen", title: "Glen CLI", version: cliVersion },
287
+ capabilities: { experimentalApi: true },
288
+ },
289
+ });
290
+ });
291
+ });
292
+ export { importCodexDesktopThread };
293
+ //# sourceMappingURL=import-codex-desktop-thread.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-codex-desktop-thread.js","sourceRoot":"","sources":["../../../../src/commands/takeover/_utils/import-codex-desktop-thread.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { cliErr } from "../../../_utils/cli-error.js";
2
+ import { type Result } from "../../../_utils/result.js";
3
+ declare const launchDesktopUrl: (url: string, platform?: NodeJS.Platform) => Result<void, ReturnType<typeof cliErr>>;
4
+ export { launchDesktopUrl };
@@ -0,0 +1,40 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { causeOf, cliErr } from "../../../_utils/cli-error.js";
3
+ import { err, ok } from "../../../_utils/result.js";
4
+ const launchDesktopUrl = (url, platform = process.platform) => {
5
+ const parsed = (() => {
6
+ try {
7
+ return new URL(url);
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ })();
13
+ if (!parsed ||
14
+ (parsed.protocol !== "claude:" && parsed.protocol !== "codex:"))
15
+ return err(cliErr({
16
+ what: "refused to open an unsupported desktop URL",
17
+ why: url,
18
+ remedy: "update Glen, then retry the takeover",
19
+ }));
20
+ const command = platform === "darwin"
21
+ ? { binary: "open", args: [url] }
22
+ : platform === "win32"
23
+ ? {
24
+ binary: "cmd.exe",
25
+ args: ["/d", "/s", "/c", "start", "", url],
26
+ }
27
+ : { binary: "xdg-open", args: [url] };
28
+ const launched = spawnSync(command.binary, command.args, { stdio: "ignore" });
29
+ if (launched.error || launched.status !== 0)
30
+ return err(cliErr({
31
+ what: "the Desktop session was created but its app did not open",
32
+ why: launched.error
33
+ ? causeOf(launched.error)
34
+ : `exit status ${launched.status ?? "unknown"}`,
35
+ remedy: `open this URL manually: ${url}`,
36
+ }));
37
+ return ok(undefined);
38
+ };
39
+ export { launchDesktopUrl };
40
+ //# sourceMappingURL=launch-desktop-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launch-desktop-url.js","sourceRoot":"","sources":["../../../../src/commands/takeover/_utils/launch-desktop-url.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAe,GAAG,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,gBAAgB,GAAG,CACvB,GAAW,EACX,WAA4B,OAAO,CAAC,QAAQ,EACH,EAAE;IAC3C,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC;YACH,OAAO,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,IACE,CAAC,MAAM;QACP,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAC;QAE/D,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,4CAA4C;YAClD,GAAG,EAAE,GAAG;YACR,MAAM,EAAE,sCAAsC;SAC/C,CAAC,CACH,CAAC;IAEJ,MAAM,OAAO,GACX,QAAQ,KAAK,QAAQ;QACnB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE;QACjC,CAAC,CAAC,QAAQ,KAAK,OAAO;YACpB,CAAC,CAAC;gBACE,MAAM,EAAE,SAAS;gBACjB,IAAI,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC;aAC3C;YACH,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC;IAC5C,MAAM,QAAQ,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC9E,IAAI,QAAQ,CAAC,KAAK,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QACzC,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,0DAA0D;YAChE,GAAG,EAAE,QAAQ,CAAC,KAAK;gBACjB,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACzB,CAAC,CAAC,eAAe,QAAQ,CAAC,MAAM,IAAI,SAAS,EAAE;YACjD,MAAM,EAAE,2BAA2B,GAAG,EAAE;SACzC,CAAC,CACH,CAAC;IACJ,OAAO,EAAE,CAAC,SAAS,CAAC,CAAC;AACvB,CAAC,CAAC;AAEF,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type CliError } from "../../../_utils/cli-error.js";
2
+ import { type Result } from "../../../_utils/result.js";
3
+ declare const nativeFile: {
4
+ stage(prefix: string, lines: readonly Record<string, unknown>[]): Promise<Result<{
5
+ path: string;
6
+ recoveryCommand: string;
7
+ }, CliError>>;
8
+ install(stagedPath: string, targetPath: string, recoveryCommand: string): Promise<Result<{
9
+ recoveryCommand: string;
10
+ }, CliError>>;
11
+ cleanup(stagedPath: string): Promise<void>;
12
+ launch(binary: string, args: readonly string[], workspace: string): Result<void, CliError>;
13
+ };
14
+ export { nativeFile };
@@ -0,0 +1,105 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { constants } from "node:fs";
3
+ import { copyFile, link, mkdir, mkdtemp, readFile, rm, writeFile, } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import { basename, dirname, join } from "node:path";
6
+ import { causeOf, cliErr } from "../../../_utils/cli-error.js";
7
+ import { err, fromPromise, ok } from "../../../_utils/result.js";
8
+ const nativeFile = {
9
+ async stage(prefix, lines) {
10
+ const directory = await fromPromise(mkdtemp(join(tmpdir(), prefix)));
11
+ if (!directory.ok)
12
+ return err(cliErr({
13
+ what: "could not create a private takeover staging directory",
14
+ why: causeOf(directory.error),
15
+ remedy: "check temporary-directory permissions, then retry",
16
+ }));
17
+ const path = join(directory.value, "session.jsonl");
18
+ const written = await fromPromise(writeFile(path, `${lines.map((line) => JSON.stringify(line)).join("\n")}\n`, {
19
+ mode: 0o600,
20
+ flag: "wx",
21
+ }));
22
+ if (!written.ok) {
23
+ await rm(directory.value, { recursive: true, force: true });
24
+ return err(cliErr({
25
+ what: "could not stage the native takeover session",
26
+ why: causeOf(written.error),
27
+ path,
28
+ remedy: "check disk space and temporary-directory permissions, then retry",
29
+ }));
30
+ }
31
+ return ok({ path, recoveryCommand: "" });
32
+ },
33
+ async install(stagedPath, targetPath, recoveryCommand) {
34
+ const staged = await fromPromise(readFile(stagedPath));
35
+ if (!staged.ok)
36
+ return err(cliErr({
37
+ what: "could not read the verified staged session",
38
+ why: causeOf(staged.error),
39
+ path: stagedPath,
40
+ remedy: "retry the takeover command",
41
+ }));
42
+ const existing = await fromPromise(readFile(targetPath));
43
+ if (existing.ok) {
44
+ if (existing.value.equals(staged.value))
45
+ return ok({ recoveryCommand });
46
+ return err(cliErr({
47
+ what: "the destination session ID already exists with different content",
48
+ path: targetPath,
49
+ remedy: "ask the sender for a new takeover command; nothing was overwritten",
50
+ }));
51
+ }
52
+ const made = await fromPromise(mkdir(dirname(targetPath), { recursive: true, mode: 0o700 }));
53
+ if (!made.ok)
54
+ return err(cliErr({
55
+ what: "could not create the target agent session directory",
56
+ why: causeOf(made.error),
57
+ path: dirname(targetPath),
58
+ remedy: "check directory permissions, then retry",
59
+ }));
60
+ const temporary = join(dirname(targetPath), `.${basename(targetPath)}.${process.pid}.tmp`);
61
+ const copied = await fromPromise(copyFile(stagedPath, temporary, constants.COPYFILE_EXCL));
62
+ if (!copied.ok)
63
+ return err(cliErr({
64
+ what: "could not copy the verified session into the target store",
65
+ why: causeOf(copied.error),
66
+ path: temporary,
67
+ remedy: "remove the reported temporary file if present, then retry",
68
+ }));
69
+ const linked = await fromPromise(link(temporary, targetPath));
70
+ await rm(temporary, { force: true });
71
+ if (!linked.ok) {
72
+ const raced = await fromPromise(readFile(targetPath));
73
+ if (raced.ok && raced.value.equals(staged.value))
74
+ return ok({ recoveryCommand });
75
+ return err(cliErr({
76
+ what: "could not atomically install the native session",
77
+ why: causeOf(linked.error),
78
+ path: targetPath,
79
+ remedy: "ask the sender for a new takeover command if that destination now exists; nothing was overwritten",
80
+ }));
81
+ }
82
+ return ok({ recoveryCommand });
83
+ },
84
+ async cleanup(stagedPath) {
85
+ await rm(dirname(stagedPath), { recursive: true, force: true });
86
+ },
87
+ launch(binary, args, workspace) {
88
+ const launched = spawnSync(binary, [...args], {
89
+ cwd: workspace,
90
+ stdio: "inherit",
91
+ });
92
+ if (launched.error || launched.status !== 0)
93
+ return err(cliErr({
94
+ what: "the target agent process exited before continuing the session",
95
+ why: launched.error
96
+ ? causeOf(launched.error)
97
+ : `exit status ${launched.status ?? "unknown"}`,
98
+ path: binary,
99
+ remedy: "launch the installed session manually",
100
+ }));
101
+ return ok(undefined);
102
+ },
103
+ };
104
+ export { nativeFile };
105
+ //# sourceMappingURL=native-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-file.js","sourceRoot":"","sources":["../../../../src/commands/takeover/_utils/native-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type CliError } from "../../../_utils/cli-error.js";
2
+ import { type Result } from "../../../_utils/result.js";
3
+ declare const probeAgent: (input: {
4
+ readonly displayName: string;
5
+ readonly binName: string;
6
+ readonly binaryOverride?: string;
7
+ readonly versionPattern: RegExp;
8
+ readonly model: string;
9
+ readonly contextWindowTokens: number;
10
+ readonly startupReserveTokens: number;
11
+ readonly responseReserveTokens: number;
12
+ }) => Result<{
13
+ binary: string;
14
+ model: string;
15
+ version: string;
16
+ contextWindowTokens: number;
17
+ startupReserveTokens: number;
18
+ responseReserveTokens: number;
19
+ }, CliError>;
20
+ export { probeAgent };
@@ -0,0 +1,37 @@
1
+ import { cliErr } from "../../../_utils/cli-error.js";
2
+ import { findBin } from "../../../_utils/find-bin.js";
3
+ import { err, ok } from "../../../_utils/result.js";
4
+ import { runBin } from "../../../_utils/run-bin.js";
5
+ const probeAgent = (input) => {
6
+ const binary = input.binaryOverride ?? findBin(input.binName);
7
+ if (!binary)
8
+ return err(cliErr({
9
+ what: `${input.displayName} is not installed or discoverable`,
10
+ remedy: `install ${input.displayName}, then run \`glen install --agent ${input.binName}\` and retry`,
11
+ }));
12
+ const version = runBin(binary, ["--version"], { timeoutMs: 5000 });
13
+ if (!version.ok)
14
+ return err(cliErr({
15
+ what: `could not verify the installed ${input.displayName} version`,
16
+ why: version.error.spawnError ?? version.error.stderrTail,
17
+ path: binary,
18
+ remedy: `confirm \`${input.binName} --version\` works, then retry`,
19
+ }));
20
+ const normalized = version.value.stdout.trim();
21
+ if (!input.versionPattern.test(normalized))
22
+ return err(cliErr({
23
+ what: `this ${input.displayName} version is not supported for transcript takeover`,
24
+ why: normalized || "the version command returned no version",
25
+ remedy: "update Glen and the target agent; no native session was written",
26
+ }));
27
+ return ok({
28
+ binary,
29
+ model: input.model,
30
+ version: normalized,
31
+ contextWindowTokens: input.contextWindowTokens,
32
+ startupReserveTokens: input.startupReserveTokens,
33
+ responseReserveTokens: input.responseReserveTokens,
34
+ });
35
+ };
36
+ export { probeAgent };
37
+ //# sourceMappingURL=probe-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe-agent.js","sourceRoot":"","sources":["../../../../src/commands/takeover/_utils/probe-agent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AACtD,OAAO,EAAe,GAAG,EAAE,EAAE,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAEpD,MAAM,UAAU,GAAG,CAAC,KASnB,EAUC,EAAE;IACF,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,IAAI,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9D,IAAI,CAAC,MAAM;QACT,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,GAAG,KAAK,CAAC,WAAW,mCAAmC;YAC7D,MAAM,EAAE,WAAW,KAAK,CAAC,WAAW,qCAAqC,KAAK,CAAC,OAAO,cAAc;SACrG,CAAC,CACH,CAAC;IACJ,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACnE,IAAI,CAAC,OAAO,CAAC,EAAE;QACb,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,kCAAkC,KAAK,CAAC,WAAW,UAAU;YACnE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU;YACzD,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,aAAa,KAAK,CAAC,OAAO,gCAAgC;SACnE,CAAC,CACH,CAAC;IACJ,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAC/C,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC;QACxC,OAAO,GAAG,CACR,MAAM,CAAC;YACL,IAAI,EAAE,QAAQ,KAAK,CAAC,WAAW,mDAAmD;YAClF,GAAG,EAAE,UAAU,IAAI,yCAAyC;YAC5D,MAAM,EACJ,iEAAiE;SACpE,CAAC,CACH,CAAC;IACJ,OAAO,EAAE,CAAC;QACR,MAAM;QACN,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,UAAU;QACnB,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;QAC9C,oBAAoB,EAAE,KAAK,CAAC,oBAAoB;QAChD,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;KACnD,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ declare const provenanceContext: (input: {
2
+ readonly sourceTitle: string | null;
3
+ readonly sourceOwner: string | null;
4
+ readonly sourceAgent: string | null;
5
+ readonly sourceEntityId: string;
6
+ }) => string;
7
+ export { provenanceContext };
@@ -0,0 +1,12 @@
1
+ const provenanceContext = (input) => [
2
+ "This is a fresh, non-destructive Glen transcript handoff.",
3
+ input.sourceTitle ? `Source: ${input.sourceTitle}.` : null,
4
+ input.sourceOwner ? `Shared by: ${input.sourceOwner}.` : null,
5
+ input.sourceAgent ? `Original agent: ${input.sourceAgent}.` : null,
6
+ `Source transcript ID: ${input.sourceEntityId}.`,
7
+ "Continue from the imported history; the original session remains unchanged.",
8
+ ]
9
+ .filter((part) => part !== null)
10
+ .join(" ");
11
+ export { provenanceContext };
12
+ //# sourceMappingURL=provenance-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provenance-context.js","sourceRoot":"","sources":["../../../../src/commands/takeover/_utils/provenance-context.ts"],"names":[],"mappings":"AAAA,MAAM,iBAAiB,GAAG,CAAC,KAK1B,EAAU,EAAE,CACX;IACE,2DAA2D;IAC3D,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI;IAC1D,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI;IAC7D,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,mBAAmB,KAAK,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,IAAI;IAClE,yBAAyB,KAAK,CAAC,cAAc,GAAG;IAChD,6EAA6E;CAC9E;KACE,MAAM,CAAC,CAAC,IAAI,EAAkB,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;KAC/C,IAAI,CAAC,GAAG,CAAC,CAAC;AAEf,OAAO,EAAE,iBAAiB,EAAE,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { type CliError } from "../../../_utils/cli-error.js";
2
+ import { type Result } from "../../../_utils/result.js";
3
+ type Adapter = {
4
+ probe: () => Promise<Result<{
5
+ model: string;
6
+ version: string;
7
+ contextWindowTokens: number;
8
+ startupReserveTokens: number;
9
+ responseReserveTokens: number;
10
+ }, CliError>>;
11
+ stage: () => Promise<Result<{
12
+ path: string;
13
+ recoveryCommand: string;
14
+ }, CliError>>;
15
+ parse: (staged: {
16
+ path: string;
17
+ recoveryCommand: string;
18
+ }) => Promise<Result<readonly {
19
+ role: string;
20
+ content: string;
21
+ }[], CliError>>;
22
+ install: (staged: {
23
+ path: string;
24
+ recoveryCommand: string;
25
+ }) => Promise<Result<{
26
+ recoveryCommand: string;
27
+ destinationSessionId?: string;
28
+ }, CliError>>;
29
+ launch: (installed: {
30
+ recoveryCommand: string;
31
+ destinationSessionId?: string;
32
+ }) => Promise<Result<void, CliError>>;
33
+ cleanup: (staged: {
34
+ path: string;
35
+ recoveryCommand: string;
36
+ }) => Promise<void>;
37
+ recover?: () => Promise<Result<{
38
+ recoveryCommand: string;
39
+ destinationSessionId?: string;
40
+ } | null, CliError>>;
41
+ settleRecovery?: (destinationSessionId: string) => Promise<Result<void, CliError>>;
42
+ rollback?: (installed: {
43
+ recoveryCommand: string;
44
+ destinationSessionId?: string;
45
+ }) => Promise<Result<void, CliError>>;
46
+ };
47
+ declare const stagedSession: {
48
+ forTarget(_target: "claude-code" | "claude-code-cli" | "claude-code-desktop" | "codex" | "codex-cli" | "codex-desktop" | "cursor" | "pi", _payload: {
49
+ takeoverId: string;
50
+ canonicalDigest: string;
51
+ destinationSessionId: string;
52
+ messages: readonly {
53
+ role: "user" | "assistant";
54
+ content: string;
55
+ }[];
56
+ provenance: {
57
+ sourceEntityId: string;
58
+ sourceTitle: string | null;
59
+ sourceOwner: string | null;
60
+ sourceAgent: string | null;
61
+ };
62
+ }, _workspace: string): Promise<Result<Adapter, CliError>>;
63
+ };
64
+ export { stagedSession };