@damian87/omp 0.12.0 → 0.14.0

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 (94) hide show
  1. package/.github/skills/schedule/SKILL.md +27 -2
  2. package/.github/skills/verify-byok/SKILL.md +50 -0
  3. package/README.md +88 -4
  4. package/catalog/capabilities.json +23 -0
  5. package/catalog/skills-general.json +25 -0
  6. package/dist/src/cli.js +158 -5
  7. package/dist/src/cli.js.map +1 -1
  8. package/dist/src/commands/comms.d.ts +2 -0
  9. package/dist/src/commands/comms.js +110 -0
  10. package/dist/src/commands/comms.js.map +1 -0
  11. package/dist/src/commands/council.d.ts +2 -0
  12. package/dist/src/commands/council.js +77 -0
  13. package/dist/src/commands/council.js.map +1 -0
  14. package/dist/src/commands/env.d.ts +2 -0
  15. package/dist/src/commands/env.js +95 -0
  16. package/dist/src/commands/env.js.map +1 -0
  17. package/dist/src/commands/gateway.d.ts +3 -0
  18. package/dist/src/commands/gateway.js +129 -0
  19. package/dist/src/commands/gateway.js.map +1 -0
  20. package/dist/src/commands/memory.d.ts +7 -0
  21. package/dist/src/commands/memory.js +202 -0
  22. package/dist/src/commands/memory.js.map +1 -0
  23. package/dist/src/commands/mode.d.ts +4 -0
  24. package/dist/src/commands/mode.js +119 -0
  25. package/dist/src/commands/mode.js.map +1 -0
  26. package/dist/src/commands/schedule.d.ts +2 -0
  27. package/dist/src/commands/schedule.js +91 -0
  28. package/dist/src/commands/schedule.js.map +1 -0
  29. package/dist/src/commands/team.d.ts +2 -0
  30. package/dist/src/commands/team.js +146 -0
  31. package/dist/src/commands/team.js.map +1 -0
  32. package/dist/src/commands/utils.d.ts +13 -0
  33. package/dist/src/commands/utils.js +68 -0
  34. package/dist/src/commands/utils.js.map +1 -0
  35. package/dist/src/gateway/desktop-notify.d.ts +56 -0
  36. package/dist/src/gateway/desktop-notify.js +183 -0
  37. package/dist/src/gateway/desktop-notify.js.map +1 -0
  38. package/dist/src/goal.js +6 -8
  39. package/dist/src/goal.js.map +1 -1
  40. package/dist/src/instructions-memory.js +26 -3
  41. package/dist/src/instructions-memory.js.map +1 -1
  42. package/dist/src/memory-review/apply.d.ts +7 -0
  43. package/dist/src/memory-review/apply.js +75 -0
  44. package/dist/src/memory-review/apply.js.map +1 -0
  45. package/dist/src/memory-review/config.d.ts +22 -0
  46. package/dist/src/memory-review/config.js +54 -0
  47. package/dist/src/memory-review/config.js.map +1 -0
  48. package/dist/src/memory-review/guard.d.ts +5 -0
  49. package/dist/src/memory-review/guard.js +37 -0
  50. package/dist/src/memory-review/guard.js.map +1 -0
  51. package/dist/src/memory-review/index.d.ts +17 -0
  52. package/dist/src/memory-review/index.js +87 -0
  53. package/dist/src/memory-review/index.js.map +1 -0
  54. package/dist/src/memory-review/prompt.d.ts +18 -0
  55. package/dist/src/memory-review/prompt.js +89 -0
  56. package/dist/src/memory-review/prompt.js.map +1 -0
  57. package/dist/src/memory-review/spawn.d.ts +2 -0
  58. package/dist/src/memory-review/spawn.js +51 -0
  59. package/dist/src/memory-review/spawn.js.map +1 -0
  60. package/dist/src/memory-review/transcript.d.ts +24 -0
  61. package/dist/src/memory-review/transcript.js +212 -0
  62. package/dist/src/memory-review/transcript.js.map +1 -0
  63. package/dist/src/memory-review/trigger.d.ts +21 -0
  64. package/dist/src/memory-review/trigger.js +27 -0
  65. package/dist/src/memory-review/trigger.js.map +1 -0
  66. package/dist/src/project-memory.d.ts +9 -0
  67. package/dist/src/project-memory.js +72 -1
  68. package/dist/src/project-memory.js.map +1 -1
  69. package/dist/src/schedule/commands.d.ts +13 -0
  70. package/dist/src/schedule/commands.js +24 -1
  71. package/dist/src/schedule/commands.js.map +1 -1
  72. package/dist/src/schedule/deep-link.d.ts +18 -0
  73. package/dist/src/schedule/deep-link.js +41 -0
  74. package/dist/src/schedule/deep-link.js.map +1 -0
  75. package/dist/src/schedule/runner.d.ts +10 -0
  76. package/dist/src/schedule/runner.js +36 -0
  77. package/dist/src/schedule/runner.js.map +1 -1
  78. package/dist/src/schedule/types.d.ts +16 -0
  79. package/dist/src/state.js +25 -37
  80. package/dist/src/state.js.map +1 -1
  81. package/dist/src/utils/fs.d.ts +14 -0
  82. package/dist/src/utils/fs.js +32 -0
  83. package/dist/src/utils/fs.js.map +1 -0
  84. package/dist/src/utils/paths.d.ts +14 -0
  85. package/dist/src/utils/paths.js +21 -0
  86. package/dist/src/utils/paths.js.map +1 -0
  87. package/docs/memory-mode.md +94 -0
  88. package/docs/research/2026-06-22-schedule-desktop-notifications.md +193 -0
  89. package/package.json +4 -2
  90. package/plugin.json +1 -1
  91. package/scripts/lib/memory-review-trigger.mjs +59 -0
  92. package/scripts/lib/pending-directives.mjs +36 -0
  93. package/scripts/session-end.mjs +8 -0
  94. package/scripts/session-start.mjs +4 -0
