litmus-cli 1.5.0-beta.1 → 1.5.0-beta.2

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 (80) hide show
  1. package/README.md +19 -2
  2. package/dist/commands/connect.d.ts +2 -0
  3. package/dist/commands/connect.d.ts.map +1 -1
  4. package/dist/commands/connect.js +1 -1
  5. package/dist/commands/connect.js.map +1 -1
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +25 -6
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/index.js +10 -232
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/ai-tracking.d.ts +4 -0
  12. package/dist/lib/ai-tracking.d.ts.map +1 -1
  13. package/dist/lib/ai-tracking.js +68 -0
  14. package/dist/lib/ai-tracking.js.map +1 -1
  15. package/dist/lib/api.d.ts +1 -0
  16. package/dist/lib/api.d.ts.map +1 -1
  17. package/dist/lib/api.js +13 -4
  18. package/dist/lib/api.js.map +1 -1
  19. package/dist/lib/capture-notice-ping.d.ts +7 -27
  20. package/dist/lib/capture-notice-ping.d.ts.map +1 -1
  21. package/dist/lib/capture-notice-ping.js +10 -42
  22. package/dist/lib/capture-notice-ping.js.map +1 -1
  23. package/dist/lib/capture-nudge.d.ts +5 -7
  24. package/dist/lib/capture-nudge.d.ts.map +1 -1
  25. package/dist/lib/capture-nudge.js +19 -35
  26. package/dist/lib/capture-nudge.js.map +1 -1
  27. package/dist/lib/capture-selftest.d.ts +9 -0
  28. package/dist/lib/capture-selftest.d.ts.map +1 -1
  29. package/dist/lib/capture-selftest.js +27 -2
  30. package/dist/lib/capture-selftest.js.map +1 -1
  31. package/dist/lib/codex-capture-health.d.ts +21 -0
  32. package/dist/lib/codex-capture-health.d.ts.map +1 -0
  33. package/dist/lib/codex-capture-health.js +82 -0
  34. package/dist/lib/codex-capture-health.js.map +1 -0
  35. package/dist/lib/environment-checks.d.ts +1 -3
  36. package/dist/lib/environment-checks.d.ts.map +1 -1
  37. package/dist/lib/environment-checks.js +2 -16
  38. package/dist/lib/environment-checks.js.map +1 -1
  39. package/dist/lib/file-monitor.d.ts +18 -0
  40. package/dist/lib/file-monitor.d.ts.map +1 -0
  41. package/dist/lib/file-monitor.js +87 -0
  42. package/dist/lib/file-monitor.js.map +1 -0
  43. package/dist/lib/hook-logger.cjs +47 -10
  44. package/dist/lib/hosted-capture.d.ts +4 -2
  45. package/dist/lib/hosted-capture.d.ts.map +1 -1
  46. package/dist/lib/hosted-capture.js +74 -16
  47. package/dist/lib/hosted-capture.js.map +1 -1
  48. package/dist/lib/init-location.d.ts +4 -0
  49. package/dist/lib/init-location.d.ts.map +1 -0
  50. package/dist/lib/init-location.js +36 -0
  51. package/dist/lib/init-location.js.map +1 -0
  52. package/dist/lib/mac-notifier.d.ts +4 -0
  53. package/dist/lib/mac-notifier.d.ts.map +1 -0
  54. package/dist/lib/mac-notifier.js +72 -0
  55. package/dist/lib/mac-notifier.js.map +1 -0
  56. package/dist/lib/node-version.d.ts +8 -0
  57. package/dist/lib/node-version.d.ts.map +1 -0
  58. package/dist/lib/node-version.js +23 -0
  59. package/dist/lib/node-version.js.map +1 -0
  60. package/dist/lib/notify.d.ts +4 -5
  61. package/dist/lib/notify.d.ts.map +1 -1
  62. package/dist/lib/notify.js +24 -25
  63. package/dist/lib/notify.js.map +1 -1
  64. package/dist/lib/portal-launcher.d.ts.map +1 -1
  65. package/dist/lib/portal-launcher.js +6 -1
  66. package/dist/lib/portal-launcher.js.map +1 -1
  67. package/dist/lib/tracker.d.ts +1 -0
  68. package/dist/lib/tracker.d.ts.map +1 -1
  69. package/dist/lib/tracker.js +4 -2
  70. package/dist/lib/tracker.js.map +1 -1
  71. package/dist/lib/watcher.js +147 -101
  72. package/dist/lib/watcher.js.map +1 -1
  73. package/dist/notification-assets/litmus.icns +0 -0
  74. package/dist/notification-assets/litmus.png +0 -0
  75. package/dist/notification-assets/notifier.js +12 -0
  76. package/dist/program.d.ts +2 -0
  77. package/dist/program.d.ts.map +1 -0
  78. package/dist/program.js +236 -0
  79. package/dist/program.js.map +1 -0
  80. package/package.json +5 -5
