litmus-cli 1.4.97 → 1.4.98

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.
@@ -1,5 +1,6 @@
1
1
  export declare const NUDGE_TRIGGER_TOOLS: readonly ["codex", "copilot", "claude_code"];
2
2
  export type NudgeTriggerTool = (typeof NUDGE_TRIGGER_TOOLS)[number];
3
+ export type NudgeSetupAction = "approve_codex" | "trust_copilot" | "repair";
3
4
  export declare const NUDGE_STATE_FILE_NAME = "nudge-state.json";
4
5
  export interface NudgeState {
5
6
  /** Consecutive env scans each trigger tool has been present on. */
@@ -17,6 +18,7 @@ export type NudgeAction = {
17
18
  } | {
18
19
  action: "nudge";
19
20
  tool: NudgeTriggerTool;
21
+ setupAction: NudgeSetupAction;
20
22
  }
21
23
  /** Capture just started working — remove the notice file, latch off. */
22
24
  | {
@@ -33,8 +35,9 @@ export type NudgeDecision = NudgeAction & {
33
35
  * @param promptCount ai_prompt + ai_response events captured so far
34
36
  * @param now epoch ms
35
37
  * @param msRemaining ms to the effective deadline, null when none configured
38
+ * @param setupIssues confirmed, actionable faults; absent/unknown stays quiet
36
39
  */
37
- export declare function decideNudge(state: NudgeState, scanTools: string[], promptCount: number, now: number, msRemaining: number | null): NudgeDecision;
40
+ export declare function decideNudge(state: NudgeState, scanTools: string[], promptCount: number, now: number, msRemaining: number | null, setupIssues?: Partial<Record<NudgeTriggerTool, NudgeSetupAction>>): NudgeDecision;
38
41
  /** Tolerant load: anything unreadable or malformed means a fresh state. */
39
42
  export declare function loadNudgeState(projectDir: string): NudgeState;
40
43
  export declare function saveNudgeState(projectDir: string, state: NudgeState): void;
@@ -89,12 +92,7 @@ export declare function removeAiNoticeFile(projectDir: string): boolean;
89
92
  * (zip, status) omit it; a missing file is then simply "not ours".
90
93
  */
91
94
  export declare function isCliNoticeArtifact(projectDir: string, relPath: string, lastKnown?: Map<string, boolean>): boolean;
92
- /**
93
- * @param withDetailsPointer false when the notice file could not be written
94
- * (a candidate-owned file occupies the path) — pointing at a file that
95
- * carries THEIR content would misdirect.
96
- */
97
- export declare function nudgeNotificationCopy(tool: NudgeTriggerTool, withDetailsPointer?: boolean): {
95
+ export declare function nudgeNotificationCopy(action: NudgeSetupAction): {
98
96
  title: string;
99
97
  message: string;
100
98
  };
@@ -1 +1 @@
1
- {"version":3,"file":"capture-nudge.d.ts","sourceRoot":"","sources":["../../src/lib/capture-nudge.ts"],"names":[],"mappings":"AAkCA,eAAO,MAAM,mBAAmB,YAAI,OAAO,EAAE,SAAS,EAAE,aAAa,CAAU,CAAA;AAC/E,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAqBnE,eAAO,MAAM,qBAAqB,qBAAqB,CAAA;AAEvD,MAAM,WAAW,UAAU;IACzB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC,CAAA;IACtD,uDAAuD;IACvD,UAAU,EAAE,MAAM,CAAA;IAClB,iEAAiE;IACjE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,iBAAiB,IAAI,UAAU,CAE9C;AAED,MAAM,MAAM,WAAW,GACnB;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,GAClB;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE;AAC7C,wEAAwE;GACtE;IAAE,MAAM,EAAE,eAAe,CAAA;CAAE,CAAA;AAE/B,MAAM,MAAM,aAAa,GAAG,WAAW,GAAG;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,CAAA;AAE/D;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,KAAK,EAAE,UAAU,EACjB,SAAS,EAAE,MAAM,EAAE,EACnB,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,WAAW,EAAE,MAAM,GAAG,IAAI,GACzB,aAAa,CAmCf;AAQD,2EAA2E;AAC3E,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,CAkB7D;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,IAAI,CAK1E;AASD,MAAM,WAAW,gBAAgB;IAC/B,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,mBAAmB,IAAI,gBAAgB,CAEtD;AAeD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CA8B3F;AAaD,eAAO,MAAM,mBAAmB,wBAAwB,CAAA;AAExD;;;;;oCAKoC;AACpC,eAAO,MAAM,kBAAkB,2FAC2D,CAAA;AAE1F,wBAAgB,eAAe,IAAI,MAAM,CA2BxC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAW7D;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAU9D;AAkBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAcT;AAWD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,gBAAgB,EACtB,kBAAkB,UAAO,GACxB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAiBpC;AAGD,kFAAkF;AAClF,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,GAAG,MAAM,CAQnI"}
1
+ {"version":3,"file":"capture-nudge.d.ts","sourceRoot":"","sources":["../../src/lib/capture-nudge.ts"],"names":[],"mappings":"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"}
@@ -4,11 +4,9 @@ import { assessmentActivityLogs } from "./assessment-activity.js";
4
4
  * (watcher.ts is a spawned script, so logic living there can't be imported
5
5
  * by tests; same split as detection.ts).
6
6
  *
7
- * The signature this exists to catch: a hook-capturable AI tool is running
8
- * but zero prompts have been captured — almost always Codex or the Copilot
9
- * CLI sitting behind their silent trust gates (ENG-951/ENG-1323), i.e. a
10
- * candidate whose AI work is invisibly not being recorded. The nudge is
11
- * CANDIDATE-FACING ONLY: a desktop notification plus a notice file at the
7
+ * A running tool is nudged only when its configuration identifies a concrete
8
+ * setup action. Missing prompts alone are not a setup diagnosis. The nudge is
9
+ * CANDIDATE-FACING ONLY; no new notice file is written at the
12
10
  * assessment root. It emits NO activity event — the grader renders every
13
11
  * non-response activity event verbatim in the judge-visible timeline
14
12
  * (substrate_sections.py) and merges the in-zip activity.jsonl, so anything
@@ -60,8 +58,9 @@ export function initialNudgeState() {
60
58
  * @param promptCount ai_prompt + ai_response events captured so far
61
59
  * @param now epoch ms
62
60
  * @param msRemaining ms to the effective deadline, null when none configured
61
+ * @param setupIssues confirmed, actionable faults; absent/unknown stays quiet
63
62
  */
64
- export function decideNudge(state, scanTools, promptCount, now, msRemaining) {
63
+ export function decideNudge(state, scanTools, promptCount, now, msRemaining, setupIssues = {}) {
65
64
  if (state.latched)
66
65
  return { action: "none", state };
67
66
  // Capture confirmed: latch off permanently and signal notice removal.
@@ -73,7 +72,7 @@ export function decideNudge(state, scanTools, promptCount, now, msRemaining) {
73
72
  const present = new Set(scanTools);
74
73
  const consecutive = {};
75
74
  for (const tool of NUDGE_TRIGGER_TOOLS) {
76
- consecutive[tool] = present.has(tool) ? (state.consecutive[tool] ?? 0) + 1 : 0;
75
+ consecutive[tool] = present.has(tool) && setupIssues[tool] ? (state.consecutive[tool] ?? 0) + 1 : 0;
77
76
  }
78
77
  const next = { ...state, consecutive };
79
78
  // First trigger tool (in copy-priority order) that has been present long
@@ -92,6 +91,7 @@ export function decideNudge(state, scanTools, promptCount, now, msRemaining) {
92
91
  return {
93
92
  action: "nudge",
94
93
  tool,
94
+ setupAction: setupIssues[tool],
95
95
  state: { ...next, nudgeCount: next.nudgeCount + 1, lastNudgeAt: now },
96
96
  };
97
97
  }
@@ -315,34 +315,18 @@ export function isCliNoticeArtifact(projectDir, relPath, lastKnown) {
315
315
  return lastKnown?.get(relPath) ?? false;
316
316
  }
317
317
  // ── Notification copy ─────────────────────────────────────────────
318
- // Tone matches the ENG-951 init notice: helpful, never accusatory. Zero
319
- // captured prompts leaves the grader's process axes UNRATED (ENG-2476; the
320
- // old renormalize-it-out gate is gone), so uncaptured AI work counts for
321
- // nothing rather than against them — the honest pitch is still "visible AI
322
- // use counts in your favor", not a threat.
323
- const NOTICE_POINTER = `Details: ${AI_NOTICE_FILE_NAME} in your assessment folder.`;
324
- /**
325
- * @param withDetailsPointer false when the notice file could not be written
326
- * (a candidate-owned file occupies the path) — pointing at a file that
327
- * carries THEIR content would misdirect.
328
- */
329
- export function nudgeNotificationCopy(tool, withDetailsPointer = true) {
330
- let message;
331
- switch (tool) {
332
- case "codex":
333
- message =
334
- `No AI prompts captured yet. If you're using Codex, restart it (or trust the Litmus hooks under /hooks) so your AI work is recorded for review by the hiring company, then run "litmus doctor" to recover earlier prompts.`;
335
- break;
336
- case "copilot":
337
- message =
338
- `No AI prompts captured yet. If you're using the Copilot CLI, restart it (or answer yes to its folder-trust prompt) so your AI work is recorded for review by the hiring company, then run "litmus doctor" to recover earlier prompts.`;
339
- break;
340
- default:
341
- message =
342
- 'No AI prompts captured yet. Run "litmus doctor" in your assessment folder to check AI tracking.';
343
- break;
344
- }
345
- return { title: "Litmus", message: withDetailsPointer ? `${message} ${NOTICE_POINTER}` : message };
318
+ // One action, selected from a confirmed setup issue. No capture-status
319
+ // disclosure or assessment-file pointer in candidate notifications.
320
+ export function nudgeNotificationCopy(action) {
321
+ if (action === "approve_codex")
322
+ return {
323
+ title: "Enable Litmus hooks", message: "Open /hooks in Codex and approve the Litmus hooks.",
324
+ };
325
+ if (action === "trust_copilot")
326
+ return {
327
+ title: "Approve folder access", message: "Accept the folder-trust prompt in Copilot CLI.",
328
+ };
329
+ return { title: "Finish setup", message: "Run litmus doctor in your assessment folder." };
346
330
  }
347
331
  /** Incremental count across both capture lanes, with independent byte cursors. */
348
332
  export function scanAssessmentCapture(projectDir, token, cursors) {
@@ -1 +1 @@
1
- {"version":3,"file":"capture-nudge.js","sourceRoot":"","sources":["../../src/lib/capture-nudge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"capture-nudge.js","sourceRoot":"","sources":["../../src/lib/capture-nudge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Built once per asset revision using macOS's built-in applet compiler. No
2
+ * downloaded executables, development toolchain, or installer is required. */
3
+ export declare function prepareMacNotifier(): Promise<string>;
4
+ //# sourceMappingURL=mac-notifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mac-notifier.d.ts","sourceRoot":"","sources":["../../src/lib/mac-notifier.ts"],"names":[],"mappings":"AAgBA;8EAC8E;AAC9E,wBAAgB,kBAAkB,IAAI,OAAO,CAAC,MAAM,CAAC,CAGpD"}
@@ -0,0 +1,72 @@
1
+ import { execFile } from "child_process";
2
+ import { createHash } from "crypto";
3
+ import { cp, mkdir, mkdtemp, readFile, rename, rm, stat, writeFile } from "fs/promises";
4
+ import os from "os";
5
+ import path from "path";
6
+ import { fileURLToPath } from "url";
7
+ const assets = fileURLToPath(new URL("../notification-assets/", import.meta.url));
8
+ let preparing;
9
+ function run(command, args) {
10
+ return new Promise((resolve, reject) => {
11
+ execFile(command, args, { timeout: 15000, windowsHide: true }, error => error ? reject(error) : resolve());
12
+ });
13
+ }
14
+ /** Built once per asset revision using macOS's built-in applet compiler. No
15
+ * downloaded executables, development toolchain, or installer is required. */
16
+ export function prepareMacNotifier() {
17
+ preparing ?? (preparing = prepare().catch(error => { preparing = undefined; throw error; }));
18
+ return preparing;
19
+ }
20
+ async function prepare() {
21
+ const script = await readFile(path.join(assets, "notifier.js"));
22
+ const icon = await readFile(path.join(assets, "litmus.icns"));
23
+ const revision = createHash("sha256").update("bundle-v1").update(script).update(icon).digest("hex").slice(0, 16);
24
+ const root = path.join(os.homedir(), ".litmus", "notifications", revision);
25
+ const app = path.join(root, "Litmus.app");
26
+ const ready = path.join(app, "Contents", "Resources", ".litmus-ready");
27
+ try {
28
+ if ((await stat(ready)).isFile())
29
+ return app;
30
+ }
31
+ catch { /* first use */ }
32
+ await mkdir(root, { recursive: true, mode: 0o700 });
33
+ const staging = await mkdtemp(path.join(root, ".build-"));
34
+ const stagedApp = path.join(staging, "Litmus.app");
35
+ try {
36
+ await run("/usr/bin/osacompile", ["-l", "JavaScript", "-o", stagedApp, path.join(assets, "notifier.js")]);
37
+ await writeFile(path.join(stagedApp, "Contents", "Info.plist"), `<?xml version="1.0" encoding="UTF-8"?>
38
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
39
+ <plist version="1.0"><dict>
40
+ <key>CFBundleExecutable</key><string>applet</string>
41
+ <key>CFBundleIdentifier</key><string>com.litmushiring.notifications</string>
42
+ <key>CFBundleName</key><string>Litmus</string>
43
+ <key>CFBundleIconFile</key><string>litmus.icns</string>
44
+ <key>CFBundlePackageType</key><string>APPL</string>
45
+ <key>CFBundleVersion</key><string>1</string>
46
+ <key>LSUIElement</key><true/>
47
+ <key>OSAAppletShowStartupScreen</key><false/>
48
+ </dict></plist>`);
49
+ await cp(path.join(assets, "litmus.icns"), path.join(stagedApp, "Contents", "Resources", "litmus.icns"));
50
+ // Editing a compiled app invalidates its ad-hoc signature. Sign the final
51
+ // bundle, not the source applet, before launching it.
52
+ await writeFile(path.join(stagedApp, "Contents", "Resources", ".litmus-ready"), revision);
53
+ await run("/usr/bin/codesign", ["--force", "--sign", "-", stagedApp]);
54
+ try {
55
+ await rename(stagedApp, app);
56
+ }
57
+ catch (error) {
58
+ // Another watcher may have installed this exact revision first.
59
+ try {
60
+ await stat(ready);
61
+ }
62
+ catch {
63
+ throw error;
64
+ }
65
+ }
66
+ return app;
67
+ }
68
+ finally {
69
+ await rm(staging, { recursive: true, force: true });
70
+ }
71
+ }
72
+ //# sourceMappingURL=mac-notifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mac-notifier.js","sourceRoot":"","sources":["../../src/lib/mac-notifier.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@
2
2
  * Best-effort desktop notification (ENG-1857) — zero dependencies, silent
3
3
  * failure. Used by the watcher to reach a candidate whose terminal (and
4
4
  * tracker.log) they are not looking at. It must never throw and never block:
5
- * every path is a fire-and-forget execFile with a 5s timeout, and a missing
5
+ * notification sends use execFile with a 5s timeout, and a missing
6
6
  * binary (no notify-send, locked-down PowerShell) is simply a no-op.
7
7
  */
8
8
  import { execFile } from "child_process";
@@ -11,15 +11,14 @@ import { execFile } from "child_process";
11
11
  * run. Pure — split out so tests can check construction (quote escaping)
12
12
  * without spawning anything.
13
13
  */
14
- export declare function buildNotifyCommand(platform: NodeJS.Platform, title: string, message: string): {
14
+ export declare function buildNotifyCommand(platform: NodeJS.Platform, title: string, message: string, macApp?: string): {
15
15
  cmd: string;
16
16
  args: string[];
17
17
  } | null;
18
18
  /**
19
19
  * Show a desktop notification. Never throws, never blocks the caller;
20
20
  * failure of any kind (missing binary, DE without a notification daemon,
21
- * headless session) is silently ignored — the notice file is the durable
22
- * fallback surface.
21
+ * headless session) is silently ignored.
23
22
  */
24
23
  export declare function desktopNotify(title: string, message: string, exec?: typeof execFile): void;
25
24
  /**
@@ -27,5 +26,5 @@ export declare function desktopNotify(title: string, message: string, exec?: typ
27
26
  * caller that retries an unsent notification (ENG-3307's capture notice). Never
28
27
  * rejects; resolves false on a missing binary, a non-zero exit or the timeout.
29
28
  */
30
- export declare function desktopNotifyResult(title: string, message: string, exec?: typeof execFile): Promise<boolean>;
29
+ export declare function desktopNotifyResult(title: string, message: string, exec?: typeof execFile, prepare?: () => Promise<string>): Promise<boolean>;
31
30
  //# sourceMappingURL=notify.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/lib/notify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAYxC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GACd;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CA4BxC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,OAAO,QAAmB,GAC/B,IAAI,CAaN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,OAAO,QAAmB,GAC/B,OAAO,CAAC,OAAO,CAAC,CAgBlB"}
1
+ {"version":3,"file":"notify.d.ts","sourceRoot":"","sources":["../../src/lib/notify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AAWxC;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CA4BxC;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,OAAO,QAAmB,GAC/B,IAAI,CAEN;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,OAAO,QAAmB,EAChC,OAAO,GAAE,MAAM,OAAO,CAAC,MAAM,CAAsB,GAClD,OAAO,CAAC,OAAO,CAAC,CAoBlB"}
@@ -2,14 +2,13 @@
2
2
  * Best-effort desktop notification (ENG-1857) — zero dependencies, silent
3
3
  * failure. Used by the watcher to reach a candidate whose terminal (and
4
4
  * tracker.log) they are not looking at. It must never throw and never block:
5
- * every path is a fire-and-forget execFile with a 5s timeout, and a missing
5
+ * notification sends use execFile with a 5s timeout, and a missing
6
6
  * binary (no notify-send, locked-down PowerShell) is simply a no-op.
7
7
  */
8
8
  import { execFile } from "child_process";
9
- /** AppleScript string literal: backslashes and double quotes escaped. */
10
- function appleScriptString(s) {
11
- return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
12
- }
9
+ import { fileURLToPath, pathToFileURL } from "url";
10
+ import { prepareMacNotifier } from "./mac-notifier.js";
11
+ const notificationIcon = fileURLToPath(new URL("../notification-assets/litmus.png", import.meta.url));
13
12
  /** PowerShell single-quoted string literal: single quotes doubled. */
14
13
  function powerShellString(s) {
15
14
  return `'${s.replace(/'/g, "''")}'`;
@@ -19,12 +18,11 @@ function powerShellString(s) {
19
18
  * run. Pure — split out so tests can check construction (quote escaping)
20
19
  * without spawning anything.
21
20
  */
22
- export function buildNotifyCommand(platform, title, message) {
21
+ export function buildNotifyCommand(platform, title, message, macApp) {
23
22
  if (platform === "darwin") {
24
- return {
25
- cmd: "osascript",
26
- args: ["-e", `display notification ${appleScriptString(message)} with title ${appleScriptString(title)}`],
27
- };
23
+ if (!macApp)
24
+ return null;
25
+ return { cmd: "open", args: ["-g", "-n", "-W", macApp, "--args", "--title", title, "--message", message] };
28
26
  }
29
27
  if (platform === "win32") {
30
28
  // WinRT toast via PowerShell — present on every supported Windows, no
@@ -33,10 +31,12 @@ export function buildNotifyCommand(platform, title, message) {
33
31
  // needed on top.
34
32
  const script = [
35
33
  "[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null",
36
- "$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastText02)",
34
+ "$template = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent([Windows.UI.Notifications.ToastTemplateType]::ToastImageAndText02)",
37
35
  "$texts = $template.GetElementsByTagName('text')",
38
36
  `$texts.Item(0).AppendChild($template.CreateTextNode(${powerShellString(title)})) | Out-Null`,
39
37
  `$texts.Item(1).AppendChild($template.CreateTextNode(${powerShellString(message)})) | Out-Null`,
38
+ "$image = $template.GetElementsByTagName('image').Item(0)",
39
+ `$image.SetAttribute('src', ${powerShellString(pathToFileURL(notificationIcon).href)})`,
40
40
  "$toast = [Windows.UI.Notifications.ToastNotification]::new($template)",
41
41
  `[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier(${powerShellString("Litmus")}).Show($toast)`,
42
42
  ].join("; ");
@@ -44,36 +44,35 @@ export function buildNotifyCommand(platform, title, message) {
44
44
  }
45
45
  if (platform === "linux") {
46
46
  // notify-send if present; execFile's ENOENT is swallowed below when not.
47
- return { cmd: "notify-send", args: [title, message] };
47
+ return { cmd: "notify-send", args: ["--icon", notificationIcon, "--", title, message] };
48
48
  }
49
49
  return null;
50
50
  }
51
51
  /**
52
52
  * Show a desktop notification. Never throws, never blocks the caller;
53
53
  * failure of any kind (missing binary, DE without a notification daemon,
54
- * headless session) is silently ignored — the notice file is the durable
55
- * fallback surface.
54
+ * headless session) is silently ignored.
56
55
  */
57
56
  export function desktopNotify(title, message, exec = execFile) {
58
- try {
59
- const command = buildNotifyCommand(process.platform, title, message);
60
- if (!command)
61
- return;
62
- const child = exec(command.cmd, command.args, { timeout: 5000, windowsHide: true }, () => { });
63
- // Detach from the event loop so a slow notifier can't hold the watcher up.
64
- child.unref?.();
65
- }
66
- catch { /* never let a notification failure surface */ }
57
+ void desktopNotifyResult(title, message, exec);
67
58
  }
68
59
  /**
69
60
  * `desktopNotify`, reporting whether the notifier ran and exited cleanly. For a
70
61
  * caller that retries an unsent notification (ENG-3307's capture notice). Never
71
62
  * rejects; resolves false on a missing binary, a non-zero exit or the timeout.
72
63
  */
73
- export function desktopNotifyResult(title, message, exec = execFile) {
64
+ export async function desktopNotifyResult(title, message, exec = execFile, prepare = prepareMacNotifier) {
65
+ let macApp;
66
+ try {
67
+ if (process.platform === "darwin")
68
+ macApp = await prepare();
69
+ }
70
+ catch {
71
+ return false;
72
+ }
74
73
  return new Promise((resolve) => {
75
74
  try {
76
- const command = buildNotifyCommand(process.platform, title, message);
75
+ const command = buildNotifyCommand(process.platform, title, message, macApp);
77
76
  if (!command)
78
77
  return resolve(false);
79
78
  const child = exec(command.cmd, command.args, { timeout: 5000, windowsHide: true }, (error) => resolve(!error));
@@ -1 +1 @@
1
- {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/lib/notify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"notify.js","sourceRoot":"","sources":["../../src/lib/notify.ts"],"names":[],"mappings":"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"}
@@ -34,7 +34,7 @@ import { buildGitBundle, currentHead } from "./git-bundle.js";
34
34
  import { fetchInitMetadata, ServerError } from "./api.js";
35
35
  import { resolveBackendBase } from "./api-base.js";
36
36
  import { ServerTimesSchema } from "./schemas.js";
37
- import { detectInstalledHooks, addActiveAssessment, removeActiveAssessment } from "./ai-tracking.js";
37
+ import { detectInstalledHooks, notificationSetupAction, addActiveAssessment, removeActiveAssessment } from "./ai-tracking.js";
38
38
  import { retireAiCaptureForEndedSession, sessionOverMarked } from "./session-over.js";
39
39
  import { readActivityLogTail } from "./activity-tail.js";
40
40
  import { setupAiTracking } from "../commands/init.js";
@@ -43,7 +43,7 @@ import { createKeepAliveGuard } from "./keepalive.js";
43
43
  import { WATCHER_READY_GRACE_MS, WATCHER_BOOT_TIMEOUT_MS } from "./tracker.js";
44
44
  import { getProcessListAsync, probeUnfilteredTasklist, getConnections, extractConnection, resolvePidNames } from "./platform.js";
45
45
  import { detectTools, refineClaudeTool } from "./detection.js";
46
- import { decideNudge, loadNudgeState, saveNudgeState, scanAssessmentCapture, writeAiNoticeFile, removeAiNoticeFile, nudgeNotificationCopy, isCliNoticeArtifact, AI_NOTICE_FILE_NAME, } from "./capture-nudge.js";
46
+ import { decideNudge, loadNudgeState, saveNudgeState, scanAssessmentCapture, NUDGE_TRIGGER_TOOLS, removeAiNoticeFile, nudgeNotificationCopy, isCliNoticeArtifact, AI_NOTICE_FILE_NAME, } from "./capture-nudge.js";
47
47
  import { desktopNotify } from "./notify.js";
48
48
  import { codexStoreInventory, readCodexDelivery } from "./codex-capture-health.js";
49
49
  // ENG-1491: an uncaught throw no longer always kills the watcher — on a
@@ -1180,18 +1180,14 @@ function checkGitCommits() {
1180
1180
  }
1181
1181
  setInterval(checkGitCommits, 30 * 1000); // Every 30 seconds
1182
1182
  // ── Capture nudge (ENG-1857) ─────────────────────────────────────
1183
- // A hook-capturable AI tool running with ZERO captured prompts is the silent
1184
- // Codex/Copilot trust-gate signature: the candidate's AI work is invisibly
1185
- // not being recorded, and they'd only find out from their report. Warn THEM,
1186
- // live. Strictly candidate-facing: a desktop notification, a notice file at
1187
- // the assessment root, and stderr (-> .litmus/tracker.log, excluded from all
1188
- // grader signals via substrate.py's _is_capture_artifact). It must emit NO
1189
- // activity event — the grader renders every non-response activity event
1190
- // verbatim in the judge-visible timeline and merges the in-zip
1191
- // activity.jsonl, so an event here would leak straight to reviewers.
1183
+ // Ask for one action only when an active tool has a confirmed setup fault.
1184
+ // No conversations alone proves nothing. Candidate notifications emit no
1185
+ // activity event: the grader renders those in the judge-visible timeline.
1186
+ // Diagnostics stay on stderr (.litmus/tracker.log, excluded from grading).
1192
1187
  //
1193
1188
  // State persists in .litmus/nudge-state.json so the routine watcher respawns
1194
1189
  // (litmus status/doctor revive watchers) don't re-nag from scratch.
1190
+ removeOwnedAiNotice(); // retire guidance left by older CLI versions
1195
1191
  let nudgeState = loadNudgeState(projectDir);
1196
1192
  // Incremental ai_prompt/ai_response counters over the folder and same-token
1197
1193
  // supervisor logs; only appended bytes are read each cycle. A restart rescans
@@ -1218,24 +1214,24 @@ function runCaptureNudge(aiTools) {
1218
1214
  }
1219
1215
  const deadlineMs = litmusConfig ? getEffectiveDeadline(litmusConfig) : null;
1220
1216
  const msRemaining = deadlineMs === null ? null : deadlineMs - Date.now();
1221
- const decision = decideNudge(nudgeState, aiTools, capturedAiCount, Date.now(), msRemaining);
1217
+ const setupIssues = {};
1218
+ for (const tool of NUDGE_TRIGGER_TOOLS) {
1219
+ if (!aiTools.includes(tool))
1220
+ continue;
1221
+ const issue = notificationSetupAction(projectDir, tool);
1222
+ if (issue)
1223
+ setupIssues[tool] = issue;
1224
+ }
1225
+ const decision = decideNudge(nudgeState, aiTools, capturedAiCount, Date.now(), msRemaining, setupIssues);
1222
1226
  nudgeState = decision.state;
1223
1227
  saveNudgeState(projectDir, nudgeState);
1224
1228
  if (decision.action === "nudge") {
1225
- // Write first: when a candidate-owned file occupies the path we never
1226
- // clobber it, and the notification then drops its "Details:" pointer
1227
- // (which would name a file carrying THEIR content).
1228
- const noticeWritten = writeAiNoticeFile(projectDir);
1229
- if (noticeWritten) {
1230
- isCliNoticeArtifact(projectDir, AI_NOTICE_FILE_NAME, noticeOwnership); // refresh ownership
1231
- }
1232
- else {
1233
- process.stderr.write(`[watcher] ${AI_NOTICE_FILE_NAME} exists and is not ours; notification only\n`);
1234
- }
1235
- const copy = nudgeNotificationCopy(decision.tool, noticeWritten);
1229
+ // Retire old guidance without touching candidate edits.
1230
+ removeOwnedAiNotice();
1231
+ const copy = nudgeNotificationCopy(decision.setupAction);
1236
1232
  desktopNotify(copy.title, copy.message);
1237
1233
  // stderr only — this lands in tracker.log, never in activity.jsonl.
1238
- process.stderr.write(`[watcher] capture nudge fired (${decision.tool}, nudge ${nudgeState.nudgeCount}): AI tool present, zero prompts captured\n`);
1234
+ process.stderr.write(`[watcher] capture nudge fired (${decision.tool}, nudge ${nudgeState.nudgeCount}): confirmed setup issue ${decision.setupAction}\n`);
1239
1235
  }
1240
1236
  else if (decision.action === "remove_notice") {
1241
1237
  removeOwnedAiNotice();