@@ -0,0 +1,212 @@
1
+ import { closeSync, existsSync, openSync, readSync, readdirSync, statSync } from "node:fs";
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ export const DEFAULT_MAX_BYTES = 8 * 1024 * 1024;
5
+ // Parsed conversation is sparse (~10-15 tokens/msg; tool outputs dropped), so a
6
+ // generous window captures realistic long sessions in full while still bounding
7
+ // pathological ones. 200 covers observed real sessions (~178 msgs) end-to-end.
8
+ export const DEFAULT_MAX_MESSAGES = 200;
9
+ // Session ids are UUID-like (Copilot uses them as the session-state dir name).
10
+ // Validate before joining into a path so a crafted id can't traverse out of the
11
+ // session-state root (e.g. "../../etc").
12
+ export function isValidSessionId(uuid) {
13
+ return (typeof uuid === "string" &&
14
+ /^[A-Za-z0-9._-]+$/.test(uuid) &&
15
+ !uuid.includes("..") &&
16
+ /[A-Za-z0-9]/.test(uuid) // reject dot/dash-only ids (e.g. ".") that resolve to the base dir
17
+ );
18
+ }
19
+ export function sessionEventsPath(uuid, base) {
20
+ const root = base ?? join(homedir(), ".copilot", "session-state");
21
+ return join(root, uuid, "events.jsonl");
22
+ }
23
+ /** Newest session-state dir by mtime — used when the wrapper triggers a review
24
+ * post-exit and doesn't know the just-finished session's UUID. */
25
+ export function latestSessionId(base) {
26
+ const root = base ?? join(homedir(), ".copilot", "session-state");
27
+ if (!existsSync(root))
28
+ return null;
29
+ let best = null;
30
+ let bestMtime = -1;
31
+ for (const name of readdirSync(root)) {
32
+ try {
33
+ const st = statSync(join(root, name));
34
+ if (st.isDirectory() && st.mtimeMs > bestMtime) {
35
+ bestMtime = st.mtimeMs;
36
+ best = name;
37
+ }
38
+ }
39
+ catch {
40
+ // unreadable entry — skip
41
+ }
42
+ }
43
+ return best;
44
+ }
45
+ /** All session dir names under the session-state base (for before/after diff). */
46
+ export function listSessionIds(base) {
47
+ const root = base ?? join(homedir(), ".copilot", "session-state");
48
+ if (!existsSync(root))
49
+ return [];
50
+ return readdirSync(root).filter((name) => {
51
+ try {
52
+ return statSync(join(root, name)).isDirectory();
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ });
58
+ }
59
+ /** The session that appeared since `before` — i.e. the one the just-finished
60
+ * headless `copilot -p` run created. Returns null if none is new, so the
61
+ * wrapper SKIPS rather than guessing the wrong session. */
62
+ export function newestSessionSince(before, base) {
63
+ const seen = new Set(before);
64
+ const fresh = listSessionIds(base).filter((id) => !seen.has(id));
65
+ if (fresh.length === 0)
66
+ return null;
67
+ if (fresh.length === 1)
68
+ return fresh[0];
69
+ const root = base ?? join(homedir(), ".copilot", "session-state");
70
+ let best = null;
71
+ let bestMtime = -1;
72
+ for (const id of fresh) {
73
+ try {
74
+ const m = statSync(join(root, id)).mtimeMs;
75
+ if (m > bestMtime) {
76
+ bestMtime = m;
77
+ best = id;
78
+ }
79
+ }
80
+ catch {
81
+ // skip unreadable
82
+ }
83
+ }
84
+ return best;
85
+ }
86
+ function readTail(path, maxBytes) {
87
+ const size = statSync(path).size;
88
+ const start = Math.max(0, size - maxBytes);
89
+ const len = size - start;
90
+ const fd = openSync(path, "r");
91
+ try {
92
+ const buf = Buffer.alloc(len);
93
+ readSync(fd, buf, 0, len, start);
94
+ return buf.toString("utf8");
95
+ }
96
+ finally {
97
+ closeSync(fd);
98
+ }
99
+ }
100
+ // Summarize an assistant turn's tool calls. In agentic sessions most turns
101
+ // have empty `content` and do their work via `toolRequests`; without this they
102
+ // would be dropped — making a substantive session look "too short" and starving
103
+ // the reviewer of what the agent actually did. Format: "name: <intent|command>".
104
+ function summarizeToolRequests(toolRequests) {
105
+ if (!Array.isArray(toolRequests) || toolRequests.length === 0)
106
+ return "";
107
+ const parts = [];
108
+ for (const t of toolRequests) {
109
+ if (!t || typeof t !== "object")
110
+ continue;
111
+ const tr = t;
112
+ const name = typeof tr.name === "string" ? tr.name : "tool";
113
+ const args = tr.arguments && typeof tr.arguments === "object" ? tr.arguments : {};
114
+ const detail = (typeof tr.intentionSummary === "string" && tr.intentionSummary.trim()) ||
115
+ (typeof args.description === "string" && args.description.trim()) ||
116
+ (typeof args.command === "string" && args.command.trim()) ||
117
+ "";
118
+ parts.push(detail ? `${name}: ${detail}` : name);
119
+ }
120
+ return parts.length ? `(tools: ${parts.join(", ")})` : "";
121
+ }
122
+ function extractText(content) {
123
+ if (typeof content === "string")
124
+ return content;
125
+ if (Array.isArray(content)) {
126
+ return content
127
+ .map((part) => {
128
+ if (typeof part === "string")
129
+ return part;
130
+ if (part && typeof part === "object" && typeof part.text === "string") {
131
+ return part.text;
132
+ }
133
+ return "";
134
+ })
135
+ .filter(Boolean)
136
+ .join("\n");
137
+ }
138
+ return "";
139
+ }
140
+ export function parseTranscript(raw) {
141
+ const messages = [];
142
+ for (const line of raw.split("\n")) {
143
+ const trimmed = line.trim();
144
+ if (!trimmed)
145
+ continue;
146
+ let obj;
147
+ try {
148
+ const parsed = JSON.parse(trimmed);
149
+ obj = parsed && typeof parsed === "object" ? parsed : undefined;
150
+ }
151
+ catch {
152
+ continue; // partial line (tail boundary) or non-JSON — skip
153
+ }
154
+ if (!obj)
155
+ continue;
156
+ // Real Copilot shape: {"type":"user.message","data":{"content":...,"role":...}}.
157
+ // Only "*.message" events carry conversation text; every other event type
158
+ // (session.*, assistant.turn_*, tool.*, hook.*) is skipped. Fall back to a
159
+ // generic {role, content}/{message:{content}} shape for other producers.
160
+ const type = typeof obj.type === "string" ? obj.type : "";
161
+ const data = (obj.data && typeof obj.data === "object" ? obj.data : {});
162
+ let role;
163
+ let content;
164
+ let toolSummary = "";
165
+ if (type.endsWith(".message")) {
166
+ role = typeof data.role === "string" ? data.role : type.slice(0, -".message".length);
167
+ content = data.content;
168
+ // Assistant turns that act via tools carry the work in toolRequests, not
169
+ // content — fold a summary in so the turn counts and the reviewer sees it.
170
+ if (role === "assistant")
171
+ toolSummary = summarizeToolRequests(data.toolRequests);
172
+ }
173
+ else if (type) {
174
+ continue; // a typed event that is not a message — no conversation text
175
+ }
176
+ else {
177
+ const message = (obj.message ?? {});
178
+ role = String(obj.role ?? message.role ?? "unknown");
179
+ content = message.content ?? obj.content ?? obj.text;
180
+ }
181
+ // Skip the system prompt — it's boilerplate, huge, and not user knowledge.
182
+ if (role === "system")
183
+ continue;
184
+ const base = extractText(content).trim();
185
+ const text = [base, toolSummary].filter(Boolean).join("\n");
186
+ if (text) {
187
+ messages.push({ role, text });
188
+ }
189
+ }
190
+ return messages;
191
+ }
192
+ export function readSessionTranscript(uuid, options = {}) {
193
+ if (!isValidSessionId(uuid))
194
+ return [];
195
+ const maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
196
+ const maxMessages = options.maxMessages ?? DEFAULT_MAX_MESSAGES;
197
+ const path = sessionEventsPath(uuid, options.sessionStateDir);
198
+ if (!existsSync(path))
199
+ return [];
200
+ let raw = "";
201
+ try {
202
+ raw = readTail(path, maxBytes);
203
+ }
204
+ catch {
205
+ return [];
206
+ }
207
+ const all = parseTranscript(raw);
208
+ // Window to the most recent maxMessages so the review prompt stays bounded by
209
+ // conversation length regardless of how long the session ran.
210
+ return all.length > maxMessages ? all.slice(all.length - maxMessages) : all;
211
+ }
212
+ //# sourceMappingURL=transcript.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../src/memory-review/transcript.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface SpawnedChild {
2
+ unref?: () => void;
3
+ on?: (event: string, cb: (...args: unknown[]) => void) => void;
4
+ }
5
+ export type DetachSpawn = (command: string, args: string[], options: {
6
+ detached: boolean;
7
+ stdio: "ignore";
8
+ }) => SpawnedChild;
9
+ export interface HeadlessTriggerOptions {
10
+ cwd: string;
11
+ argv: string[];
12
+ cliPath: string;
13
+ sessionId: string;
14
+ spawn?: DetachSpawn;
15
+ modeOverride?: "on" | "off";
16
+ }
17
+ export declare function isHeadless(argv: string[]): boolean;
18
+ export declare function triggerHeadlessReview(opts: HeadlessTriggerOptions): {
19
+ triggered: boolean;
20
+ reason?: string;
21
+ };
@@ -0,0 +1,27 @@
1
+ import { spawn as nodeSpawn } from "node:child_process";
2
+ import { readMemoryConfig } from "./config.js";
3
+ const PROMPT_FLAGS = new Set(["-p", "--prompt"]);
4
+ export function isHeadless(argv) {
5
+ return argv.some((a) => PROMPT_FLAGS.has(a));
6
+ }
7
+ export function triggerHeadlessReview(opts) {
8
+ if (!isHeadless(opts.argv))
9
+ return { triggered: false, reason: "not headless" };
10
+ const mode = opts.modeOverride ?? readMemoryConfig(opts.cwd).memoryMode;
11
+ if (mode !== "on")
12
+ return { triggered: false, reason: "memory-mode off" };
13
+ if (!opts.sessionId)
14
+ return { triggered: false, reason: "no session id" };
15
+ const spawn = opts.spawn ?? nodeSpawn;
16
+ try {
17
+ const child = spawn(process.execPath, [opts.cliPath, "memory-review", "--session", opts.sessionId, "--root", opts.cwd], { detached: true, stdio: "ignore" });
18
+ // Handle async spawn errors so they never surface as unhandled (fail-open).
19
+ child?.on?.("error", () => { });
20
+ child?.unref?.();
21
+ return { triggered: true };
22
+ }
23
+ catch (err) {
24
+ return { triggered: false, reason: String(err?.message ?? err) };
25
+ }
26
+ }
27
+ //# sourceMappingURL=trigger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger.js","sourceRoot":"","sources":["../../../src/memory-review/trigger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AA4B/C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;AAEjD,MAAM,UAAU,UAAU,CAAC,IAAc;IACvC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,IAA4B;IAE5B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAChF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,IAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;IACxE,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAC1E,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAK,SAAoC,CAAC;IAClE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CACjB,OAAO,CAAC,QAAQ,EAChB,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,EAChF,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CACpC,CAAC;QACF,4EAA4E;QAC5E,KAAK,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC/B,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;QACjB,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAE,GAAa,EAAE,OAAO,IAAI,GAAG,CAAC,EAAE,CAAC;IAC9E,CAAC;AACH,CAAC"}
@@ -9,5 +9,14 @@ export interface NoteMeta {
9
9
  export declare function addNote(cwd: string, title: string, body?: string): string;
10
10
  /** Cheap index of (id, title) — the only thing surfaced; bodies stay on disk. */
11
11
  export declare function noteIndex(cwd: string): NoteMeta[];
12
+ /** Notes ordered newest-first by mtime, optionally capped. Used to surface the
13
+ * most recent titles in the injected block without unbounded growth. */
14
+ export declare function recentNotes(cwd: string, limit?: number): NoteMeta[];
15
+ /** Prune notes by count (keep N newest) and/or age (older than N days).
16
+ * Returns the ids removed. No options → no-op (never deletes silently). */
17
+ export declare function pruneNotes(cwd: string, opts: {
18
+ keep?: number;
19
+ olderThanDays?: number;
20
+ }): string[];
12
21
  /** Full note body by id, or null when missing. */
13
22
  export declare function readNote(cwd: string, id: string): string | null;
@@ -1,4 +1,4 @@
1
- import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, writeFileSync } from "node:fs";
1
+ import { existsSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync, writeFileSync } from "node:fs";
2
2
  import { dirname, join } from "node:path";