@@ -0,0 +1,82 @@
1
+ import fs from "fs/promises";
2
+ import os from "os";
3
+ import path from "path";
4
+ export const CODEX_CAPTURE_STATUS = "codex-capture-status.json";
5
+ /** Metadata only. This is an unscoped store inventory, NOT evidence that a
6
+ * prompt belongs to this assessment. Never read transcript contents here. */
7
+ export async function codexStoreInventory(root = process.env.CODEX_HOME?.trim() || path.join(os.homedir(), ".codex")) {
8
+ let visited = 0;
9
+ let rolloutFound = false;
10
+ let incomplete = false;
11
+ let unreadable = false;
12
+ async function visit(dir, depth) {
13
+ if (visited >= 256) {
14
+ incomplete = true;
15
+ return;
16
+ }
17
+ let handle;
18
+ try {
19
+ handle = await fs.opendir(dir);
20
+ for await (const entry of handle) {
21
+ if (++visited > 256) {
22
+ incomplete = true;
23
+ break;
24
+ }
25
+ if (entry.isFile() && /^rollout-.+\.jsonl(?:\.zst)?$/.test(entry.name))
26
+ rolloutFound = true;
27
+ if (entry.isDirectory()) {
28
+ if (depth < 4)
29
+ await visit(path.join(dir, entry.name), depth + 1);
30
+ else
31
+ incomplete = true;
32
+ }
33
+ }
34
+ }
35
+ catch (error) {
36
+ if (error.code !== "ENOENT")
37
+ unreadable = true;
38
+ }
39
+ }
40
+ await visit(path.join(root, "sessions"), 0);
41
+ await visit(path.join(root, "archived_sessions"), 0);
42
+ return { scope: "unscoped_user_store", rolloutFound, incomplete, unreadable };
43
+ }
44
+ /** The hook writes only its latest outcome. Treat the sidecar as untrusted:
45
+ * allowlist every field before sending it through the watcher outbox. */
46
+ export async function readCodexDelivery(litmusDir, sinceMs) {
47
+ try {
48
+ const file = path.join(litmusDir, CODEX_CAPTURE_STATUS);
49
+ const handle = await fs.open(file, "r");
50
+ let raw;
51
+ try {
52
+ if ((await handle.stat()).size > 1024)
53
+ return null;
54
+ const buffer = Buffer.alloc(1024);
55
+ const { bytesRead } = await handle.read(buffer, 0, buffer.length, 0);
56
+ raw = buffer.subarray(0, bytesRead).toString("utf8");
57
+ }
58
+ finally {
59
+ await handle.close();
60
+ }
61
+ const value = JSON.parse(raw);
62
+ if (typeof value.ts !== "string" || !Number.isFinite(Date.parse(value.ts)) || Date.parse(value.ts) < sinceMs || Date.parse(value.ts) > Date.now() + 60000)
63
+ return null;
64
+ if (!["ai_prompt", "ai_response"].includes(value.eventType) || typeof value.localAppend !== "boolean")
65
+ return null;
66
+ if (!["delivered", "http_error", "transport_error", "response_error", "response_aborted", "timeout", "configuration_missing", "invalid_url"].includes(value.outcome))
67
+ return null;
68
+ return {
69
+ ts: new Date(Date.parse(value.ts)).toISOString(),
70
+ eventType: value.eventType,
71
+ localAppend: value.localAppend,
72
+ outcome: value.outcome,
73
+ status: Number.isInteger(value.status) && value.status >= 100 && value.status <= 599 ? value.status : null,
74
+ code: ["ENOTFOUND", "EAI_AGAIN", "ECONNREFUSED", "ECONNRESET", "ETIMEDOUT", "CERT_HAS_EXPIRED", "UNABLE_TO_VERIFY_LEAF_SIGNATURE", "ERR_TLS_CERT_ALTNAME_INVALID"].includes(value.code) ? value.code : null,
75
+ elapsedMs: Number.isFinite(value.elapsedMs) && value.elapsedMs >= 0 && value.elapsedMs <= 60000 ? value.elapsedMs : null,
76
+ };
77
+ }
78
+ catch {
79
+ return null;
80
+ }
81
+ }
82
+ //# sourceMappingURL=codex-capture-health.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex-capture-health.js","sourceRoot":"","sources":["../../src/lib/codex-capture-health.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { rmSync } from "fs";
2
+ export { NODE_MIN_VERSION, checkNodeVersion } from "./node-version.js";
2
3
  /**
3
4
  * Environment checks shared by `litmus setup-check` (pre-init, ENG-2300) and
4
5
  * `litmus doctor` (post-init repair, ENG-1446).
@@ -37,12 +38,9 @@ export interface EnvironmentCheck {
37
38
  /** Internals shown with --verbose. */
38
39
  verbose?: string;
39
40
  }
40
- /** The `engines.node` floor in package.json; pinned to it by test. */
41
- export declare const NODE_MIN_VERSION = "20.19.0";
42
41
  export declare const REINSTALL_COMMAND = "npm install -g litmus-cli@latest";
43
42
  /** Registry document for the `latest` dist-tag. */
44
43
  export declare const NPM_LATEST_URL = "https://registry.npmjs.org/litmus-cli/latest";
