@sigil0/looking-glass 0.1.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 (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +572 -0
  3. package/dist/agents/coordinator.d.ts +21 -0
  4. package/dist/agents/coordinator.d.ts.map +1 -0
  5. package/dist/agents/coordinator.js +171 -0
  6. package/dist/agents/coordinator.js.map +1 -0
  7. package/dist/app.d.ts +44 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +215 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +419 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config.d.ts +4 -0
  16. package/dist/config.d.ts.map +1 -0
  17. package/dist/config.js +132 -0
  18. package/dist/config.js.map +1 -0
  19. package/dist/engine/context.d.ts +6 -0
  20. package/dist/engine/context.d.ts.map +1 -0
  21. package/dist/engine/context.js +65 -0
  22. package/dist/engine/context.js.map +1 -0
  23. package/dist/engine/engine.d.ts +74 -0
  24. package/dist/engine/engine.d.ts.map +1 -0
  25. package/dist/engine/engine.js +573 -0
  26. package/dist/engine/engine.js.map +1 -0
  27. package/dist/engine/types.d.ts +35 -0
  28. package/dist/engine/types.d.ts.map +1 -0
  29. package/dist/engine/types.js +2 -0
  30. package/dist/engine/types.js.map +1 -0
  31. package/dist/instructions.d.ts +8 -0
  32. package/dist/instructions.d.ts.map +1 -0
  33. package/dist/instructions.js +60 -0
  34. package/dist/instructions.js.map +1 -0
  35. package/dist/model/codex-lb.d.ts +141 -0
  36. package/dist/model/codex-lb.d.ts.map +1 -0
  37. package/dist/model/codex-lb.js +471 -0
  38. package/dist/model/codex-lb.js.map +1 -0
  39. package/dist/paths.d.ts +7 -0
  40. package/dist/paths.d.ts.map +1 -0
  41. package/dist/paths.js +41 -0
  42. package/dist/paths.js.map +1 -0
  43. package/dist/scheduler/daemon.d.ts +40 -0
  44. package/dist/scheduler/daemon.d.ts.map +1 -0
  45. package/dist/scheduler/daemon.js +189 -0
  46. package/dist/scheduler/daemon.js.map +1 -0
  47. package/dist/scheduler/index.d.ts +8 -0
  48. package/dist/scheduler/index.d.ts.map +1 -0
  49. package/dist/scheduler/index.js +6 -0
  50. package/dist/scheduler/index.js.map +1 -0
  51. package/dist/scheduler/runner.d.ts +18 -0
  52. package/dist/scheduler/runner.d.ts.map +1 -0
  53. package/dist/scheduler/runner.js +173 -0
  54. package/dist/scheduler/runner.js.map +1 -0
  55. package/dist/scheduler/schedule.d.ts +7 -0
  56. package/dist/scheduler/schedule.d.ts.map +1 -0
  57. package/dist/scheduler/schedule.js +94 -0
  58. package/dist/scheduler/schedule.js.map +1 -0
  59. package/dist/scheduler/store.d.ts +55 -0
  60. package/dist/scheduler/store.d.ts.map +1 -0
  61. package/dist/scheduler/store.js +1203 -0
  62. package/dist/scheduler/store.js.map +1 -0
  63. package/dist/scheduler/systemd.d.ts +7 -0
  64. package/dist/scheduler/systemd.d.ts.map +1 -0
  65. package/dist/scheduler/systemd.js +97 -0
  66. package/dist/scheduler/systemd.js.map +1 -0
  67. package/dist/scheduler/types.d.ts +145 -0
  68. package/dist/scheduler/types.d.ts.map +1 -0
  69. package/dist/scheduler/types.js +7 -0
  70. package/dist/scheduler/types.js.map +1 -0
  71. package/dist/security.d.ts +6 -0
  72. package/dist/security.d.ts.map +1 -0
  73. package/dist/security.js +27 -0
  74. package/dist/security.js.map +1 -0
  75. package/dist/storage/artifact-store.d.ts +19 -0
  76. package/dist/storage/artifact-store.d.ts.map +1 -0
  77. package/dist/storage/artifact-store.js +47 -0
  78. package/dist/storage/artifact-store.js.map +1 -0
  79. package/dist/storage/database.d.ts +5 -0
  80. package/dist/storage/database.d.ts.map +1 -0
  81. package/dist/storage/database.js +395 -0
  82. package/dist/storage/database.js.map +1 -0
  83. package/dist/storage/session-store.d.ts +114 -0
  84. package/dist/storage/session-store.d.ts.map +1 -0
  85. package/dist/storage/session-store.js +731 -0
  86. package/dist/storage/session-store.js.map +1 -0
  87. package/dist/tools/agents.d.ts +14 -0
  88. package/dist/tools/agents.d.ts.map +1 -0
  89. package/dist/tools/agents.js +35 -0
  90. package/dist/tools/agents.js.map +1 -0
  91. package/dist/tools/apply-patch.d.ts +7 -0
  92. package/dist/tools/apply-patch.d.ts.map +1 -0
  93. package/dist/tools/apply-patch.js +429 -0
  94. package/dist/tools/apply-patch.js.map +1 -0
  95. package/dist/tools/ask.d.ts +8 -0
  96. package/dist/tools/ask.d.ts.map +1 -0
  97. package/dist/tools/ask.js +27 -0
  98. package/dist/tools/ask.js.map +1 -0
  99. package/dist/tools/bash.d.ts +9 -0
  100. package/dist/tools/bash.d.ts.map +1 -0
  101. package/dist/tools/bash.js +98 -0
  102. package/dist/tools/bash.js.map +1 -0
  103. package/dist/tools/index.d.ts +9 -0
  104. package/dist/tools/index.d.ts.map +1 -0
  105. package/dist/tools/index.js +34 -0
  106. package/dist/tools/index.js.map +1 -0
  107. package/dist/tools/paths.d.ts +3 -0
  108. package/dist/tools/paths.d.ts.map +1 -0
  109. package/dist/tools/paths.js +34 -0
  110. package/dist/tools/paths.js.map +1 -0
  111. package/dist/tools/process.d.ts +21 -0
  112. package/dist/tools/process.d.ts.map +1 -0
  113. package/dist/tools/process.js +104 -0
  114. package/dist/tools/process.js.map +1 -0
  115. package/dist/tools/read.d.ts +9 -0
  116. package/dist/tools/read.d.ts.map +1 -0
  117. package/dist/tools/read.js +95 -0
  118. package/dist/tools/read.js.map +1 -0
  119. package/dist/tools/registry.d.ts +19 -0
  120. package/dist/tools/registry.d.ts.map +1 -0
  121. package/dist/tools/registry.js +188 -0
  122. package/dist/tools/registry.js.map +1 -0
  123. package/dist/tools/safety.d.ts +9 -0
  124. package/dist/tools/safety.d.ts.map +1 -0
  125. package/dist/tools/safety.js +199 -0
  126. package/dist/tools/safety.js.map +1 -0
  127. package/dist/tools/schedule.d.ts +4 -0
  128. package/dist/tools/schedule.d.ts.map +1 -0
  129. package/dist/tools/schedule.js +191 -0
  130. package/dist/tools/schedule.js.map +1 -0
  131. package/dist/tools/search.d.ts +16 -0
  132. package/dist/tools/search.d.ts.map +1 -0
  133. package/dist/tools/search.js +75 -0
  134. package/dist/tools/search.js.map +1 -0
  135. package/dist/tools/types.d.ts +54 -0
  136. package/dist/tools/types.d.ts.map +1 -0
  137. package/dist/tools/types.js +10 -0
  138. package/dist/tools/types.js.map +1 -0
  139. package/dist/types.d.ts +90 -0
  140. package/dist/types.d.ts.map +1 -0
  141. package/dist/types.js +2 -0
  142. package/dist/types.js.map +1 -0
  143. package/dist/ui/stdio.d.ts +5 -0
  144. package/dist/ui/stdio.d.ts.map +1 -0
  145. package/dist/ui/stdio.js +65 -0
  146. package/dist/ui/stdio.js.map +1 -0
  147. package/dist/ui/tui.d.ts +93 -0
  148. package/dist/ui/tui.d.ts.map +1 -0
  149. package/dist/ui/tui.js +2246 -0
  150. package/dist/ui/tui.js.map +1 -0
  151. package/package.json +53 -0
@@ -0,0 +1,189 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { hostname } from "node:os";
3
+ import { CommandRunner, SessionPromptRunner } from "./runner.js";
4
+ function positiveInteger(value, name, maximum = 2_147_483_647) {
5
+ if (!Number.isSafeInteger(value) || value < 1 || value > maximum) {
6
+ throw new Error(`${name} must be an integer between 1 and ${maximum}`);
7
+ }
8
+ return value;
9
+ }
10
+ function wait(ms, signal) {
11
+ return new Promise((resolve) => {
12
+ if (signal.aborted) {
13
+ resolve();
14
+ return;
15
+ }
16
+ const timer = setTimeout(done, ms);
17
+ signal.addEventListener("abort", done, { once: true });
18
+ function done() {
19
+ clearTimeout(timer);
20
+ signal.removeEventListener("abort", done);
21
+ resolve();
22
+ }
23
+ });
24
+ }
25
+ export class SchedulerDaemon {
26
+ store;
27
+ owner;
28
+ bootId;
29
+ runner;
30
+ sessionPromptRunner;
31
+ pollIntervalMs;
32
+ leaseMs;
33
+ maxConcurrentCommands;
34
+ materializeBatchSize;
35
+ running = new Set();
36
+ commandSignal;
37
+ commandAbort;
38
+ firstWorkerError;
39
+ hasWorkerError = false;
40
+ constructor(store, options) {
41
+ this.store = store;
42
+ this.pollIntervalMs = positiveInteger(options.pollIntervalMs, "pollIntervalMs");
43
+ this.leaseMs = positiveInteger(options.leaseMs, "leaseMs");
44
+ this.maxConcurrentCommands = positiveInteger(options.maxConcurrentCommands, "maxConcurrentCommands", 1_000);
45
+ this.materializeBatchSize = positiveInteger(options.materializeBatchSize ?? 100, "materializeBatchSize", 10_000);
46
+ this.owner = options.owner ?? `${hostname()}:${process.pid}`;
47
+ this.bootId = options.bootId ?? randomUUID();
48
+ this.runner = new CommandRunner(store, options.sensitiveEnvKeys);
49
+ this.sessionPromptRunner = options.sessionPromptHandler
50
+ ? new SessionPromptRunner(store, options.sessionPromptHandler, options.sensitiveEnvKeys)
51
+ : undefined;
52
+ }
53
+ async run(signal) {
54
+ if (this.running.size > 0 || this.commandAbort)
55
+ throw new Error("Scheduler daemon is already running");
56
+ this.firstWorkerError = undefined;
57
+ this.hasWorkerError = false;
58
+ const startedAt = Date.now();
59
+ if (!this.store.acquireLease(this.owner, this.bootId, startedAt, this.leaseMs)) {
60
+ throw new Error("Another scheduler daemon holds the lease");
61
+ }
62
+ const internalAbort = new AbortController();
63
+ this.commandAbort = internalAbort;
64
+ this.commandSignal = AbortSignal.any([signal, internalAbort.signal]);
65
+ const heartbeatInterval = Math.max(1, Math.floor(this.leaseMs / 3));
66
+ let nextPoll = startedAt;
67
+ let nextHeartbeat = startedAt + heartbeatInterval;
68
+ let loopError;
69
+ let hasLoopError = false;
70
+ let cleanupError;
71
+ let hasCleanupError = false;
72
+ try {
73
+ while (!this.commandSignal.aborted) {
74
+ const now = Date.now();
75
+ if (now >= nextHeartbeat) {
76
+ if (!this.store.renewLease(this.owner, this.bootId, now, this.leaseMs)) {
77
+ internalAbort.abort();
78
+ throw new Error("Scheduler daemon lost its lease");
79
+ }
80
+ nextHeartbeat = now + heartbeatInterval;
81
+ }
82
+ if (now >= nextPoll) {
83
+ await this.tick();
84
+ nextPoll = Date.now() + this.pollIntervalMs;
85
+ }
86
+ await wait(Math.max(1, Math.min(nextPoll, nextHeartbeat) - Date.now()), this.commandSignal);
87
+ }
88
+ }
89
+ catch (error) {
90
+ loopError = error;
91
+ hasLoopError = true;
92
+ }
93
+ finally {
94
+ internalAbort.abort();
95
+ try {
96
+ await this.settleWorkersWithLease();
97
+ }
98
+ catch (error) {
99
+ cleanupError = error;
100
+ hasCleanupError = true;
101
+ }
102
+ try {
103
+ this.store.releaseLease(this.owner, this.bootId);
104
+ }
105
+ catch (error) {
106
+ cleanupError = error;
107
+ hasCleanupError = true;
108
+ }
109
+ finally {
110
+ this.commandSignal = undefined;
111
+ this.commandAbort = undefined;
112
+ }
113
+ }
114
+ if (this.hasWorkerError)
115
+ throw this.firstWorkerError;
116
+ if (hasLoopError)
117
+ throw loopError;
118
+ if (hasCleanupError)
119
+ throw cleanupError;
120
+ }
121
+ async tick(now) {
122
+ if (this.hasWorkerError)
123
+ throw this.firstWorkerError;
124
+ const materialized = this.store.materialize(now ?? Date.now(), this.materializeBatchSize);
125
+ const available = this.maxConcurrentCommands - this.running.size;
126
+ if (available <= 0)
127
+ return { materialized: materialized.length, claimed: 0 };
128
+ const claimNow = now ?? Date.now();
129
+ const commandClaims = this.store.claimCommands(this.owner, this.bootId, claimNow, this.leaseMs, available);
130
+ for (const claim of commandClaims) {
131
+ let task;
132
+ task = this.runner.run(claim, this.commandSignal)
133
+ .then(() => undefined)
134
+ .catch((error) => this.captureWorkerError(error))
135
+ .finally(() => this.running.delete(task));
136
+ this.running.add(task);
137
+ }
138
+ const sessionAvailable = available - commandClaims.length;
139
+ const sessionClaims = this.sessionPromptRunner && sessionAvailable > 0
140
+ ? this.store.claimSessionPrompts(this.owner, this.bootId, claimNow, this.leaseMs, sessionAvailable)
141
+ : [];
142
+ for (const claim of sessionClaims) {
143
+ let task;
144
+ task = this.sessionPromptRunner.run(claim, this.commandSignal)
145
+ .then(() => undefined)
146
+ .catch((error) => this.captureWorkerError(error))
147
+ .finally(() => this.running.delete(task));
148
+ this.running.add(task);
149
+ }
150
+ return { materialized: materialized.length, claimed: commandClaims.length + sessionClaims.length };
151
+ }
152
+ async waitForIdle() {
153
+ await this.settleWorkers();
154
+ if (this.hasWorkerError)
155
+ throw this.firstWorkerError;
156
+ }
157
+ captureWorkerError(error) {
158
+ if (!this.hasWorkerError) {
159
+ this.firstWorkerError = error;
160
+ this.hasWorkerError = true;
161
+ }
162
+ this.commandAbort?.abort();
163
+ }
164
+ async settleWorkers() {
165
+ await Promise.all([...this.running]);
166
+ }
167
+ async settleWorkersWithLease() {
168
+ const heartbeatInterval = Math.max(1, Math.floor(this.leaseMs / 3));
169
+ while (this.running.size > 0) {
170
+ let timer;
171
+ await Promise.race([
172
+ Promise.all([...this.running]),
173
+ new Promise((resolve) => {
174
+ timer = setTimeout(resolve, heartbeatInterval);
175
+ timer.unref();
176
+ }),
177
+ ]);
178
+ if (timer)
179
+ clearTimeout(timer);
180
+ if (this.running.size > 0) {
181
+ const now = Date.now();
182
+ if (!this.store.renewLease(this.owner, this.bootId, now, this.leaseMs)) {
183
+ throw new Error("Scheduler daemon lost its lease while stopping command workers");
184
+ }
185
+ }
186
+ }
187
+ }
188
+ }
189
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/scheduler/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { SchedulerDaemon } from "./daemon.js";
2
+ export type { SchedulerDaemonOptions, SchedulerTickResult } from "./daemon.js";
3
+ export { CommandRunner, scheduledSessionReadOnly, SessionPromptRunner } from "./runner.js";
4
+ export { initialDue, nextCronDue, parseOnceSchedule, validateSchedule, validateTimezone } from "./schedule.js";
5
+ export { SchedulerStore } from "./store.js";
6
+ export { installService, renderUnit, serviceStatus, uninstallService, userUnitPath } from "./systemd.js";
7
+ export type { ClaimedCommand, ClaimedSessionPrompt, CommandCompletion, CreateCommandInput, CreateReminderInput, CreateSessionPromptInput, DaemonLease, InboxRecord, JobKind, Occurrence, OccurrenceState, ScheduleKind, SchedulerJob, SessionPromptCompletion, SessionPromptHandler, } from "./types.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC/E,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACzG,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,EACnB,wBAAwB,EACxB,WAAW,EACX,WAAW,EACX,OAAO,EACP,UAAU,EACV,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { SchedulerDaemon } from "./daemon.js";
2
+ export { CommandRunner, scheduledSessionReadOnly, SessionPromptRunner } from "./runner.js";
3
+ export { initialDue, nextCronDue, parseOnceSchedule, validateSchedule, validateTimezone } from "./schedule.js";
4
+ export { SchedulerStore } from "./store.js";
5
+ export { installService, renderUnit, serviceStatus, uninstallService, userUnitPath } from "./systemd.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scheduler/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,EAAE,aAAa,EAAE,wBAAwB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC/G,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,aAAa,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { ClaimedCommand, ClaimedSessionPrompt, Occurrence, SessionPromptHandler } from "./types.js";
2
+ import { SchedulerStore } from "./store.js";
3
+ import type { ApprovalMode } from "../types.js";
4
+ export declare function scheduledSessionReadOnly(approvalMode: ApprovalMode): boolean;
5
+ export declare class CommandRunner {
6
+ private readonly store;
7
+ private readonly sensitiveEnvKeys;
8
+ constructor(store: SchedulerStore, sensitiveEnvKeys?: readonly string[]);
9
+ run(claim: ClaimedCommand, signal?: AbortSignal): Promise<Occurrence>;
10
+ }
11
+ export declare class SessionPromptRunner {
12
+ private readonly store;
13
+ private readonly handler;
14
+ private readonly sensitiveEnvKeys;
15
+ constructor(store: SchedulerStore, handler: SessionPromptHandler, sensitiveEnvKeys?: readonly string[]);
16
+ run(claim: ClaimedSessionPrompt, signal?: AbortSignal): Promise<Occurrence>;
17
+ }
18
+ //# sourceMappingURL=runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/scheduler/runner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EAEpB,UAAU,EAEV,oBAAoB,EACrB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhD,wBAAgB,wBAAwB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAE5E;AAkBD,qBAAa,aAAa;IAEtB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBADhB,KAAK,EAAE,cAAc,EACrB,gBAAgB,GAAE,SAAS,MAAM,EAAO;IAGrD,GAAG,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA6E5E;AAED,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;gBAFhB,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,oBAAoB,EAC7B,gBAAgB,GAAE,SAAS,MAAM,EAAO;IAGrD,GAAG,CAAC,KAAK,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAqElF"}
@@ -0,0 +1,173 @@
1
+ import { runProcess } from "../tools/process.js";
2
+ import { shellEnvironment } from "../tools/safety.js";
3
+ import { sessionPromptReservation } from "./types.js";
4
+ import { redactSensitiveText } from "../security.js";
5
+ export function scheduledSessionReadOnly(approvalMode) {
6
+ return approvalMode !== "unrestricted";
7
+ }
8
+ function failedCompletion(error) {
9
+ const message = error instanceof Error ? error.message : String(error);
10
+ return {
11
+ state: "failed",
12
+ exitCode: null,
13
+ signal: null,
14
+ reason: `Failed to start command: ${message}`,
15
+ stdout: Buffer.alloc(0),
16
+ stderr: Buffer.alloc(0),
17
+ stdoutBytes: 0,
18
+ stderrBytes: 0,
19
+ stdoutTruncated: false,
20
+ stderrTruncated: false,
21
+ };
22
+ }
23
+ export class CommandRunner {
24
+ store;
25
+ sensitiveEnvKeys;
26
+ constructor(store, sensitiveEnvKeys = []) {
27
+ this.store = store;
28
+ this.sensitiveEnvKeys = sensitiveEnvKeys;
29
+ }
30
+ async run(claim, signal) {
31
+ const { job, occurrence } = claim;
32
+ const token = occurrence.claimToken;
33
+ const started = this.store.startClaimedCommand(occurrence.id, token, occurrence.claimOwner, occurrence.claimBootId);
34
+ if (!started)
35
+ throw new Error("Scheduler command lost its lease or claim before start");
36
+ if (started.state !== "running")
37
+ return started;
38
+ let completion;
39
+ if (signal?.aborted) {
40
+ completion = {
41
+ state: "cancelled",
42
+ exitCode: null,
43
+ signal: null,
44
+ reason: "Scheduler daemon stopped before the command started",
45
+ stdout: Buffer.alloc(0),
46
+ stderr: Buffer.alloc(0),
47
+ stdoutBytes: 0,
48
+ stderrBytes: 0,
49
+ stdoutTruncated: false,
50
+ stderrTruncated: false,
51
+ };
52
+ }
53
+ else {
54
+ try {
55
+ const result = await runProcess("/bin/bash", ["--noprofile", "--norc", "-c", job.command], {
56
+ cwd: job.cwd,
57
+ env: shellEnvironment({ ...process.env, ...job.env }, this.sensitiveEnvKeys),
58
+ timeoutMs: job.timeoutMs ?? 1,
59
+ captureBytes: job.outputBytes ?? 0,
60
+ ...(signal ? { signal } : {}),
61
+ detached: true,
62
+ });
63
+ const state = signal?.aborted
64
+ ? "unknown"
65
+ : result.timedOut
66
+ ? "timed_out"
67
+ : result.exitCode === 0 && result.signal === null
68
+ ? "succeeded"
69
+ : "failed";
70
+ let reason = null;
71
+ if (state === "unknown")
72
+ reason = "Scheduler daemon stopped while the command was running; its outcome is unknown";
73
+ else if (state === "timed_out")
74
+ reason = `Command exceeded its ${job.timeoutMs ?? 0}ms timeout`;
75
+ else if (state === "failed" && result.signal)
76
+ reason = `Command terminated by ${result.signal}`;
77
+ else if (state === "failed")
78
+ reason = `Command exited with code ${result.exitCode ?? "unknown"}`;
79
+ const secrets = this.sensitiveEnvKeys
80
+ .map((key) => process.env[key])
81
+ .filter((value) => typeof value === "string" && value.length >= 8);
82
+ completion = {
83
+ state,
84
+ exitCode: result.exitCode,
85
+ signal: result.signal,
86
+ reason,
87
+ stdout: Buffer.from(redactSensitiveText(result.stdout.toString("utf8"), secrets)),
88
+ stderr: Buffer.from(redactSensitiveText(result.stderr.toString("utf8"), secrets)),
89
+ stdoutBytes: result.stdoutBytes,
90
+ stderrBytes: result.stderrBytes,
91
+ stdoutTruncated: result.stdoutTruncated,
92
+ stderrTruncated: result.stderrTruncated,
93
+ };
94
+ }
95
+ catch (error) {
96
+ completion = failedCompletion(error);
97
+ }
98
+ }
99
+ const finished = this.store.finishCommand(occurrence.id, token, occurrence.claimOwner, occurrence.claimBootId, completion);
100
+ if (!finished)
101
+ throw new Error("Scheduler command result could not be persisted after lease or claim loss");
102
+ return finished;
103
+ }
104
+ }
105
+ export class SessionPromptRunner {
106
+ store;
107
+ handler;
108
+ sensitiveEnvKeys;
109
+ constructor(store, handler, sensitiveEnvKeys = []) {
110
+ this.store = store;
111
+ this.handler = handler;
112
+ this.sensitiveEnvKeys = sensitiveEnvKeys;
113
+ }
114
+ async run(claim, signal) {
115
+ const { job, occurrence } = claim;
116
+ const token = occurrence.claimToken;
117
+ const started = this.store.startClaimedSessionPrompt(occurrence.id, token, occurrence.claimOwner, occurrence.claimBootId);
118
+ if (!started)
119
+ throw new Error("Scheduler session prompt lost its lease or claim before start");
120
+ if (started.state !== "running")
121
+ return started;
122
+ const reservation = sessionPromptReservation(occurrence.claimOwner, occurrence.claimBootId, occurrence.claimToken);
123
+ const handlerSignal = signal ?? new AbortController().signal;
124
+ let completion;
125
+ try {
126
+ if (handlerSignal.aborted) {
127
+ completion = {
128
+ state: "cancelled",
129
+ reason: "Scheduler daemon stopped before the session prompt started",
130
+ };
131
+ }
132
+ else {
133
+ try {
134
+ const secrets = this.sensitiveEnvKeys
135
+ .map((key) => process.env[key])
136
+ .filter((value) => typeof value === "string" && value.length >= 8);
137
+ const output = redactSensitiveText(await this.handler(job, handlerSignal, reservation), secrets);
138
+ completion = handlerSignal.aborted
139
+ ? {
140
+ state: "unknown",
141
+ reason: "Scheduler daemon stopped while the session prompt was running; its outcome is unknown",
142
+ }
143
+ : { state: "succeeded", output, reason: null };
144
+ }
145
+ catch (error) {
146
+ const secrets = this.sensitiveEnvKeys
147
+ .map((key) => process.env[key])
148
+ .filter((value) => typeof value === "string" && value.length >= 8);
149
+ const message = redactSensitiveText(error instanceof Error ? error.message : String(error), secrets);
150
+ completion = handlerSignal.aborted
151
+ ? {
152
+ state: "unknown",
153
+ error: message,
154
+ reason: "Scheduler daemon stopped while the session prompt was running; its outcome is unknown",
155
+ }
156
+ : {
157
+ state: "failed",
158
+ error: message,
159
+ reason: `Session prompt failed: ${message}`,
160
+ };
161
+ }
162
+ }
163
+ }
164
+ finally {
165
+ this.store.releaseSessionPromptReservation(job.sessionId, reservation.owner, reservation.token);
166
+ }
167
+ const finished = this.store.finishSessionPrompt(occurrence.id, token, occurrence.claimOwner, occurrence.claimBootId, completion);
168
+ if (!finished)
169
+ throw new Error("Scheduler session prompt result could not be persisted after lease or claim loss");
170
+ return finished;
171
+ }
172
+ }
173
+ //# sourceMappingURL=runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/scheduler/runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function rejectNul(value: string, field: string): void;
2
+ export declare function validateTimezone(timezone: string): void;
3
+ export declare function parseOnceSchedule(schedule: string): number;
4
+ export declare function validateSchedule(kind: "once" | "cron", schedule: string, timezone: string): void;
5
+ export declare function initialDue(kind: "once" | "cron", schedule: string, timezone: string, now: number): number;
6
+ export declare function nextCronDue(schedule: string, timezone: string, scheduledAt: number): number;
7
+ //# sourceMappingURL=schedule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.d.ts","sourceRoot":"","sources":["../../src/scheduler/schedule.ts"],"names":[],"mappings":"AAIA,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQvD;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuC1D;AAgBD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAQhG;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAIzG;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAM3F"}
@@ -0,0 +1,94 @@
1
+ import { Cron } from "croner";
2
+ const ISO_WITH_OFFSET = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{1,3}))?)?(Z|[+-]\d{2}:\d{2})$/;
3
+ export function rejectNul(value, field) {
4
+ if (value.includes("\0"))
5
+ throw new Error(`${field} must not contain NUL bytes`);
6
+ }
7
+ export function validateTimezone(timezone) {
8
+ rejectNul(timezone, "timezone");
9
+ if (timezone.length === 0)
10
+ throw new Error("timezone must not be empty");
11
+ try {
12
+ new Intl.DateTimeFormat("en-US", { timeZone: timezone }).format(0);
13
+ }
14
+ catch {
15
+ throw new Error(`Invalid timezone: ${timezone}`);
16
+ }
17
+ }
18
+ export function parseOnceSchedule(schedule) {
19
+ rejectNul(schedule, "schedule");
20
+ const match = ISO_WITH_OFFSET.exec(schedule);
21
+ if (!match)
22
+ throw new Error("One-shot schedule must be an ISO datetime with Z or an explicit offset");
23
+ const year = Number(match[1]);
24
+ const month = Number(match[2]);
25
+ const day = Number(match[3]);
26
+ const hour = Number(match[4]);
27
+ const minute = Number(match[5]);
28
+ const second = Number(match[6] ?? "0");
29
+ const millisecond = Number((match[7] ?? "").padEnd(3, "0"));
30
+ const offset = match[8];
31
+ if (month < 1 || month > 12 || hour > 23 || minute > 59 || second > 59) {
32
+ throw new Error(`Invalid one-shot schedule: ${schedule}`);
33
+ }
34
+ if (offset !== "Z") {
35
+ const offsetHour = Number(offset?.slice(1, 3));
36
+ const offsetMinute = Number(offset?.slice(4, 6));
37
+ if (offsetHour > 23 || offsetMinute > 59)
38
+ throw new Error(`Invalid one-shot schedule: ${schedule}`);
39
+ }
40
+ const local = new Date(0);
41
+ local.setUTCFullYear(year, month - 1, day);
42
+ local.setUTCHours(hour, minute, second, millisecond);
43
+ if (local.getUTCFullYear() !== year
44
+ || local.getUTCMonth() !== month - 1
45
+ || local.getUTCDate() !== day
46
+ || local.getUTCHours() !== hour
47
+ || local.getUTCMinutes() !== minute
48
+ || local.getUTCSeconds() !== second) {
49
+ throw new Error(`Invalid one-shot schedule: ${schedule}`);
50
+ }
51
+ const timestamp = Date.parse(schedule);
52
+ if (!Number.isFinite(timestamp))
53
+ throw new Error(`Invalid one-shot schedule: ${schedule}`);
54
+ return timestamp;
55
+ }
56
+ function cron(schedule, timezone) {
57
+ rejectNul(schedule, "schedule");
58
+ validateTimezone(timezone);
59
+ if (schedule.trim().split(/\s+/).length !== 5) {
60
+ throw new Error("Cron schedule must contain exactly five fields");
61
+ }
62
+ try {
63
+ return new Cron(schedule, { timezone, mode: "5-part", paused: true });
64
+ }
65
+ catch (error) {
66
+ const detail = error instanceof Error ? error.message : String(error);
67
+ throw new Error(`Invalid cron schedule: ${detail}`);
68
+ }
69
+ }
70
+ export function validateSchedule(kind, schedule, timezone) {
71
+ if (kind !== "once" && kind !== "cron")
72
+ throw new Error(`Invalid schedule kind: ${String(kind)}`);
73
+ validateTimezone(timezone);
74
+ if (kind === "once") {
75
+ parseOnceSchedule(schedule);
76
+ }
77
+ else {
78
+ cron(schedule, timezone);
79
+ }
80
+ }
81
+ export function initialDue(kind, schedule, timezone, now) {
82
+ validateSchedule(kind, schedule, timezone);
83
+ if (kind === "once")
84
+ return parseOnceSchedule(schedule);
85
+ return nextCronDue(schedule, timezone, now);
86
+ }
87
+ export function nextCronDue(schedule, timezone, scheduledAt) {
88
+ const next = cron(schedule, timezone).nextRun(new Date(scheduledAt));
89
+ if (!next || !Number.isFinite(next.getTime()) || next.getTime() <= scheduledAt) {
90
+ throw new Error("Cron schedule has no next occurrence");
91
+ }
92
+ return next.getTime();
93
+ }
94
+ //# sourceMappingURL=schedule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schedule.js","sourceRoot":"","sources":["../../src/scheduler/schedule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import type { GlassDatabase } from "../storage/database.js";
2
+ import type { ClaimedCommand, ClaimedSessionPrompt, CommandCompletion, CreateCommandInput, CreateReminderInput, CreateSessionPromptInput, DaemonLease, InboxRecord, Occurrence, SchedulerJob, SessionPromptCompletion } from "./types.js";
3
+ export declare class SchedulerStore {
4
+ private readonly db;
5
+ constructor(db: GlassDatabase);
6
+ createReminder(input: CreateReminderInput, now?: number): SchedulerJob;
7
+ createCommand(input: CreateCommandInput, now?: number): SchedulerJob;
8
+ createSessionPrompt(input: CreateSessionPromptInput, now?: number): SchedulerJob;
9
+ listJobs(includeDeleted?: boolean): SchedulerJob[];
10
+ listJobsForSession(sessionId: string): SchedulerJob[];
11
+ setSessionJobsEnabled(sessionId: string, enabled: boolean, now?: number): SchedulerJob[];
12
+ getJob(id: string): SchedulerJob | null;
13
+ pauseJob(id: string, now?: number): SchedulerJob;
14
+ resumeJob(id: string): SchedulerJob;
15
+ acknowledgeUnknown(id: string, now?: number): SchedulerJob;
16
+ deleteJob(id: string, now?: number): SchedulerJob;
17
+ listInbox(options?: {
18
+ unackedOnly?: boolean;
19
+ limit?: number;
20
+ }): InboxRecord[];
21
+ listInboxForJobs(jobIds: string[], options?: {
22
+ unackedOnly?: boolean;
23
+ limit?: number;
24
+ }): InboxRecord[];
25
+ getInbox(id: number): InboxRecord | null;
26
+ ackInbox(id: number, now?: number): boolean;
27
+ listRuns(jobId?: string, limit?: number): Occurrence[];
28
+ runNow(jobId: string, now?: number): Occurrence;
29
+ materialize(now?: number, batchSize?: number): Occurrence[];
30
+ tick(now?: number, batchSize?: number): Occurrence[];
31
+ acquireLease(owner: string, bootId: string, now?: number, leaseMs?: number): boolean;
32
+ renewLease(owner: string, bootId: string, now?: number, leaseMs?: number): boolean;
33
+ releaseLease(owner: string, bootId: string, now?: number): boolean;
34
+ getLease(): DaemonLease | null;
35
+ claimCommands(owner: string, bootId: string, now?: number, leaseMs?: number, limit?: number): ClaimedCommand[];
36
+ startClaimedCommand(occurrenceId: number, claimToken: string, owner: string, bootId: string, now?: number): Occurrence | null;
37
+ releaseSessionPromptReservation(sessionId: string, owner: string, token: string): boolean;
38
+ finishCommand(occurrenceId: number, claimToken: string, owner: string, bootId: string, completion: CommandCompletion, now?: number): Occurrence | null;
39
+ claimSessionPrompts(owner: string, bootId: string, now?: number, leaseMs?: number, limit?: number): ClaimedSessionPrompt[];
40
+ startClaimedSessionPrompt(occurrenceId: number, claimToken: string, owner: string, bootId: string, now?: number): Occurrence | null;
41
+ finishSessionPrompt(occurrenceId: number, claimToken: string, owner: string, bootId: string, completion: SessionPromptCompletion, now?: number): Occurrence | null;
42
+ private cancelUnstarted;
43
+ private recoverInterrupted;
44
+ private disableCompletedOneShot;
45
+ private blockUnknownJob;
46
+ private insertOccurrence;
47
+ private insertInbox;
48
+ private hasActiveOccurrence;
49
+ private requireJob;
50
+ private requireCommandJob;
51
+ private requireSessionPromptJob;
52
+ private isPersistentSession;
53
+ private requireOccurrence;
54
+ }
55
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/scheduler/store.ts"],"names":[],"mappings":"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"}