steroids-cli 0.9.11 → 0.9.12

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 (49) hide show
  1. package/dist/parallel/merge-commit-checks.d.ts +6 -0
  2. package/dist/parallel/merge-commit-checks.d.ts.map +1 -0
  3. package/dist/parallel/merge-commit-checks.js +28 -0
  4. package/dist/parallel/merge-commit-checks.js.map +1 -0
  5. package/dist/parallel/merge-process.d.ts +21 -0
  6. package/dist/parallel/merge-process.d.ts.map +1 -0
  7. package/dist/parallel/merge-process.js +104 -0
  8. package/dist/parallel/merge-process.js.map +1 -0
  9. package/dist/parallel/merge-sealing.d.ts +11 -0
  10. package/dist/parallel/merge-sealing.d.ts.map +1 -0
  11. package/dist/parallel/merge-sealing.js +64 -0
  12. package/dist/parallel/merge-sealing.js.map +1 -0
  13. package/dist/parallel/merge-validation.d.ts +6 -0
  14. package/dist/parallel/merge-validation.d.ts.map +1 -0
  15. package/dist/parallel/merge-validation.js +57 -0
  16. package/dist/parallel/merge-validation.js.map +1 -0
  17. package/dist/parallel/merge-workspace.d.ts +8 -0
  18. package/dist/parallel/merge-workspace.d.ts.map +1 -0
  19. package/dist/parallel/merge-workspace.js +37 -0
  20. package/dist/parallel/merge-workspace.js.map +1 -0
  21. package/dist/parallel/merge.d.ts +2 -5
  22. package/dist/parallel/merge.d.ts.map +1 -1
  23. package/dist/parallel/merge.js +14 -245
  24. package/dist/parallel/merge.js.map +1 -1
  25. package/dist/runners/wakeup-checks.d.ts +14 -0
  26. package/dist/runners/wakeup-checks.d.ts.map +1 -0
  27. package/dist/runners/wakeup-checks.js +85 -0
  28. package/dist/runners/wakeup-checks.js.map +1 -0
  29. package/dist/runners/wakeup-reconcile.d.ts +10 -0
  30. package/dist/runners/wakeup-reconcile.d.ts.map +1 -0
  31. package/dist/runners/wakeup-reconcile.js +84 -0
  32. package/dist/runners/wakeup-reconcile.js.map +1 -0
  33. package/dist/runners/wakeup-runner.d.ts +18 -0
  34. package/dist/runners/wakeup-runner.d.ts.map +1 -0
  35. package/dist/runners/wakeup-runner.js +47 -0
  36. package/dist/runners/wakeup-runner.js.map +1 -0
  37. package/dist/runners/wakeup-sanitise.d.ts +24 -0
  38. package/dist/runners/wakeup-sanitise.d.ts.map +1 -0
  39. package/dist/runners/wakeup-sanitise.js +247 -0
  40. package/dist/runners/wakeup-sanitise.js.map +1 -0
  41. package/dist/runners/wakeup-timing.d.ts +12 -0
  42. package/dist/runners/wakeup-timing.d.ts.map +1 -0
  43. package/dist/runners/wakeup-timing.js +37 -0
  44. package/dist/runners/wakeup-timing.js.map +1 -0
  45. package/dist/runners/wakeup.d.ts +7 -8
  46. package/dist/runners/wakeup.d.ts.map +1 -1
  47. package/dist/runners/wakeup.js +26 -464
  48. package/dist/runners/wakeup.js.map +1 -1
  49. package/package.json +1 -1
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ /**
3
+ * Runner management for wakeup
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.killProcess = killProcess;
7
+ exports.startRunner = startRunner;
8
+ const node_child_process_1 = require("node:child_process");
9
+ const loader_js_1 = require("../config/loader.js");
10
+ /**
11
+ * Kill a process by PID
12
+ */
13
+ function killProcess(pid) {
14
+ try {
15
+ process.kill(pid, 'SIGTERM');
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ /**
23
+ * Start a new runner daemon
24
+ * Uses 'steroids runners start --detach' so the runner registers in the global DB
25
+ * and updates heartbeat, allowing hasActiveRunnerForProject() to detect it.
26
+ * When runners.parallel.enabled is true, launches a parallel session instead.
27
+ */
28
+ function startRunner(projectPath) {
29
+ try {
30
+ const config = (0, loader_js_1.loadConfig)(projectPath);
31
+ const parallelEnabled = config.runners?.parallel?.enabled === true;
32
+ const args = parallelEnabled
33
+ ? ['runners', 'start', '--parallel', '--project', projectPath]
34
+ : ['runners', 'start', '--detach', '--project', projectPath];
35
+ const child = (0, node_child_process_1.spawn)('steroids', args, {
36
+ cwd: projectPath,
37
+ detached: true,
38
+ stdio: 'ignore',
39
+ });
40
+ child.unref();
41
+ return { pid: child.pid ?? 0, parallel: parallelEnabled };
42
+ }
43
+ catch {
44
+ return null;
45
+ }
46
+ }
47
+ //# sourceMappingURL=wakeup-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup-runner.js","sourceRoot":"","sources":["../../src/runners/wakeup-runner.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAQH,kCAOC;AAQD,kCAoBC;AAzCD,2DAA2C;AAC3C,mDAAiD;AAEjD;;GAEG;AACH,SAAgB,WAAW,CAAC,GAAW;IACrC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7B,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,SAAgB,WAAW,CAAC,WAAmB;IAC7C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,sBAAU,EAAC,WAAW,CAAC,CAAC;QACvC,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAC;QAEnE,MAAM,IAAI,GAAG,eAAe;YAC1B,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,CAAC;YAC9D,CAAC,CAAC,CAAC,SAAS,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC;QAE/D,MAAM,KAAK,GAAG,IAAA,0BAAK,EAAC,UAAU,EAAE,IAAI,EAAE;YACpC,GAAG,EAAE,WAAW;YAChB,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;SAChB,CAAC,CAAC;QAEH,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Periodic state sanitisation for projects in wakeup
3
+ */
4
+ import { openDatabase } from '../database/connection.js';
5
+ import { openGlobalDatabase } from './global-db.js';
6
+ export interface SanitiseSettings {
7
+ enabled: boolean;
8
+ intervalMinutes: number;
9
+ staleInvocationTimeoutSec: number;
10
+ }
11
+ export interface SanitiseSummary {
12
+ ran: boolean;
13
+ reason: string;
14
+ recoveredApprovals: number;
15
+ recoveredRejects: number;
16
+ closedStaleInvocations: number;
17
+ releasedTaskLocks: number;
18
+ releasedSectionLocks: number;
19
+ }
20
+ export declare function getSanitiseSettings(projectPath: string): SanitiseSettings;
21
+ export declare function shouldRunPeriodicSanitise(db: ReturnType<typeof openGlobalDatabase>['db'], projectPath: string, intervalMinutes: number): boolean;
22
+ export declare function runPeriodicSanitiseForProject(globalDb: ReturnType<typeof openGlobalDatabase>['db'], projectDb: ReturnType<typeof openDatabase>['db'], projectPath: string, dryRun: boolean): SanitiseSummary;
23
+ export declare function sanitisedActionCount(summary: SanitiseSummary): number;
24
+ //# sourceMappingURL=wakeup-sanitise.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup-sanitise.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAGpD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,yBAAyB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAKD,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAezE;AAMD,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,IAAI,CAAC,EAC/C,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,GACtB,OAAO,CAkBT;AAmOD,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,IAAI,CAAC,EACrD,SAAS,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,IAAI,CAAC,EAChD,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,OAAO,GACd,eAAe,CAuCjB;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CAQrE"}
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ /**
3
+ * Periodic state sanitisation for projects in wakeup
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getSanitiseSettings = getSanitiseSettings;
7
+ exports.shouldRunPeriodicSanitise = shouldRunPeriodicSanitise;
8
+ exports.runPeriodicSanitiseForProject = runPeriodicSanitiseForProject;
9
+ exports.sanitisedActionCount = sanitisedActionCount;
10
+ const node_fs_1 = require("node:fs");
11
+ const node_path_1 = require("node:path");
12
+ const node_fs_2 = require("node:fs");
13
+ const loader_js_1 = require("../config/loader.js");
14
+ const DEFAULT_SANITISE_INTERVAL_MINUTES = 5;
15
+ const DEFAULT_SANITISE_INVOCATION_TIMEOUT_SEC = 1800;
16
+ function getSanitiseSettings(projectPath) {
17
+ const config = (0, loader_js_1.loadConfig)(projectPath);
18
+ const health = config.health ?? {};
19
+ const enabled = health.sanitiseEnabled ?? true;
20
+ const intervalMinutes = Math.max(1, Number(health.sanitiseIntervalMinutes ?? DEFAULT_SANITISE_INTERVAL_MINUTES));
21
+ const staleInvocationTimeoutSec = Math.max(60, Number(health.sanitiseInvocationTimeoutSec ?? DEFAULT_SANITISE_INVOCATION_TIMEOUT_SEC));
22
+ return { enabled, intervalMinutes, staleInvocationTimeoutSec };
23
+ }
24
+ function getSanitiseSchemaKey(projectPath) {
25
+ return `wakeup_sanitise_last_run::${projectPath}`;
26
+ }
27
+ function shouldRunPeriodicSanitise(db, projectPath, intervalMinutes) {
28
+ const key = getSanitiseSchemaKey(projectPath);
29
+ const row = db
30
+ .prepare('SELECT value FROM _global_schema WHERE key = ?')
31
+ .get(key);
32
+ if (!row?.value) {
33
+ return true;
34
+ }
35
+ const due = db.prepare(`SELECT CASE
36
+ WHEN datetime(?) <= datetime('now', ?)
37
+ THEN 1 ELSE 0
38
+ END AS due`).get(row.value, `-${intervalMinutes} minutes`);
39
+ return (due?.due ?? 0) === 1;
40
+ }
41
+ function markPeriodicSanitiseRun(db, projectPath) {
42
+ db.prepare(`INSERT INTO _global_schema (key, value) VALUES (?, datetime('now'))
43
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(getSanitiseSchemaKey(projectPath));
44
+ }
45
+ function parseReviewerDecisionFromLog(projectPath, invocationId) {
46
+ const logPath = (0, node_path_1.join)(projectPath, '.steroids', 'invocations', `${invocationId}.log`);
47
+ if (!(0, node_fs_1.existsSync)(logPath)) {
48
+ return null;
49
+ }
50
+ try {
51
+ const raw = (0, node_fs_2.readFileSync)(logPath, 'utf-8');
52
+ if (raw.includes('DECISION: APPROVE')) {
53
+ return 'approve';
54
+ }
55
+ if (raw.includes('DECISION: REJECT')) {
56
+ return 'reject';
57
+ }
58
+ }
59
+ catch {
60
+ return null;
61
+ }
62
+ return null;
63
+ }
64
+ function sanitiseProjectState(globalDb, projectDb, projectPath, dryRun, staleInvocationTimeoutSec) {
65
+ const summary = {
66
+ ran: true,
67
+ reason: 'ok',
68
+ recoveredApprovals: 0,
69
+ recoveredRejects: 0,
70
+ closedStaleInvocations: 0,
71
+ releasedTaskLocks: 0,
72
+ releasedSectionLocks: 0,
73
+ };
74
+ const staleCutoffMs = Date.now() - staleInvocationTimeoutSec * 1000;
75
+ const activeRunnerTaskRows = globalDb
76
+ .prepare(`SELECT current_task_id, parallel_session_id
77
+ FROM runners
78
+ WHERE project_path = ?
79
+ AND status = 'running'
80
+ AND heartbeat_at > datetime('now', '-5 minutes')
81
+ AND (current_task_id IS NOT NULL OR parallel_session_id IS NOT NULL)`)
82
+ .all(projectPath);
83
+ const activeTaskIds = new Set(activeRunnerTaskRows
84
+ .map((row) => row.current_task_id)
85
+ .filter((taskId) => typeof taskId === 'string' && taskId.length > 0));
86
+ const hasActiveParallelRunner = activeRunnerTaskRows.some((row) => typeof row.parallel_session_id === 'string' && row.parallel_session_id.length > 0);
87
+ let hasActiveMergeLock = false;
88
+ try {
89
+ const mergeLockRows = projectDb
90
+ .prepare('SELECT expires_at FROM merge_locks')
91
+ .all();
92
+ const nowMs = Date.now();
93
+ hasActiveMergeLock = mergeLockRows.some((row) => {
94
+ const expiresAtMs = Date.parse(row.expires_at);
95
+ return Number.isFinite(expiresAtMs) && expiresAtMs > nowMs;
96
+ });
97
+ }
98
+ catch {
99
+ hasActiveMergeLock = false;
100
+ }
101
+ const hasActiveParallelContext = hasActiveParallelRunner || hasActiveMergeLock;
102
+ const staleInvocations = projectDb
103
+ .prepare(`SELECT i.id, i.task_id, i.role, i.started_at_ms, t.status AS task_status
104
+ FROM task_invocations i
105
+ LEFT JOIN tasks t ON t.id = i.task_id
106
+ WHERE i.status = 'running'
107
+ AND i.started_at_ms IS NOT NULL
108
+ AND i.started_at_ms <= ?
109
+ ORDER BY i.started_at_ms ASC`)
110
+ .all(staleCutoffMs);
111
+ for (const row of staleInvocations) {
112
+ if (activeTaskIds.has(row.task_id) || hasActiveParallelContext) {
113
+ continue;
114
+ }
115
+ const completedAtMs = Date.now();
116
+ const durationMs = Math.max(0, completedAtMs - row.started_at_ms);
117
+ const reviewerDecision = row.role === 'reviewer'
118
+ ? parseReviewerDecisionFromLog(projectPath, row.id)
119
+ : null;
120
+ if (!dryRun) {
121
+ if (reviewerDecision === 'approve' && row.task_status === 'review') {
122
+ projectDb
123
+ .prepare(`UPDATE task_invocations
124
+ SET status = 'completed',
125
+ success = 1,
126
+ timed_out = 0,
127
+ exit_code = 0,
128
+ completed_at_ms = ?,
129
+ duration_ms = ?,
130
+ error = COALESCE(error, 'Recovered by periodic sanitise (review approve token found).')
131
+ WHERE id = ? AND status = 'running'`)
132
+ .run(completedAtMs, durationMs, row.id);
133
+ projectDb
134
+ .prepare(`UPDATE tasks
135
+ SET status = 'completed',
136
+ updated_at = datetime('now')
137
+ WHERE id = ? AND status = 'review'`)
138
+ .run(row.task_id);
139
+ projectDb
140
+ .prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
141
+ SELECT ?, 'review', 'completed', 'orchestrator', 'orchestrator',
142
+ 'Recovered by periodic sanitise from reviewer decision log (DECISION: APPROVE).',
143
+ datetime('now')
144
+ WHERE EXISTS (SELECT 1 FROM tasks WHERE id = ? AND status = 'completed')`)
145
+ .run(row.task_id, row.task_id);
146
+ }
147
+ else if (reviewerDecision === 'reject' && row.task_status === 'review') {
148
+ projectDb
149
+ .prepare(`UPDATE task_invocations
150
+ SET status = 'completed',
151
+ success = 1,
152
+ timed_out = 0,
153
+ exit_code = 0,
154
+ completed_at_ms = ?,
155
+ duration_ms = ?,
156
+ error = COALESCE(error, 'Recovered by periodic sanitise (review reject token found).')
157
+ WHERE id = ? AND status = 'running'`)
158
+ .run(completedAtMs, durationMs, row.id);
159
+ projectDb
160
+ .prepare(`UPDATE tasks
161
+ SET status = 'in_progress',
162
+ rejection_count = COALESCE(rejection_count, 0) + 1,
163
+ updated_at = datetime('now')
164
+ WHERE id = ? AND status = 'review'`)
165
+ .run(row.task_id);
166
+ projectDb
167
+ .prepare(`INSERT INTO audit (task_id, from_status, to_status, actor, actor_type, notes, created_at)
168
+ SELECT ?, 'review', 'in_progress', 'orchestrator', 'orchestrator',
169
+ 'Recovered by periodic sanitise from reviewer decision log (DECISION: REJECT).',
170
+ datetime('now')
171
+ WHERE EXISTS (SELECT 1 FROM tasks WHERE id = ? AND status = 'in_progress')`)
172
+ .run(row.task_id, row.task_id);
173
+ }
174
+ else {
175
+ projectDb
176
+ .prepare(`UPDATE task_invocations
177
+ SET status = 'failed',
178
+ success = 0,
179
+ timed_out = 1,
180
+ exit_code = 1,
181
+ completed_at_ms = ?,
182
+ duration_ms = ?,
183
+ error = COALESCE(error, 'Periodic sanitise closed stale running invocation.')
184
+ WHERE id = ? AND status = 'running'`)
185
+ .run(completedAtMs, durationMs, row.id);
186
+ }
187
+ }
188
+ if (reviewerDecision === 'approve' && row.task_status === 'review') {
189
+ summary.recoveredApprovals += 1;
190
+ }
191
+ else if (reviewerDecision === 'reject' && row.task_status === 'review') {
192
+ summary.recoveredRejects += 1;
193
+ }
194
+ else {
195
+ summary.closedStaleInvocations += 1;
196
+ }
197
+ }
198
+ if (!dryRun) {
199
+ const releasedTaskLocks = projectDb
200
+ .prepare(`DELETE FROM task_locks WHERE expires_at <= datetime('now')`)
201
+ .run();
202
+ summary.releasedTaskLocks = releasedTaskLocks.changes;
203
+ const releasedSectionLocks = projectDb
204
+ .prepare(`DELETE FROM section_locks WHERE expires_at <= datetime('now')`)
205
+ .run();
206
+ summary.releasedSectionLocks = releasedSectionLocks.changes;
207
+ }
208
+ return summary;
209
+ }
210
+ function runPeriodicSanitiseForProject(globalDb, projectDb, projectPath, dryRun) {
211
+ const settings = getSanitiseSettings(projectPath);
212
+ if (!settings.enabled) {
213
+ return {
214
+ ran: false,
215
+ reason: 'disabled',
216
+ recoveredApprovals: 0,
217
+ recoveredRejects: 0,
218
+ closedStaleInvocations: 0,
219
+ releasedTaskLocks: 0,
220
+ releasedSectionLocks: 0,
221
+ };
222
+ }
223
+ if (!shouldRunPeriodicSanitise(globalDb, projectPath, settings.intervalMinutes)) {
224
+ return {
225
+ ran: false,
226
+ reason: 'interval_not_due',
227
+ recoveredApprovals: 0,
228
+ recoveredRejects: 0,
229
+ closedStaleInvocations: 0,
230
+ releasedTaskLocks: 0,
231
+ releasedSectionLocks: 0,
232
+ };
233
+ }
234
+ const summary = sanitiseProjectState(globalDb, projectDb, projectPath, dryRun, settings.staleInvocationTimeoutSec);
235
+ if (!dryRun) {
236
+ markPeriodicSanitiseRun(globalDb, projectPath);
237
+ }
238
+ return summary;
239
+ }
240
+ function sanitisedActionCount(summary) {
241
+ return (summary.recoveredApprovals +
242
+ summary.recoveredRejects +
243
+ summary.closedStaleInvocations +
244
+ summary.releasedTaskLocks +
245
+ summary.releasedSectionLocks);
246
+ }
247
+ //# sourceMappingURL=wakeup-sanitise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup-sanitise.js","sourceRoot":"","sources":["../../src/runners/wakeup-sanitise.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Wakeup timing and state tracking
3
+ */
4
+ /**
5
+ * Record the last wakeup invocation time
6
+ */
7
+ export declare function recordWakeupTime(): void;
8
+ /**
9
+ * Get the last wakeup invocation time
10
+ */
11
+ export declare function getLastWakeupTime(): string | null;
12
+ //# sourceMappingURL=wakeup-timing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup-timing.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup-timing.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAUvC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAUjD"}
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ /**
3
+ * Wakeup timing and state tracking
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.recordWakeupTime = recordWakeupTime;
7
+ exports.getLastWakeupTime = getLastWakeupTime;
8
+ const global_db_js_1 = require("./global-db.js");
9
+ /**
10
+ * Record the last wakeup invocation time
11
+ */
12
+ function recordWakeupTime() {
13
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
14
+ try {
15
+ db.prepare(`INSERT INTO _global_schema (key, value) VALUES ('last_wakeup_at', datetime('now'))
16
+ ON CONFLICT(key) DO UPDATE SET value = datetime('now')`).run();
17
+ }
18
+ finally {
19
+ close();
20
+ }
21
+ }
22
+ /**
23
+ * Get the last wakeup invocation time
24
+ */
25
+ function getLastWakeupTime() {
26
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
27
+ try {
28
+ const row = db
29
+ .prepare("SELECT value FROM _global_schema WHERE key = 'last_wakeup_at'")
30
+ .get();
31
+ return row?.value ?? null;
32
+ }
33
+ finally {
34
+ close();
35
+ }
36
+ }
37
+ //# sourceMappingURL=wakeup-timing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wakeup-timing.js","sourceRoot":"","sources":["../../src/runners/wakeup-timing.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAOH,4CAUC;AAKD,8CAUC;AA9BD,iDAAoD;AAEpD;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,IAAA,iCAAkB,GAAE,CAAC;IAC3C,IAAI,CAAC;QACH,EAAE,CAAC,OAAO,CACR;8DACwD,CACzD,CAAC,GAAG,EAAE,CAAC;IACV,CAAC;YAAS,CAAC;QACT,KAAK,EAAE,CAAC;IACV,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB;IAC/B,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,IAAA,iCAAkB,GAAE,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE;aACX,OAAO,CAAC,+DAA+D,CAAC;aACxE,GAAG,EAAmC,CAAC;QAC1C,OAAO,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC;IAC5B,CAAC;YAAS,CAAC;QACT,KAAK,EAAE,CAAC;IACV,CAAC;AACH,CAAC"}
@@ -1,6 +1,8 @@
1
1
  /**
2
2
  * Cron wake-up command for restarting stale/dead runners
3
3
  */
4
+ import { hasActiveRunnerForProject, hasActiveParallelSessionForProject } from './wakeup-checks.js';
5
+ import { getLastWakeupTime } from './wakeup-timing.js';
4
6
  export interface WakeupOptions {
5
7
  quiet?: boolean;
6
8
  dryRun?: boolean;
@@ -18,16 +20,13 @@ export interface WakeupResult {
18
20
  deletedInvocationLogs?: number;
19
21
  sanitisedActions?: number;
20
22
  }
23
+ export { getLastWakeupTime, hasActiveRunnerForProject, hasActiveParallelSessionForProject };
21
24
  /**
22
- * Check if there's an active runner for a specific project
23
- * Exported for use in daemon startup checks
25
+ * Main wake-up function
26
+ * Called by cron every minute to ensure runners are healthy
27
+ * Iterates over ALL registered projects and starts runners as needed
28
+ * Returns per-project results
24
29
  */
25
- export declare function hasActiveRunnerForProject(projectPath: string): boolean;
26
- export declare function hasActiveParallelSessionForProject(projectPath: string): boolean;
27
- /**
28
- * Get the last wakeup invocation time
29
- */
30
- export declare function getLastWakeupTime(): string | null;
31
30
  export declare function wakeup(options?: WakeupOptions): Promise<WakeupResult[]>;
32
31
  /**
33
32
  * Check if wake-up is needed without taking action
@@ -1 +1 @@
1
- {"version":3,"file":"wakeup.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAiDD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAiBtE;AAED,wBAAgB,kCAAkC,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAkC/E;AAmfD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CAUjD;AAED,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAyQjF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAyCD"}
1
+ {"version":3,"file":"wakeup.d.ts","sourceRoot":"","sources":["../../src/runners/wakeup.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmBH,OAAO,EAEL,yBAAyB,EACzB,kCAAkC,EACnC,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAoB,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEzE,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+BAA+B,CAAC,EAAE,OAAO,CAAC;IAC1C,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,kCAAkC,EAAE,CAAC;AAE5F;;;;;GAKG;AACH,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAgRjF;AAED;;GAEG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC;IACjD,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CAyCD"}