45
- export declare function checkNodeVersion(version?: string): EnvironmentCheck;
46
44
  /**
47
45
  * Numeric compare of dotted versions; prerelease suffixes are ignored, so
48
46
  * `1.4.25-beta` compares as `1.4.25`. Returns <0 when a is behind b.
@@ -1 +1 @@
1
- {"version":3,"file":"environment-checks.d.ts","sourceRoot":"","sources":["../../src/lib/environment-checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,MAAM,EAAiB,MAAM,IAAI,CAAA;AAOhF;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,sBAAsB,CAAA;IAC9B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,YAAY,CAAA;AAEzC,eAAO,MAAM,iBAAiB,qCAAqC,CAAA;AAEnE,mDAAmD;AACnD,eAAO,MAAM,cAAc,iDAAiD,CAAA;AAS5E,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,MAAwB,GAAG,gBAAgB,CAYpF;AAID;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAAA;AAE5I,wBAAsB,cAAc,CAAC,SAAS,GAAE,SAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlF;AAED,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAC/B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+BjC;AAID;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwB5B;AAID,wBAAgB,QAAQ,CAAC,IAAI,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAgF,GAAG,gBAAgB,CAclJ;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACZ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkEjC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,MAAM,CAAA;CAAO,GAC5G,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,eAAe,GAAG,UAAU,CAAA;CAAE,CAAC,CA2CtG;AAID;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC1C,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAS9B"}
1
+ {"version":3,"file":"environment-checks.d.ts","sourceRoot":"","sources":["../../src/lib/environment-checks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,MAAM,EAAiB,MAAM,IAAI,CAAA;AAOhF,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,MAAM,GAAG,MAAM,CAAA;AAE3D,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,sBAAsB,CAAA;IAC9B,oEAAoE;IACpE,MAAM,EAAE,MAAM,CAAA;IACd,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,iBAAiB,qCAAqC,CAAA;AAEnE,mDAAmD;AACnD,eAAO,MAAM,cAAc,iDAAiD,CAAA;AAS5E;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED,MAAM,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAAK,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,CAAA;CAAE,CAAC,CAAA;AAE5I,wBAAsB,cAAc,CAAC,SAAS,GAAE,SAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAMlF;AAED,wBAAsB,eAAe,CAAC,IAAI,GAAE;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAA;CAC/B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA+BjC;AAID;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAwB5B;AAID,wBAAgB,QAAQ,CAAC,IAAI,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAgF,GAAG,gBAAgB,CAclJ;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,GAAE;IAC3C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;CACZ,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkEjC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,MAAM,CAAA;CAAO,GAC5G,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,UAAU,GAAG,SAAS,GAAG,SAAS,GAAG,eAAe,GAAG,UAAU,CAAA;CAAE,CAAC,CA2CtG;AAID;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;CAC1C,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAS9B"}
@@ -4,8 +4,8 @@ import path from "path";
4
4
  import { execSync } from "child_process";
5
5
  import { CLI_VERSION } from "./version.js";
6
6
  import { startTracker, trackerDiagnostics, waitForTrackerReady } from "./tracker.js";
7
- /** The `engines.node` floor in package.json; pinned to it by test. */
8
- export const NODE_MIN_VERSION = "20.19.0";
7
+ import { checkNodeVersion } from "./node-version.js";
8
+ export { NODE_MIN_VERSION, checkNodeVersion } from "./node-version.js";
9
9
  export const REINSTALL_COMMAND = "npm install -g litmus-cli@latest";
10
10
  /** Registry document for the `latest` dist-tag. */
11
11
  export const NPM_LATEST_URL = "https://registry.npmjs.org/litmus-cli/latest";
@@ -13,20 +13,6 @@ const REGISTRY_TIMEOUT_MS = 5000;
13
13
  const SERVER_TIMEOUT_MS = 8000;
14
14
  /** Above this the connection is reported as slow. Still `ok`: slowness is not a fix the candidate can apply. */
15
15
  const SERVER_SLOW_MS = 3000;
16
- // ── Node ─────────────────────────────────────────────────────────────
17
- export function checkNodeVersion(version = process.version) {
18
- if (!/^v?\d+(?:\.\d+){0,2}(?:[-+].*)?$/.test(version.trim())) {
19
- return { name: "node", status: "warn", detail: `Node.js: version could not be read (${version})` };
20
- }
21
- if (compareVersions(version, NODE_MIN_VERSION) < 0) {
22
- return {
23
- name: "node",
24
- status: "fail",
25
- detail: `Node.js: ${version} is too old. Update to Node.js ${NODE_MIN_VERSION} or newer, then run "litmus setup-check" again.`,
26
- };
27
- }
28
- return { name: "node", status: "ok", detail: `Node.js: ${version}` };
29
- }
30
16
  // ── CLI version against npm ──────────────────────────────────────────