3
3
  import { ompRoot } from "./omp-root.js";
4
4
  function memPath(cwd) {
@@ -86,6 +86,77 @@ export function noteIndex(cwd) {
86
86
  })
87
87
  .sort((a, b) => a.id.localeCompare(b.id));
88
88
  }
89
+ /** Notes ordered newest-first by mtime, optionally capped. Used to surface the
90
+ * most recent titles in the injected block without unbounded growth. */
91
+ export function recentNotes(cwd, limit) {
92
+ const dir = notesDir(cwd);
93
+ if (!existsSync(dir))
94
+ return [];
95
+ const entries = readdirSync(dir)
96
+ .filter((f) => f.endsWith(".md"))
97
+ .map((f) => {
98
+ const id = f.replace(/\.md$/, "");
99
+ let title = id;
100
+ let mtime = 0;
101
+ try {
102
+ const full = join(dir, f);
103
+ mtime = statSync(full).mtimeMs;
104
+ const first = readFileSync(full, "utf8").split("\n")[0] ?? "";
105
+ title = first.replace(/^#\s*/, "").trim() || id;
106
+ }
107
+ catch {
108
+ // keep defaults
109
+ }
110
+ return { id, title, mtime };
111
+ })
112
+ .sort((a, b) => b.mtime - a.mtime);
113
+ const capped = typeof limit === "number" ? entries.slice(0, limit) : entries;
114
+ return capped.map(({ id, title }) => ({ id, title }));
115
+ }
116
+ /** Prune notes by count (keep N newest) and/or age (older than N days).
117
+ * Returns the ids removed. No options → no-op (never deletes silently). */
118
+ export function pruneNotes(cwd, opts) {
119
+ const dir = notesDir(cwd);
120
+ if (!existsSync(dir))
121
+ return [];
122
+ const files = readdirSync(dir)
123
+ .filter((f) => f.endsWith(".md"))
124
+ .map((f) => {
125
+ let mtime = 0;
126
+ try {
127
+ mtime = statSync(join(dir, f)).mtimeMs;
128
+ }
129
+ catch {
130
+ // unreadable — treat as oldest so it's eligible for pruning
131
+ }
132
+ return { id: f.replace(/\.md$/, ""), file: f, mtime };
133
+ })
134
+ .sort((a, b) => b.mtime - a.mtime); // newest-first
135
+ const toRemove = new Set();
136
+ if (typeof opts.keep === "number" && opts.keep >= 0) {
137
+ for (const e of files.slice(opts.keep))
138
+ toRemove.add(e.file);
139
+ }
140
+ if (typeof opts.olderThanDays === "number" && opts.olderThanDays >= 0) {
141
+ const cutoff = Date.now() - opts.olderThanDays * 86400_000;
142
+ for (const e of files)
143
+ if (e.mtime < cutoff)
144
+ toRemove.add(e.file);
145
+ }
146
+ const removed = [];
147
+ for (const e of files) {
148
+ if (!toRemove.has(e.file))
149
+ continue;
150
+ try {
151
+ unlinkSync(join(dir, e.file));
152
+ removed.push(e.id);
153
+ }
154
+ catch {
155
+ // skip files we can't remove
156
+ }
157
+ }
158
+ return removed.sort();
159
+ }
89
160
  /** Full note body by id, or null when missing. */
90
161
  export function readNote(cwd, id) {
91
162
  // Ids are slugs ([a-z0-9-]); reject anything else so a crafted id can't
@@ -1 +1 @@
1
- {"version":3,"file":"project-memory.js","sourceRoot":"","sources":["../../src/project-memory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtG,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAcxC,SAAS,OAAO,CAAC,GAAW;IAC1B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;AACvD,CAAC;AAED,wDAAwD;AAExD,SAAS,OAAO,CAAC,GAAW;IAC1B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IACpF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;QACjD,OAAO;YACL,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE;YAClE,SAAS,EAAE,OAAO,IAAI,EAAE,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;SAC5F,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC;IAClE,CAAC;AACH,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW,EAAE,GAAkB;IAC/C,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACpD,aAAa,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IACzH,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC;AACjC,CAAC;AAED,uEAAuE;AACvE,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,SAAiB;IACzD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IACzB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACnB,OAAO,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;AAC/B,CAAC;AASD,SAAS,OAAO,CAAC,KAAa;IAC5B,OAAO,CACL,MAAM,CAAC,KAAK,CAAC;SACV,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;SACvB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAC1B,CAAC;AACJ,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,KAAa,EAAE,IAAa;IAC/D,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC5B,IAAI,EAAE,GAAG,IAAI,CAAC;IACd,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;QACzC,CAAC,IAAI,CAAC,CAAC;QACP,EAAE,GAAG,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC;IACtB,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACzF,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAChC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;IACpD,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IACpC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IACnB,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClC,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACtE,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC,CAAC;SACD,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,EAAU;IAC9C,wEAAwE;IACxE,iEAAiE;IACjE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3C,MAAM,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IAChC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"project-memory.js","sourceRoot":"","sources":["../../src/project-memory.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,19 @@ export interface StatusView {
27
27
  osInstalled: boolean;
28
28
  }
29
29
  export declare function getScheduleStatus(stateCwd: string, id: string): StatusView;
30
+ export interface OpenResult {
31
+ ok: boolean;
32
+ job?: ScheduleJob;
33
+ /** Full captured output of the latest run (contents of job.lastLogPath), if present. */
34
+ logContent?: string;
35
+ error?: string;
36
+ }
37
+ /**
38
+ * Resolve a job's latest run for `omp schedule open <id>` — the by-id substitute
39
+ * for clicking a notification: returns the job plus the full captured log so the
40
+ * caller can surface the latest scan with full context. Read-only; never throws.
41
+ */
42
+ export declare function openScheduleResult(stateCwd: string, id: string): OpenResult;
30
43
  /** Run handler entry used by `omp schedule run|run-now`. Missing job → clean no-op (exit 0). */
31
44
  export declare function runScheduleById(stateCwd: string, id: string): Promise<{
32
45
  ok: boolean;
@@ -1,5 +1,5 @@
1
1
  import { execFileSync } from "node:child_process";
2
- import { existsSync, statSync, unlinkSync } from "node:fs";
2
+ import { existsSync, readFileSync, statSync, unlinkSync } from "node:fs";
3
3
  import { getInstalledStatus, installJob, uninstallJob } from "./installer.js";
4
4
  import { deleteJob, listJobs, readJob, writeJob } from "./job-store.js";
5
5
  import { ensureScheduleDirs, jobFilePath, jobLockPath, resolveSchedulePaths, } from "./paths.js";
@@ -65,6 +65,8 @@ export function addScheduleJob(stateCwd, opts) {
65
65
  ompBinPath: resolveOmpBinPath(),
66
66
  active: true,
67
67
  notifyTarget: opts.notifyTarget,
68
+ notifyDesktop: opts.notifyDesktop ?? false,
69
+ notifyOpenOmp: opts.notifyOpenOmp ?? false,
68
70
  };
69
71
  if (opts.dryRun) {
70
72
  messages.push(`[dry-run] would install job "${job.id}" (cron ${job.cron}) for agent ${job.bin} in ${job.cwd}`);
@@ -116,6 +118,27 @@ export function getScheduleStatus(stateCwd, id) {
116
118
  const job = readJob(jobFilePath(paths.jobsDir, id));
117
119
  return { job, osInstalled: job ? getInstalledStatus(id, job.backend) : false };
118
120
  }
121
+ /**
122
+ * Resolve a job's latest run for `omp schedule open <id>` — the by-id substitute
123
+ * for clicking a notification: returns the job plus the full captured log so the
124
+ * caller can surface the latest scan with full context. Read-only; never throws.
125
+ */
126
+ export function openScheduleResult(stateCwd, id) {
127
+ const paths = resolveSchedulePaths(stateCwd);
128
+ const job = readJob(jobFilePath(paths.jobsDir, id));
129
+ if (!job)
130
+ return { ok: false, error: `no schedule job "${id}"` };
131
+ let logContent;
132
+ if (job.lastLogPath && existsSync(job.lastLogPath)) {
133
+ try {
134
+ logContent = readFileSync(job.lastLogPath, "utf8");
135
+ }
136
+ catch {
137
+ // log unreadable — still return the job metadata
138
+ }
139
+ }
140
+ return { ok: true, job, logContent };
141
+ }
119
142
  /** Run handler entry used by `omp schedule run|run-now`. Missing job → clean no-op (exit 0). */
120
143
  export async function runScheduleById(stateCwd, id) {
121
144
  const paths = resolveSchedulePaths(stateCwd);
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/schedule/commands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../src/schedule/commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /** The launcher script body: cd into the job cwd and exec an interactive omp. */
2
+ export declare function buildOpenOmpScript(cwd: string, ompBinPath: string): string;
3
+ /** Write the executable launcher into the job's log dir; return its absolute path. */
4
+ export declare function writeOpenOmpLauncher(logDir: string, cwd: string, ompBinPath: string): string;
5
+ export interface OpenTargetInput {
6
+ platform: NodeJS.Platform;
7
+ notifyOpenOmp: boolean;
8
+ logDir: string;
9
+ logPath: string;
10
+ cwd: string;
11
+ ompBinPath: string;
12
+ }
13
+ /**
14
+ * Resolve the notification's click target. The "open omp" launcher is macOS-only
15
+ * (it relies on `.command` files opening in Terminal); everywhere else we fall
16
+ * back to opening the raw run log.
17
+ */
18
+ export declare function resolveOpenTarget(input: OpenTargetInput): string;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Deep-link target for a scheduled run's desktop notification.
3
+ *
4
+ * node-notifier's `open` field is opened by the OS notification daemon on click,
5
+ * so it survives the fire-and-exit cron process. We resolve it to one of:
6
+ * - the raw per-run log file (`file://<logPath>`) — the default, cross-platform; or
7
+ * - (macOS + notifyOpenOmp) a generated `.command` launcher that opens an
8
+ * interactive `omp` in the job's cwd; the SessionStart `[SCHEDULE RESULTS]`
9
+ * banner then surfaces the latest run — i.e. "opens omp ready to engage".
10
+ */
11
+ import { writeFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { pathToFileURL } from "node:url";
14
+ /** POSIX single-quote escaping: wrap in '…', closing/escaping any embedded quote. */
15
+ function shellQuote(s) {
16
+ return `'${s.replace(/'/g, "'\\''")}'`;
17
+ }
18
+ /** The launcher script body: cd into the job cwd and exec an interactive omp. */
19
+ export function buildOpenOmpScript(cwd, ompBinPath) {
20
+ // `--` ends option parsing so a dash-leading cwd/bin can't be read as a flag.
21
+ return `#!/bin/sh\ncd -- ${shellQuote(cwd)} && exec -- ${shellQuote(ompBinPath)}\n`;
22
+ }
23
+ /** Write the executable launcher into the job's log dir; return its absolute path. */
24
+ export function writeOpenOmpLauncher(logDir, cwd, ompBinPath) {
25
+ const launcherPath = join(logDir, "open-omp.command");
26
+ writeFileSync(launcherPath, buildOpenOmpScript(cwd, ompBinPath), { mode: 0o755 });
27
+ return launcherPath;
28
+ }
29
+ /**
30
+ * Resolve the notification's click target. The "open omp" launcher is macOS-only
31
+ * (it relies on `.command` files opening in Terminal); everywhere else we fall
32
+ * back to opening the raw run log.
33
+ */
34
+ export function resolveOpenTarget(input) {
35
+ if (input.notifyOpenOmp && input.platform === "darwin") {
36
+ const launcher = writeOpenOmpLauncher(input.logDir, input.cwd, input.ompBinPath);
37
+ return pathToFileURL(launcher).href;
38
+ }
39
+ return pathToFileURL(input.logPath).href;
40
+ }
41
+ //# sourceMappingURL=deep-link.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deep-link.js","sourceRoot":"","sources":["../../../src/schedule/deep-link.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,qFAAqF;AACrF,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC;AACzC,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,UAAkB;IAChE,8EAA8E;IAC9E,OAAO,oBAAoB,UAAU,CAAC,GAAG,CAAC,eAAe,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;AACtF,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,GAAW,EAAE,UAAkB;IAClF,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACtD,aAAa,CAAC,YAAY,EAAE,kBAAkB,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAClF,OAAO,YAAY,CAAC;AACtB,CAAC;AAWD;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB;IACtD,IAAI,KAAK,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACvD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QACjF,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC;IACtC,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { type SchedulePaths } from "./paths.js";
2
2
  import { type ScheduleJob, type ScheduleRunResult } from "./types.js";
3
+ import type { DesktopNotifyOptions } from "../gateway/desktop-notify.js";
3
4
  export interface RunOptions {
4
5
  /** Called when a job has expired (TTL passed or maxRuns reached) so the caller can uninstall the OS entry. */
5
6
  onExpire?: (job: ScheduleJob) => void;
@@ -12,6 +13,15 @@ export interface RunOptions {
12
13
  ok: boolean;
13
14
  reason?: string;
14
15
  }>;
16
+ /**
17
+ * Override the desktop-notify implementation (tests). Defaults to
18
+ * `gateway/desktop-notify.notifyDesktop`. Failures are logged to stderr only
19
+ * and never propagate into the job result.
20
+ */
21
+ notifyDesktop?: (opts: DesktopNotifyOptions) => Promise<{
22
+ ok: boolean;
23
+ reason?: string;
24
+ }>;
15
25
  }
16
26
  /** Execute one scheduled run (expiry check, overlap lock, timeout, log capture, result append). */
17
27
  export declare function runScheduledJob(job: ScheduleJob, paths: SchedulePaths, opts?: RunOptions): Promise<ScheduleRunResult>;
@@ -5,6 +5,7 @@ import { resolveCopilotBin } from "../copilot/launch.js";
5
5
  import { appendRunResult, readJob, writeJob } from "./job-store.js";
6
6
  import { acquireLock, forceReleaseStaleLock, isLockStale } from "./lock.js";
7
7
  import { jobFilePath, jobLockPath, resultsFilePath, runLogDir } from "./paths.js";
8
+ import { resolveOpenTarget } from "./deep-link.js";
8
9
  import { DEFAULT_TIMEOUT_MS } from "./types.js";
9
10
  function isExpired(job) {
10
11
  if (job.maxRuns !== undefined && job.runCount >= job.maxRuns)
@@ -171,6 +172,41 @@ export async function runScheduledJob(job, paths, opts = {}) {
171
172
  process.stderr.write(`schedule: notify crashed for ${job.id}: ${msg}\n`);
172
173
  }
173
174
  }
175
+ // Best-effort end-of-run desktop notification. Independent of (and combinable
176
+ // with) the Slack post above; same failure-isolation contract. The disable
177
+ // kill-switch is honored up front so a disabled run writes no launcher artifact.
178
+ if (job.notifyDesktop && !(process.env.OMP_DISABLE_DESKTOP_NOTIFY ?? "").trim()) {
179
+ try {
180
+ const open = resolveOpenTarget({
181
+ platform: process.platform,
182
+ notifyOpenOmp: job.notifyOpenOmp ?? false,
183
+ logDir: runLogDir(paths.logsDir, job.id),
184
+ logPath: result.logPath,
185
+ // Open the schedule STATE ROOT (where the [SCHEDULE RESULTS] banner
186
+ // reads from), not job.cwd — they can differ when --cwd is set.
187
+ cwd: paths.cwd,
188
+ ompBinPath: job.ompBinPath,
189
+ });
190
+ const notifyDesktop = opts.notifyDesktop ??
191
+ (async (o) => {
192
+ const { notifyDesktop: realNotify } = await import("../gateway/desktop-notify.js");
193
+ const r = await realNotify(o);
194
+ return r.ok ? { ok: true } : { ok: false, reason: r.reason };
195
+ });
196
+ const r = await notifyDesktop({
197
+ title: `schedule: ${job.id}`,
198
+ message: `${result.status} — ${result.summary}`,
199
+ open,
200
+ });
201
+ if (!r.ok) {
202
+ process.stderr.write(`schedule: desktop notify failed for ${job.id}: ${r.reason ?? "unknown"}\n`);
203
+ }
204
+ }
205
+ catch (err) {
206
+ const msg = err instanceof Error ? err.message : String(err);
207
+ process.stderr.write(`schedule: desktop notify crashed for ${job.id}: ${msg}\n`);
208
+ }
209
+ }
174
210
  return result;
175
211
  }
176
212
  finally {