31
17
  /**
32
18
  * Numeric compare of dotted versions; prerelease suffixes are ignored, so
@@ -1 +1 @@
1
- {"version":3,"file":"environment-checks.js","sourceRoot":"","sources":["../../src/lib/environment-checks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"environment-checks.js","sourceRoot":"","sources":["../../src/lib/environment-checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export declare function fileMonitorPolicy(platform?: NodeJS.Platform, wsl?: boolean): {
2
+ polling: boolean;
3
+ };
4
+ /** A running process is not proof that file changes reach our event handler. */
5
+ export declare function startFileMonitor(options: {
6
+ directory: string;
7
+ ignored: (relative: string) => boolean;
8
+ /** Special signals such as AI artifact dotfiles still reach the caller. */
9
+ observed?: (relative: string) => boolean;
10
+ onEvent: (type: "change" | "rename", relative: string) => void;
11
+ onError: (error: Error) => void;
12
+ polling?: boolean;
13
+ timeoutMs?: number;
14
+ }): {
15
+ ready: Promise<void>;
16
+ close(): Promise<void>;
17
+ };
18
+ //# sourceMappingURL=file-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-monitor.d.ts","sourceRoot":"","sources":["../../src/lib/file-monitor.ts"],"names":[],"mappings":"AAMA,wBAAgB,iBAAiB,CAAC,QAAQ,kBAAmB,EAAE,GAAG,UAAU;IAGjE,OAAO;EACjB;AAED,gFAAgF;AAChF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE;IACxC,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IACtC,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAA;IACxC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9D,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;;;EAmEA"}
@@ -0,0 +1,87 @@
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { randomUUID } from "crypto";
4
+ import { watch } from "chokidar";
5
+ import { isWsl } from "./wsl.js";
6
+ export function fileMonitorPolicy(platform = process.platform, wsl = isWsl()) {
7
+ // WSL can miss Windows-side writes on mounted drives. Poll there too;
8
+ // filtering before discovery keeps dependency trees out of the scan.
9
+ return { polling: platform === "win32" || (platform === "linux" && wsl) };
10
+ }
11
+ /** A running process is not proof that file changes reach our event handler. */
12
+ export function startFileMonitor(options) {
13
+ const excluded = (relative) => options.ignored(relative) && !options.observed?.(relative);
14
+ const probeName = `.litmus-watch-probe-${randomUUID()}`;
15
+ const probePath = path.join(options.directory, probeName);
16
+ let settled = false;
17
+ let closed = false;
18
+ let probeCreated = false;
19
+ let resolveReady;
20
+ let rejectReady;
21
+ const ready = new Promise((resolve, reject) => { resolveReady = resolve; rejectReady = reject; });
22
+ const cleanup = () => fs.promises.unlink(probePath).catch(() => { });
23
+ const fail = (error) => {
24
+ if (closed)
25
+ return;
26
+ if (!settled) {
27
+ settled = true;
28
+ clearTimeout(timer);
29
+ rejectReady(error);
30
+ void cleanup();
31
+ }
32
+ options.onError(error);
33
+ };
34
+ const watcher = watch(options.directory, {
35
+ ignoreInitial: true,
36
+ followSymlinks: false,
37
+ usePolling: options.polling ?? fileMonitorPolicy().polling,
38
+ interval: 500,
39
+ binaryInterval: 1000,
40
+ ignored: (file) => {
41
+ const relative = path.relative(options.directory, file);
42
+ return relative !== "" && relative !== probeName && excluded(relative);
43
+ },
44
+ });
45
+ const timer = setTimeout(() => fail(new Error("File watcher did not observe its startup probe before the deadline")), options.timeoutMs ?? 4000);
46
+ const event = (type, file) => {
47
+ const relative = path.relative(options.directory, file);
48
+ // Never put synthetic probe creation or cleanup in candidate activity.
49
+ if (relative === probeName) {
50
+ if (!settled && probeCreated) {
51
+ settled = true;
52
+ clearTimeout(timer);
53
+ void cleanup().then(resolveReady);
54
+ }
55
+ return;
56
+ }
57
+ if (!closed && !excluded(relative))
58
+ options.onEvent(type, relative);
59
+ };
60
+ watcher.on("add", file => event("rename", file));
61
+ watcher.on("change", file => event("change", file));
62
+ watcher.on("unlink", file => event("rename", file));
63
+ watcher.on("error", error => fail(error instanceof Error ? error : new Error(String(error))));
64
+ watcher.once("ready", () => {
65
+ if (closed || settled)
66
+ return;
67
+ probeCreated = true;
68
+ void fs.promises.writeFile(probePath, "file capture probe\n", { flag: "wx" }).then(() => {
69
+ if (closed || settled)
70
+ void cleanup();
71
+ }, fail);
72
+ });
73
+ return {
74
+ ready,
75
+ async close() {
76
+ closed = true;
77
+ clearTimeout(timer);
78
+ if (!settled) {
79
+ settled = true;
80
+ rejectReady(new Error("File watcher closed before verification"));
81
+ }
82
+ await watcher.close();
83
+ await cleanup();
84
+ },
85
+ };
86
+ }
87
+ //# sourceMappingURL=file-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-monitor.js","sourceRoot":"","sources":["../../src/lib/file-monitor.ts"],"names":[],"mappings":"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"}
@@ -589,13 +589,23 @@ function sessionOverMarked(litmusDir) {
589
589
  * `{ sessionOver }`, true only when the server refused the token for good.
590
590
  */
591
591
  function uploadEvent(config, event) {
592
- if (!config || !config.token || !config.backendUrl) return Promise.resolve({ sessionOver: false })
592
+ const started = Date.now()
593
+ // Probe-only stderr is captured by doctor, never sent for ordinary AI turns.
594
+ const probe = event?.type === "capture_selftest_probe"
595
+ const result = (sessionOver, outcome, status = null, code = null) => {
596
+ const delivery = { outcome, status, code, elapsedMs: Date.now() - started }
597
+ if (probe) process.stderr.write("LITMUS_PROBE_DELIVERY " + JSON.stringify(delivery) + "\n")
598
+ return { sessionOver, delivery }
599
+ }
600
+ const safeCode = error => ["ENOTFOUND", "EAI_AGAIN", "ECONNREFUSED", "ECONNRESET", "ETIMEDOUT", "CERT_HAS_EXPIRED", "UNABLE_TO_VERIFY_LEAF_SIGNATURE", "ERR_TLS_CERT_ALTNAME_INVALID"].includes(error?.code) ? error.code : null
601
+ if (!config || !config.token || !config.backendUrl) return Promise.resolve(result(false, "configuration_missing"))
593
602
 
594
603
  let url
595
604
  try {
596
605
  url = new URL(`${config.backendUrl}/cli/activity`)
606
+ if (!["http:", "https:"].includes(url.protocol)) throw new Error("Unsupported protocol")
597
607
  } catch {
598
- return Promise.resolve({ sessionOver: false }) // malformed backendUrl — nothing to do
608
+ return Promise.resolve(result(false, "invalid_url")) // malformed backendUrl — nothing to do
599
609
  }
600
610
 
601
611
  const body = JSON.stringify({ events: [event] })
@@ -605,11 +615,12 @@ function uploadEvent(config, event) {
605
615
  let settled = false
606
616
  let guard = null
607
617
  let sessionOver = false
608
- const done = () => {
618
+ let status = null
619
+ const done = (outcome = "transport_error", code = null) => {
609
620
  if (settled) return
610
621
  settled = true
611
622
  if (guard) clearTimeout(guard)
612
- resolve({ sessionOver })
623
+ resolve(result(sessionOver, outcome, status, code))
613
624
  }
614
625
 
615
626
  const req = reqFn(url, {
@@ -634,7 +645,7 @@ function uploadEvent(config, event) {
634
645
  // A 4xx body is kept (capped) because it is the only place the server says
635
646
  // the assessment is over for good (ENG-2768, see isFinalRefusal).
636
647
  req.on("response", (res) => {
637
- const status = res.statusCode || 0
648
+ status = res.statusCode || 0
638
649
  const chunks = []
639
650
  let kept = 0
640
651
  res.on("data", (chunk) => {
@@ -645,14 +656,15 @@ function uploadEvent(config, event) {
645
656
  })
646
657
  res.on("end", () => {
647
658
  if (chunks.length) sessionOver = isFinalRefusal(status, Buffer.concat(chunks).toString("utf8"))
648
- done()
659
+ done(status >= 200 && status < 300 ? "delivered" : "http_error")
649
660
  })
650
- res.on("error", done)
661
+ res.on("error", error => done("response_error", safeCode(error)))
662
+ res.on("aborted", () => done("response_aborted"))
651
663
  })
652
- req.on("error", done) // network down, DNS, refused, destroyed
653
- req.on("timeout", () => { req.destroy(); done() })
664
+ req.on("error", error => done("transport_error", safeCode(error))) // network down, DNS, refused, destroyed
665
+ req.on("timeout", () => { req.destroy(); done("timeout") })
654
666
  // Backstop in case none of the above fires (a socket wedged before connect).
655
- guard = setTimeout(() => { try { req.destroy() } catch { /* already gone */ } done() }, UPLOAD_TIMEOUT_MS)
667
+ guard = setTimeout(() => { try { req.destroy() } catch { /* already gone */ } done("timeout") }, UPLOAD_TIMEOUT_MS)
656
668
  req.end(body)
657
669
  })
658
670
  }
@@ -2302,6 +2314,20 @@ async function main() {
2302
2314
  const config = readConfig(litmusDir)
2303
2315
  const upload = await uploadEvent(config, event)
2304
2316
 
2317
+ // ENG-3794: a passing synthetic probe does not prove Codex invoked its
2318
+ // hooks for a real turn. Keep a content-free latest outcome for the watcher
2319
+ // to relay on its independent, retrying outbox. Never spend another request
2320
+ // or print diagnostics into the candidate's AI tool. Hosted capture has its
2321
+ // own supervisor; probes must not masquerade as real tool invocations.
2322
+ if (effectiveTool === "codex" && !selftestNonce && !hostedAtStart) {
2323
+ const statusFile = path.join(litmusDir, "codex-capture-status.json")
2324
+ const temp = statusFile + "." + process.pid + ".tmp"
2325
+ try {
2326
+ fs.writeFileSync(temp, JSON.stringify({ ts: new Date().toISOString(), eventType: event.type, localAppend: logged, ...upload.delivery }), { mode: 0o600 })
2327
+ fs.renameSync(temp, statusFile)
2328
+ } catch { try { fs.unlinkSync(temp) } catch { /* best effort */ } }
2329
+ }
2330
+
2305
2331
  // ENG-2768: the server says this token will never be accepted again. Mark
2306
2332
  // the folder so the next turn stops at the top of main(), and skip the
2307
2333
  // revival below: there is no session left for a watcher to serve.
@@ -2350,6 +2376,17 @@ const CODEX_CONTEXTUAL_PREFIXES = [
2350
2376
  ]
2351
2377
  function isCodexContextualText(text) {
2352
2378
  const trimmed = typeof text === "string" ? text.trimStart().toLowerCase() : ""
2379
+ // Desktop page visibility arrives as a standalone user-role notification.
2380
+ // Match only its metadata envelope: quoted examples and accompanying human
2381
+ // text must remain prompts, not disappear because they mention this tag.
2382
+ const page = /^<external_codex_apps_open_page>\s*([\s\S]*?)\s*<\/external_codex_apps_open_page>\s*$/.exec(trimmed)
2383
+ if (page) {
2384
+ try {
2385
+ const value = JSON.parse(page[1])
2386
+ if (value && Object.keys(value).length === 1 && Object.prototype.hasOwnProperty.call(value, "page_id")
2387
+ && (value.page_id === null || typeof value.page_id === "string")) return true
2388
+ } catch { /* malformed or human-authored examples are preserved */ }
2389
+ }
2353
2390
  return CODEX_CONTEXTUAL_PREFIXES.some(prefix => trimmed.startsWith(prefix.toLowerCase()))
2354
2391
  }
2355
2392
  // Python's ingest filter budgets JSON with ensure_ascii=True. Bound the same
@@ -2,6 +2,8 @@ import type { InitMetadata } from "./schemas.js";
2
2
  export declare const HOSTED_CAPTURE_DISCLOSURE_VERSION = "hosted_local_v2";
3
3
  export declare const HOSTED_CAPTURE_DISCLOSURE = "During this assessment, Litmus records prompts, responses, tool calls and their results from supported AI tools across this computer, including outside this workspace. The hiring company can review them alongside workspace activity. Capture ends with the coding session or pauses within ten seconds if offline. Browser AI and Copilot are not captured. Restart open AI tools to load capture hooks.";
4
4
  export declare const HOSTED_CAPTURE_FILE: string;
5
+ /** Never infer session completion from an ordinary 404 or a network failure. */
6
+ export declare function isRemovedPreviewResponse(backendUrl: string, status: number, body: unknown): boolean;
5
7
  export declare function atomicPrivateJson(file: string, value: unknown): void;
6
8
  export declare function captureLease(backendUrl: string, token: string, accept?: boolean): Promise<{
7
9
  active: boolean;
@@ -19,10 +21,10 @@ export declare function acquireCaptureSetupLock(lock: string, waitMs?: number):
19
21
  /** Reconcile legacy hook registrations before opening a machine-wide window.
20
22
  * No PID inference: a stopped watcher does not mean the assessment ended.
21
23
  */
22
- export declare function reconcileLocalCaptureRegistrations(excluded: string[], localToken?: string): Promise<void>;
24
+ export declare function reconcileLocalCaptureRegistrations(excluded: string[], localToken?: string, forgetPreview?: boolean): Promise<void>;
23
25
  /** Cancel only this newly prepared generation, never a reused/successor window.
24
26
  * No session-over marker: the assessment is still valid and init can retry.
25
27
  */
26
28
  export declare function rollbackPreparedCapture(projectDir: string, setupId: string): Promise<void>;
27
- export declare function startHostedCapture(meta: InitMetadata, token: string, apiBase: string): Promise<(() => Promise<void>) | undefined>;
29
+ export declare function startHostedCapture(meta: InitMetadata, token: string, apiBase: string, forgetPreview?: boolean): Promise<(() => Promise<void>) | undefined>;
28
30
  //# sourceMappingURL=hosted-capture.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hosted-capture.d.ts","sourceRoot":"","sources":["../../src/lib/hosted-capture.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAMhD,eAAO,MAAM,iCAAiC,oBAAoB,CAAA;AAClE,eAAO,MAAM,yBAAyB,iZAAiZ,CAAA;AACvb,eAAO,MAAM,mBAAmB,QAA4D,CAAA;AAC5F,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAKpE;AACD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,CAAC,CAWjM;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CA6B3D;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CAyBpG;AAED;;GAEG;AACH,wBAAsB,kCAAkC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6C/G;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhG;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CA6EvI"}
1
+ {"version":3,"file":"hosted-capture.d.ts","sourceRoot":"","sources":["../../src/lib/hosted-capture.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAMhD,eAAO,MAAM,iCAAiC,oBAAoB,CAAA;AAClE,eAAO,MAAM,yBAAyB,iZAAiZ,CAAA;AACvb,eAAO,MAAM,mBAAmB,QAA4D,CAAA;AAM5F,gFAAgF;AAChF,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAOnG;AAUD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAKpE;AACD,wBAAsB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,OAAO,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAC,CAAC,CAcjM;AACD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,IAAI,CA6B3D;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,CA+BpG;AAED;;GAEG;AACH,wBAAsB,kCAAkC,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDtI;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmBhG;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,UAAQ,GAAG,OAAO,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,SAAS,CAAC,CAqF9J"}
@@ -11,12 +11,42 @@ import { linkSync, unlinkSync, realpathSync } from "fs";
11
11
  import { startTracker, waitForTrackerReady, isTrackerHealthy } from "./tracker.js";
12
12
  import { setupAiTracking } from "../commands/init.js";
13
13
  import { releaseAiTrackingForAssessment, readRegistrySnapshot, pruneOrphanedCaptureRegistrations } from "./ai-tracking.js";
14
- import { retireAiCaptureForEndedSession, sessionOverMarked } from "./session-over.js";
14
+ import { retireAiCaptureForEndedSession, sessionOverMarked, writeSessionOverMarker } from "./session-over.js";
15
15
  import { findShadowConfigForDir } from "./shadow.js";
16
16
  import { prepareHostedTranscripts } from "./hosted-transcripts.js";
17
17
  export const HOSTED_CAPTURE_DISCLOSURE_VERSION = "hosted_local_v2";
18
18
  export const HOSTED_CAPTURE_DISCLOSURE = "During this assessment, Litmus records prompts, responses, tool calls and their results from supported AI tools across this computer, including outside this workspace. The hiring company can review them alongside workspace activity. Capture ends with the coding session or pauses within ten seconds if offline. Browser AI and Copilot are not captured. Restart open AI tools to load capture hooks.";
19
19
  export const HOSTED_CAPTURE_FILE = path.join(os.homedir(), ".litmus", "hosted-capture.json");
20
+ const PREVIEW_RECOVERY_HINT = "A previous preview capture service is unavailable. If that preview was removed, retry the same connect command with --forget-unavailable-preview. This stops its local capture only; it does not submit the previous assessment.";
21
+ class UnavailablePreviewCapture extends Error {
22
+ constructor() { super(PREVIEW_RECOVERY_HINT); }
23
+ }
24
+ /** Never infer session completion from an ordinary 404 or a network failure. */
25
+ export function isRemovedPreviewResponse(backendUrl, status, body) {
26
+ let url;
27
+ try {
28
+ url = new URL(backendUrl);
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ if (url.protocol !== "https:" || url.port || url.username || url.password || url.pathname !== "/"
34
+ || url.search || url.hash || !/^litmus-litmus-pr-\d+\.up\.railway\.app$/.test(url.hostname))
35
+ return false;
36
+ const value = body;
37
+ return status === 404 && value?.status === "error" && value.code === 404 && value.message === "Application not found";
38
+ }
39
+ function forgetUnavailablePreview(projectDir, token) {
40
+ // Explicit recovery is local abandonment, not evidence of server submission.
41
+ if (!writeSessionOverMarker(projectDir, token, "connect: user discarded unavailable preview capture")) {
42
+ throw new Error("Could not stop the previous preview capture. Contact support.");
43
+ }
44
+ try {
45
+ writeFileSync(path.join(projectDir, ".litmus", "shutdown"), String(Date.now()));
46
+ }
47
+ catch { /* folder may be gone */ }
48
+ releaseAiTrackingForAssessment(projectDir);
49
+ }
20
50
  export function atomicPrivateJson(file, value) {
21
51
  mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
22
52
  const temp = `${file}.${randomUUID()}.tmp`;
@@ -34,8 +64,11 @@ export async function captureLease(backendUrl, token, accept = false) {
34
64
  ...(accept ? { body: JSON.stringify({ disclosureVersion: HOSTED_CAPTURE_DISCLOSURE_VERSION }) } : {}),
35
65
  signal: AbortSignal.timeout(4000),
36
66
  });
37
- if (!response.ok)
67
+ if (!response.ok) {
68
+ if (!accept && isRemovedPreviewResponse(backendUrl, response.status, await response.json().catch(() => null)))
69
+ throw new UnavailablePreviewCapture();
38
70
  throw new Error(`Local capture authorization failed (${response.status})`);
71
+ }
39
72
  const value = await response.json();
40
73
  if (typeof value.active !== "boolean" || typeof value.leaseSeconds !== "number" || value.leaseSeconds < 0 || value.leaseSeconds > 10)
41
74
  throw new Error("Invalid capture authorization");
@@ -112,8 +145,14 @@ export async function acquireCaptureSetupLock(lock, waitMs = 0) {
112
145
  break;
113
146
  }
114
147
  catch (error) {
115
- if (error.code !== "EADDRINUSE" || Date.now() >= deadline) {
116
- throw new Error("Capture setup is already running, or its local coordination port is occupied. Retry after the other setup or application closes.");
148
+ const code = error.code;
149
+ if (code !== "EADDRINUSE" || Date.now() >= deadline) {
150
+ // Keep only fixed errno labels: raw bind errors carry the local address.
151
+ const safeCode = ["EADDRINUSE", "EACCES", "EPERM", "EADDRNOTAVAIL", "EAFNOSUPPORT", "EMFILE", "ENFILE"].includes(code ?? "") ? code : undefined;
152
+ const message = code === "EADDRINUSE"
153
+ ? "Capture setup is already running, or its local coordination port is occupied. Retry after the other setup or application closes."
154
+ : "Local capture setup could not open its coordination port. Retry, and contact the company for help if it keeps happening.";
155
+ throw Object.assign(new Error(message), { code: safeCode });
117
156
  }
118
157
  await new Promise(resolve => setTimeout(resolve, Math.min(250, deadline - Date.now())));
119
158
  }
@@ -138,7 +177,7 @@ export async function acquireCaptureSetupLock(lock, waitMs = 0) {
138
177
  /** Reconcile legacy hook registrations before opening a machine-wide window.
139
178
  * No PID inference: a stopped watcher does not mean the assessment ended.
140
179
  */
141
- export async function reconcileLocalCaptureRegistrations(excluded, localToken) {
180
+ export async function reconcileLocalCaptureRegistrations(excluded, localToken, forgetPreview = false) {
142
181
  const blocked = [];
143
182
  let handoffError;
144
183
  for (const dir of readRegistrySnapshot() ?? []) {
@@ -177,6 +216,12 @@ export async function reconcileLocalCaptureRegistrations(excluded, localToken) {
177
216
  redirect: "error", signal: AbortSignal.timeout(4000),
178
217
  });
179
218
  const body = await response.json();
219
+ if (config.captureMode === "hosted-local" && isRemovedPreviewResponse(config.backendUrl, response.status, body)) {
220
+ if (!forgetPreview)
221
+ throw new UnavailablePreviewCapture();
222
+ forgetUnavailablePreview(dir, config.token);
223
+ continue;
224
+ }
180
225
  const ended = (response.status === 403 && body.detail?.error === "Token expired")
181
226
  || (response.status === 404 && body.detail?.error === "Invalid token");
182
227
  if (!ended) {
@@ -198,6 +243,8 @@ export async function reconcileLocalCaptureRegistrations(excluded, localToken) {
198
243
  retireAiCaptureForEndedSession(dir, config.token);
199
244
  }
200
245
  catch (error) {
246
+ if (error instanceof UnavailablePreviewCapture)
247
+ throw error;
201
248
  if (error instanceof ServerError)
202
249
  handoffError ?? (handoffError = error);
203
250
  blocked.push(dir);
@@ -244,14 +291,15 @@ export async function rollbackPreparedCapture(projectDir, setupId) {
244
291
  await release();
245
292
  }
246
293
  }
247
- export async function startHostedCapture(meta, token, apiBase) {
294
+ export async function startHostedCapture(meta, token, apiBase, forgetPreview = false) {
248
295
  const key = createHash("sha256").update(token).digest("hex");
249
296
  const projectDir = hostedCaptureProjectDir(token);
250
297
  // One machine-wide window: never silently mix two candidates' conversations.
251
298
  const lock = `${HOSTED_CAPTURE_FILE}.lock`;
252
299
  mkdirSync(path.dirname(lock), { recursive: true, mode: 0o700 });
253
- // Different editor launches share this setup, but retain independent openers.
254
- const releaseLock = await acquireCaptureSetupLock(lock, meta.launcherBetaEnabled === true ? 30000 : 0);
300
+ // A supervisor renewal or another editor can briefly own this same guard.
301
+ // Stable startup needs the same bounded wait as the launcher; never steal it.
302
+ const releaseLock = await acquireCaptureSetupLock(lock, 30000);
255
303
  try {
256
304
  pruneOrphanedCaptureRegistrations();
257
305
  let prior = {};
@@ -268,17 +316,27 @@ export async function startHostedCapture(meta, token, apiBase) {
268
316
  }
269
317
  if (prior.projectDir && prior.tokenKey !== key) {
270
318
  const oldConfig = JSON.parse(readFileSync(path.join(prior.projectDir, ".litmus", "config.json"), "utf8"));
271
- const oldLease = await captureLease(oldConfig.backendUrl, oldConfig.token);
272
- if (oldLease.active) {
273
- await finishPracticeCapture(oldConfig.backendUrl, oldConfig.token, token);
274
- if ((await captureLease(oldConfig.backendUrl, oldConfig.token)).active)
275
- throw new Error("Practice capture is still active. Retry the same command.");
319
+ let oldLease;
320
+ try {
321
+ oldLease = await captureLease(oldConfig.backendUrl, oldConfig.token);
322
+ }
323
+ catch (error) {
324
+ if (!(error instanceof UnavailablePreviewCapture) || !forgetPreview || oldConfig.captureMode !== "hosted-local")
325
+ throw error;
326
+ forgetUnavailablePreview(prior.projectDir, oldConfig.token);
327
+ }
328
+ if (oldLease) {
329
+ if (oldLease.active) {
330
+ await finishPracticeCapture(oldConfig.backendUrl, oldConfig.token, token);
331
+ if ((await captureLease(oldConfig.backendUrl, oldConfig.token)).active)
332
+ throw new Error("Practice capture is still active. Retry the same command.");
333
+ }
334
+ // Confirmed server closure, not mere lease expiry, permits replacing a window.
335
+ retireAiCaptureForEndedSession(prior.projectDir, oldConfig.token);
276
336
  }
277
- // Confirmed server closure, not mere lease expiry, permits replacing a window.
278
- retireAiCaptureForEndedSession(prior.projectDir, oldConfig.token);
279
337
  rmSync(HOSTED_CAPTURE_FILE, { force: true });
280
338
  }
281
- await reconcileLocalCaptureRegistrations([projectDir, ...(prior.projectDir ? [prior.projectDir] : [])], token);
339
+ await reconcileLocalCaptureRegistrations([projectDir, ...(prior.projectDir ? [prior.projectDir] : [])], token, forgetPreview);
282
340
  if (prior.projectDir === projectDir && isTrackerHealthy(projectDir)) {
283
341
  // A later command has adopted this running window; an earlier failed
284
342
  // preparation no longer owns its rollback.