steroids-cli 0.8.24 → 0.8.26

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 (77) hide show
  1. package/dist/commands/ai.js +7 -6
  2. package/dist/commands/ai.js.map +1 -1
  3. package/dist/commands/completion.d.ts.map +1 -1
  4. package/dist/commands/completion.js +1 -0
  5. package/dist/commands/completion.js.map +1 -1
  6. package/dist/commands/config.js +10 -7
  7. package/dist/commands/config.js.map +1 -1
  8. package/dist/commands/llm.d.ts.map +1 -1
  9. package/dist/commands/llm.js +5 -0
  10. package/dist/commands/llm.js.map +1 -1
  11. package/dist/commands/merge.d.ts +3 -0
  12. package/dist/commands/merge.d.ts.map +1 -0
  13. package/dist/commands/merge.js +234 -0
  14. package/dist/commands/merge.js.map +1 -0
  15. package/dist/commands/runners-list.d.ts +3 -0
  16. package/dist/commands/runners-list.d.ts.map +1 -0
  17. package/dist/commands/runners-list.js +287 -0
  18. package/dist/commands/runners-list.js.map +1 -0
  19. package/dist/commands/runners-logs.d.ts +2 -0
  20. package/dist/commands/runners-logs.d.ts.map +1 -0
  21. package/dist/commands/runners-logs.js +207 -0
  22. package/dist/commands/runners-logs.js.map +1 -0
  23. package/dist/commands/runners-management.d.ts +3 -0
  24. package/dist/commands/runners-management.d.ts.map +1 -0
  25. package/dist/commands/runners-management.js +205 -0
  26. package/dist/commands/runners-management.js.map +1 -0
  27. package/dist/commands/runners-parallel.d.ts +26 -0
  28. package/dist/commands/runners-parallel.d.ts.map +1 -0
  29. package/dist/commands/runners-parallel.js +229 -0
  30. package/dist/commands/runners-parallel.js.map +1 -0
  31. package/dist/commands/runners-wakeup.d.ts +4 -0
  32. package/dist/commands/runners-wakeup.d.ts.map +1 -0
  33. package/dist/commands/runners-wakeup.js +157 -0
  34. package/dist/commands/runners-wakeup.js.map +1 -0
  35. package/dist/commands/runners.d.ts.map +1 -1
  36. package/dist/commands/runners.js +115 -786
  37. package/dist/commands/runners.js.map +1 -1
  38. package/dist/commands/workspaces.d.ts +3 -0
  39. package/dist/commands/workspaces.d.ts.map +1 -0
  40. package/dist/commands/workspaces.js +409 -0
  41. package/dist/commands/workspaces.js.map +1 -0
  42. package/dist/config/ai-setup.d.ts +1 -1
  43. package/dist/config/ai-setup.d.ts.map +1 -1
  44. package/dist/config/ai-setup.js +1 -0
  45. package/dist/config/ai-setup.js.map +1 -1
  46. package/dist/config/loader.d.ts +10 -3
  47. package/dist/config/loader.d.ts.map +1 -1
  48. package/dist/config/loader.js +7 -0
  49. package/dist/config/loader.js.map +1 -1
  50. package/dist/config/schema.d.ts.map +1 -1
  51. package/dist/config/schema.js +32 -3
  52. package/dist/config/schema.js.map +1 -1
  53. package/dist/index.js +10 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/providers/api-models.d.ts +11 -6
  56. package/dist/providers/api-models.d.ts.map +1 -1
  57. package/dist/providers/api-models.js +80 -0
  58. package/dist/providers/api-models.js.map +1 -1
  59. package/dist/providers/index.d.ts +2 -1
  60. package/dist/providers/index.d.ts.map +1 -1
  61. package/dist/providers/index.js +6 -1
  62. package/dist/providers/index.js.map +1 -1
  63. package/dist/providers/mistral.d.ts +58 -0
  64. package/dist/providers/mistral.d.ts.map +1 -0
  65. package/dist/providers/mistral.js +310 -0
  66. package/dist/providers/mistral.js.map +1 -0
  67. package/dist/providers/registry.d.ts.map +1 -1
  68. package/dist/providers/registry.js +2 -0
  69. package/dist/providers/registry.js.map +1 -1
  70. package/dist/runners/cron.d.ts.map +1 -1
  71. package/dist/runners/cron.js +9 -0
  72. package/dist/runners/cron.js.map +1 -1
  73. package/dist/runners/wakeup.d.ts +1 -0
  74. package/dist/runners/wakeup.d.ts.map +1 -1
  75. package/dist/runners/wakeup.js +27 -0
  76. package/dist/runners/wakeup.js.map +1 -1
  77. package/package.json +1 -1
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.runStop = runStop;
37
+ exports.runStatus = runStatus;
38
+ const fs = __importStar(require("node:fs"));
39
+ const os = __importStar(require("node:os"));
40
+ const path = __importStar(require("node:path"));
41
+ const node_util_1 = require("node:util");
42
+ const daemon_js_1 = require("../runners/daemon.js");
43
+ const lock_js_1 = require("../runners/lock.js");
44
+ async function runStop(args) {
45
+ const { values } = (0, node_util_1.parseArgs)({
46
+ args,
47
+ options: {
48
+ help: { type: 'boolean', short: 'h', default: false },
49
+ json: { type: 'boolean', short: 'j', default: false },
50
+ id: { type: 'string' },
51
+ all: { type: 'boolean', default: false },
52
+ },
53
+ allowPositionals: false,
54
+ });
55
+ if (values.help) {
56
+ console.log(`
57
+ steroids runners stop - Stop runner(s)
58
+
59
+ USAGE:
60
+ steroids runners stop [options]
61
+
62
+ OPTIONS:
63
+ --id <id> Stop specific runner
64
+ --all Stop all runners
65
+ -j, --json Output as JSON
66
+ -h, --help Show help
67
+ `);
68
+ return;
69
+ }
70
+ // Capture stop context for logging
71
+ const stopContext = {
72
+ calledFrom: process.cwd(),
73
+ callerPid: process.pid,
74
+ timestamp: new Date().toISOString(),
75
+ user: process.env.USER || process.env.USERNAME || 'unknown',
76
+ args: {
77
+ id: values.id,
78
+ all: values.all,
79
+ },
80
+ };
81
+ const runners = (0, daemon_js_1.listRunners)();
82
+ let stopped = 0;
83
+ const stoppedRunners = [];
84
+ const runnersToStop = values.id
85
+ ? runners.filter((r) => r.id === values.id || r.id.startsWith(values.id))
86
+ : values.all
87
+ ? runners
88
+ : runners.filter((r) => r.pid === process.pid || r.pid !== null);
89
+ // Log stop action to daemon logs
90
+ const logsDir = path.join(os.homedir(), '.steroids', 'runners', 'logs');
91
+ const stopLogPath = path.join(logsDir, 'stop-audit.log');
92
+ fs.mkdirSync(logsDir, { recursive: true });
93
+ for (const runner of runnersToStop) {
94
+ if (runner.pid && (0, lock_js_1.isProcessAlive)(runner.pid)) {
95
+ try {
96
+ process.kill(runner.pid, 'SIGTERM');
97
+ stopped++;
98
+ stoppedRunners.push({
99
+ id: runner.id,
100
+ pid: runner.pid,
101
+ project: runner.project_path,
102
+ });
103
+ // Log each stop to audit log
104
+ const logEntry = {
105
+ ...stopContext,
106
+ action: 'stop',
107
+ runner: {
108
+ id: runner.id,
109
+ pid: runner.pid,
110
+ project: runner.project_path,
111
+ },
112
+ };
113
+ fs.appendFileSync(stopLogPath, JSON.stringify(logEntry) + '\n');
114
+ }
115
+ catch {
116
+ // Process already dead
117
+ }
118
+ }
119
+ (0, daemon_js_1.unregisterRunner)(runner.id);
120
+ }
121
+ if (values.json) {
122
+ console.log(JSON.stringify({
123
+ success: true,
124
+ stopped,
125
+ stoppedRunners,
126
+ context: stopContext,
127
+ }));
128
+ }
129
+ else {
130
+ console.log(`Stopped ${stopped} runner(s)`);
131
+ if (stopped > 0 && !values.all) {
132
+ console.log(` Called from: ${stopContext.calledFrom}`);
133
+ console.log(` Audit log: ${stopLogPath}`);
134
+ }
135
+ }
136
+ }
137
+ async function runStatus(args) {
138
+ const { values } = (0, node_util_1.parseArgs)({
139
+ args,
140
+ options: {
141
+ help: { type: 'boolean', short: 'h', default: false },
142
+ json: { type: 'boolean', short: 'j', default: false },
143
+ },
144
+ allowPositionals: false,
145
+ });
146
+ if (values.help) {
147
+ console.log(`
148
+ steroids runners status - Show runner status
149
+
150
+ USAGE:
151
+ steroids runners status [options]
152
+
153
+ OPTIONS:
154
+ -j, --json Output as JSON
155
+ -h, --help Show help
156
+ `);
157
+ return;
158
+ }
159
+ const lockStatus = (0, lock_js_1.checkLockStatus)();
160
+ const runners = (0, daemon_js_1.listRunners)();
161
+ const activeRunner = runners.find((r) => r.pid && (0, lock_js_1.isProcessAlive)(r.pid));
162
+ const status = {
163
+ locked: lockStatus.locked,
164
+ lockPid: lockStatus.pid,
165
+ isZombie: lockStatus.isZombie,
166
+ activeRunner: activeRunner
167
+ ? {
168
+ id: activeRunner.id,
169
+ pid: activeRunner.pid,
170
+ status: activeRunner.status,
171
+ project: activeRunner.project_path,
172
+ currentTask: activeRunner.current_task_id,
173
+ heartbeat: activeRunner.heartbeat_at,
174
+ }
175
+ : null,
176
+ totalRunners: runners.length,
177
+ };
178
+ if (values.json) {
179
+ console.log(JSON.stringify(status, null, 2));
180
+ return;
181
+ }
182
+ if (activeRunner) {
183
+ console.log(`Runner Status: ACTIVE`);
184
+ console.log(` ID: ${activeRunner.id}`);
185
+ console.log(` PID: ${activeRunner.pid}`);
186
+ console.log(` Status: ${activeRunner.status}`);
187
+ if (activeRunner.project_path) {
188
+ console.log(` Project: ${activeRunner.project_path}`);
189
+ }
190
+ if (activeRunner.current_task_id) {
191
+ console.log(` Current Task: ${activeRunner.current_task_id}`);
192
+ }
193
+ console.log(` Last Heartbeat: ${activeRunner.heartbeat_at}`);
194
+ }
195
+ else if (lockStatus.isZombie) {
196
+ console.log(`Runner Status: ZOMBIE`);
197
+ console.log(` Lock exists but process (PID: ${lockStatus.pid}) is dead`);
198
+ console.log(` Run 'steroids runners wakeup' to clean up`);
199
+ }
200
+ else {
201
+ console.log(`Runner Status: INACTIVE`);
202
+ console.log(` No runner is currently active`);
203
+ }
204
+ }
205
+ //# sourceMappingURL=runners-management.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runners-management.js","sourceRoot":"","sources":["../../src/commands/runners-management.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { CyclicDependencyError } from '../parallel/scheduler.js';
2
+ export interface ParallelWorkstreamPlan {
3
+ sessionId: string;
4
+ projectPath: string;
5
+ maxClones: number;
6
+ workstreams: Array<{
7
+ id: string;
8
+ branchName: string;
9
+ sectionIds: string[];
10
+ sectionNames: string[];
11
+ }>;
12
+ }
13
+ export declare function parseSectionIds(value: string): string[];
14
+ export declare function printParallelPlan(_projectPath: string, plan: ParallelWorkstreamPlan): void;
15
+ export declare function getConfiguredMaxClones(projectPath: string): number;
16
+ export declare function buildParallelRunPlan(projectPath: string, maxClonesOverride?: number): ParallelWorkstreamPlan;
17
+ export declare function launchParallelSession(plan: ParallelWorkstreamPlan, projectPath: string): string;
18
+ export declare function spawnDetachedRunner(options: {
19
+ projectPath: string;
20
+ args: string[];
21
+ }): {
22
+ pid: number | null;
23
+ logFile?: string;
24
+ };
25
+ export { CyclicDependencyError };
26
+ //# sourceMappingURL=runners-parallel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runners-parallel.d.ts","sourceRoot":"","sources":["../../src/commands/runners-parallel.ts"],"names":[],"mappings":"AASA,OAAO,EAAwB,qBAAqB,EAA0B,MAAM,0BAA0B,CAAC;AAG/G,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,KAAK,CAAC;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,EAAE,CAAC;QACrB,YAAY,EAAE,MAAM,EAAE,CAAC;KACxB,CAAC,CAAC;CACJ;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAKvD;AAED,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAc1F;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOlE;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,sBAAsB,CAyF5G;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,CAmE/F;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG;IAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CA4C9H;AAED,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
@@ -0,0 +1,229 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.CyclicDependencyError = void 0;
37
+ exports.parseSectionIds = parseSectionIds;
38
+ exports.printParallelPlan = printParallelPlan;
39
+ exports.getConfiguredMaxClones = getConfiguredMaxClones;
40
+ exports.buildParallelRunPlan = buildParallelRunPlan;
41
+ exports.launchParallelSession = launchParallelSession;
42
+ exports.spawnDetachedRunner = spawnDetachedRunner;
43
+ const node_child_process_1 = require("node:child_process");
44
+ const fs = __importStar(require("node:fs"));
45
+ const os = __importStar(require("node:os"));
46
+ const path = __importStar(require("node:path"));
47
+ const uuid_1 = require("uuid");
48
+ const connection_js_1 = require("../database/connection.js");
49
+ const clone_js_1 = require("../parallel/clone.js");
50
+ const loader_js_1 = require("../config/loader.js");
51
+ const global_db_js_1 = require("../runners/global-db.js");
52
+ const scheduler_js_1 = require("../parallel/scheduler.js");
53
+ Object.defineProperty(exports, "CyclicDependencyError", { enumerable: true, get: function () { return scheduler_js_1.CyclicDependencyError; } });
54
+ const queries_js_1 = require("../database/queries.js");
55
+ function parseSectionIds(value) {
56
+ return value
57
+ .split(',')
58
+ .map((id) => id.trim())
59
+ .filter((id) => id.length > 0);
60
+ }
61
+ function printParallelPlan(_projectPath, plan) {
62
+ console.log(`Parallel plan for ${plan.projectPath}`);
63
+ console.log(`Session: ${plan.sessionId}`);
64
+ console.log(`Workstreams: ${plan.workstreams.length}`);
65
+ console.log(`Max clones: ${plan.maxClones}`);
66
+ for (let i = 0; i < plan.workstreams.length; i += 1) {
67
+ const workstream = plan.workstreams[i];
68
+ console.log(`${i + 1}. ${workstream.id} (${workstream.branchName})`);
69
+ for (const sectionName of workstream.sectionNames) {
70
+ console.log(` - ${sectionName}`);
71
+ }
72
+ }
73
+ }
74
+ function getConfiguredMaxClones(projectPath) {
75
+ const config = (0, loader_js_1.loadConfig)(projectPath);
76
+ const configured = config.runners?.parallel?.maxClones;
77
+ return Number.isFinite(Number(configured)) && Number(configured) > 0
78
+ ? Number(configured)
79
+ : 3;
80
+ }
81
+ function buildParallelRunPlan(projectPath, maxClonesOverride) {
82
+ const sessionId = (0, uuid_1.v4)();
83
+ const shortSessionId = sessionId.slice(0, 8);
84
+ const config = (0, loader_js_1.loadConfig)(projectPath);
85
+ if (config.runners?.parallel?.enabled !== true) {
86
+ throw new Error('Parallel mode is disabled. Set runners.parallel.enabled: true to use --parallel.');
87
+ }
88
+ const configuredMaxClones = getConfiguredMaxClones(projectPath);
89
+ const effectiveMaxClones = maxClonesOverride ?? configuredMaxClones;
90
+ const { db, close } = (0, connection_js_1.openDatabase)(projectPath);
91
+ try {
92
+ const sections = (0, queries_js_1.listSections)(db);
93
+ if (sections.length === 0) {
94
+ throw new Error('No sections found');
95
+ }
96
+ const dependencyRows = db
97
+ .prepare('SELECT section_id AS sectionId, depends_on_section_id AS dependsOnSectionId FROM section_dependencies')
98
+ .all();
99
+ const workstreamSections = sections.map((section) => ({
100
+ id: section.id,
101
+ name: section.name,
102
+ position: section.position,
103
+ }));
104
+ const workstreams = (0, scheduler_js_1.partitionWorkstreams)(workstreamSections, dependencyRows.map((dep) => ({
105
+ sectionId: dep.sectionId,
106
+ dependsOnSectionId: dep.dependsOnSectionId,
107
+ })));
108
+ const pendingRows = db
109
+ .prepare(`SELECT section_id as sectionId, COUNT(*) as count
110
+ FROM tasks
111
+ WHERE section_id IN (${sections.map(() => '?').join(',')})
112
+ AND status != 'completed'
113
+ GROUP BY section_id`)
114
+ .all(...sections.map((section) => section.id));
115
+ const pendingMap = new Map(pendingRows.map((row) => [row.sectionId, row.count]));
116
+ const sectionNameById = new Map(sections.map((section) => [section.id, section.name]));
117
+ const activeWorkstreams = workstreams.workstreams
118
+ .map((sectionIds, index) => {
119
+ const sectionNames = sectionIds
120
+ .map((sectionId) => sectionNameById.get(sectionId) ?? sectionId);
121
+ const workstream = {
122
+ id: `ws-${shortSessionId}-${index + 1}`,
123
+ branchName: `steroids/ws-${shortSessionId}-${index + 1}`,
124
+ sectionIds,
125
+ sectionNames,
126
+ };
127
+ return workstream;
128
+ })
129
+ .filter((workstream) => workstream.sectionIds.some((sectionId) => (pendingMap.get(sectionId) ?? 0) > 0));
130
+ const filteredWorkstreams = activeWorkstreams.slice(0, effectiveMaxClones);
131
+ if (filteredWorkstreams.length === 0) {
132
+ throw new Error('No pending workstreams');
133
+ }
134
+ return {
135
+ sessionId,
136
+ projectPath,
137
+ maxClones: effectiveMaxClones,
138
+ workstreams: filteredWorkstreams,
139
+ };
140
+ }
141
+ finally {
142
+ close();
143
+ }
144
+ }
145
+ function launchParallelSession(plan, projectPath) {
146
+ const { db, close } = (0, global_db_js_1.openGlobalDatabase)();
147
+ const configuredWorkspaceRoot = (0, loader_js_1.loadConfig)(projectPath).runners?.parallel?.workspaceRoot;
148
+ try {
149
+ db.prepare('INSERT INTO parallel_sessions (id, project_path, status) VALUES (?, ?, ?)').run(plan.sessionId, projectPath, 'running');
150
+ const insertWorkstream = db.prepare(`INSERT INTO workstreams (
151
+ id, session_id, branch_name, section_ids, status, clone_path
152
+ ) VALUES (?, ?, ?, ?, ?, ?)`);
153
+ for (const workstream of plan.workstreams) {
154
+ let workspacePath = null;
155
+ try {
156
+ const workspaceClone = (0, clone_js_1.createWorkspaceClone)({
157
+ projectPath,
158
+ workstreamId: workstream.id,
159
+ branchName: workstream.branchName,
160
+ workspaceRoot: configuredWorkspaceRoot,
161
+ });
162
+ workspacePath = workspaceClone.workspacePath;
163
+ insertWorkstream.run(workstream.id, plan.sessionId, workstream.branchName, JSON.stringify(workstream.sectionIds), 'running', workspaceClone.workspacePath);
164
+ const spawnResult = spawnDetachedRunner({
165
+ projectPath: workspaceClone.workspacePath,
166
+ args: [
167
+ process.argv[1],
168
+ 'runners',
169
+ 'start',
170
+ '--project', workspaceClone.workspacePath,
171
+ '--parallel',
172
+ '--section-ids', workstream.sectionIds.join(','),
173
+ '--branch', workstream.branchName,
174
+ '--parallel-session-id', plan.sessionId,
175
+ ],
176
+ });
177
+ if (!spawnResult.pid) {
178
+ throw new Error(`Failed to start clone runner for ${workstream.branchName}`);
179
+ }
180
+ }
181
+ catch (error) {
182
+ if (workspacePath) {
183
+ fs.rmSync(workspacePath, { recursive: true, force: true });
184
+ }
185
+ throw error;
186
+ }
187
+ }
188
+ }
189
+ finally {
190
+ close();
191
+ }
192
+ return plan.sessionId;
193
+ }
194
+ function spawnDetachedRunner(options) {
195
+ const config = (0, loader_js_1.loadConfig)(options.projectPath);
196
+ const daemonLogsEnabled = config.runners?.daemonLogs !== false;
197
+ let logFile;
198
+ let logFd;
199
+ if (daemonLogsEnabled) {
200
+ const logsDir = path.join(os.homedir(), '.steroids', 'runners', 'logs');
201
+ fs.mkdirSync(logsDir, { recursive: true });
202
+ const tempLogPath = path.join(logsDir, `daemon-${Date.now()}.log`);
203
+ logFd = fs.openSync(tempLogPath, 'a');
204
+ logFile = tempLogPath;
205
+ }
206
+ const child = (0, node_child_process_1.spawn)(process.execPath, options.args, {
207
+ detached: true,
208
+ stdio: daemonLogsEnabled && logFd !== undefined
209
+ ? ['ignore', logFd, logFd]
210
+ : 'ignore',
211
+ });
212
+ child.unref();
213
+ if (logFd !== undefined) {
214
+ fs.closeSync(logFd);
215
+ }
216
+ let finalLogPath;
217
+ if (logFile && child.pid) {
218
+ const logsDir = path.dirname(logFile);
219
+ finalLogPath = path.join(logsDir, `daemon-${child.pid}.log`);
220
+ try {
221
+ fs.renameSync(logFile, finalLogPath);
222
+ }
223
+ catch {
224
+ finalLogPath = logFile;
225
+ }
226
+ }
227
+ return { pid: child.pid ?? null, logFile: finalLogPath };
228
+ }
229
+ //# sourceMappingURL=runners-parallel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runners-parallel.js","sourceRoot":"","sources":["../../src/commands/runners-parallel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { GlobalFlags } from '../cli/flags.js';
2
+ export declare function runWakeup(args: string[], flags: GlobalFlags): Promise<void>;
3
+ export declare function runCron(args: string[]): Promise<void>;
4
+ //# sourceMappingURL=runners-wakeup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runners-wakeup.d.ts","sourceRoot":"","sources":["../../src/commands/runners-wakeup.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFjF;AAED,wBAAsB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA0E3D"}
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runWakeup = runWakeup;
4
+ exports.runCron = runCron;
5
+ const node_util_1 = require("node:util");
6
+ const cron_js_1 = require("../runners/cron.js");
7
+ const wakeup_js_1 = require("../runners/wakeup.js");
8
+ async function runWakeup(args, flags) {
9
+ // Hard timeout: wakeup is spawned by cron/launchd every 60s.
10
+ // If the wakeup function itself hangs (locked DB, TCC blocking file access),
11
+ // force-kill after 30s. SIGKILL is needed because process.exit() can also
12
+ // hang if native addon destructors (better-sqlite3) try to fsync blocked paths.
13
+ const WAKEUP_TIMEOUT_MS = 30_000;
14
+ const killTimer = setTimeout(() => process.kill(process.pid, 'SIGKILL'), WAKEUP_TIMEOUT_MS);
15
+ killTimer.unref();
16
+ const { values } = (0, node_util_1.parseArgs)({
17
+ args,
18
+ options: {
19
+ help: { type: 'boolean', short: 'h', default: false },
20
+ json: { type: 'boolean', short: 'j', default: false },
21
+ quiet: { type: 'boolean', short: 'q', default: false },
22
+ },
23
+ allowPositionals: false,
24
+ });
25
+ if (values.help) {
26
+ console.log(`
27
+ steroids runners wakeup - Check and restart stale runners
28
+
29
+ USAGE:
30
+ steroids runners wakeup [options]
31
+
32
+ OPTIONS:
33
+ --quiet Suppress output (for cron)
34
+ --dry-run Check without acting
35
+ -j, --json Output as JSON
36
+ -h, --help Show help
37
+ `);
38
+ return;
39
+ }
40
+ const results = await (0, wakeup_js_1.wakeup)({
41
+ quiet: values.quiet || flags.quiet || values.json || flags.json,
42
+ dryRun: flags.dryRun,
43
+ });
44
+ if (values.json || flags.json) {
45
+ console.log(JSON.stringify({ results }, null, 2));
46
+ return;
47
+ }
48
+ if (!values.quiet && !flags.quiet) {
49
+ // Summarize results
50
+ const started = results.filter(r => r.action === 'started').length;
51
+ const cleaned = results.filter(r => r.action === 'cleaned').length;
52
+ const wouldStart = results.filter(r => r.action === 'would_start').length;
53
+ if (started > 0) {
54
+ console.log(`Started ${started} runner(s)`);
55
+ }
56
+ if (cleaned > 0) {
57
+ console.log(`Cleaned ${cleaned} stale runner(s)`);
58
+ }
59
+ if (wouldStart > 0) {
60
+ console.log(`Would start ${wouldStart} runner(s) (dry-run)`);
61
+ }
62
+ if (started === 0 && cleaned === 0 && wouldStart === 0) {
63
+ console.log('No action needed');
64
+ }
65
+ // Show per-project details
66
+ for (const result of results) {
67
+ if (result.projectPath) {
68
+ const status = result.action === 'started' ? '✓' :
69
+ result.action === 'would_start' ? '~' : '-';
70
+ console.log(` ${status} ${result.projectPath}: ${result.reason}`);
71
+ }
72
+ }
73
+ }
74
+ // Two-phase exit for wakeup (cron/launchd spawns this every 60s):
75
+ // 1. Try graceful exit first (exit code 0, clean shutdown)
76
+ // 2. If process.exit() hangs (e.g. better-sqlite3 destructors fsyncing WAL
77
+ // files on TCC-protected paths), SIGKILL fires after 2s as a backstop.
78
+ setTimeout(() => process.kill(process.pid, 'SIGKILL'), 2000).unref();
79
+ process.exit(0);
80
+ }
81
+ async function runCron(args) {
82
+ if (args.length === 0 || args[0] === '-h' || args[0] === '--help') {
83
+ console.log(`
84
+ steroids runners cron - Manage cron job
85
+
86
+ USAGE:
87
+ steroids runners cron <subcommand>
88
+
89
+ SUBCOMMANDS:
90
+ install Add cron job (every minute)
91
+ uninstall Remove cron job
92
+ status Check cron status
93
+
94
+ OPTIONS:
95
+ -j, --json Output as JSON
96
+ -h, --help Show help
97
+ `);
98
+ return;
99
+ }
100
+ const subcommand = args[0];
101
+ const subArgs = args.slice(1);
102
+ const { values } = (0, node_util_1.parseArgs)({
103
+ args: subArgs,
104
+ options: {
105
+ json: { type: 'boolean', short: 'j', default: false },
106
+ },
107
+ allowPositionals: false,
108
+ });
109
+ switch (subcommand) {
110
+ case 'install': {
111
+ const result = (0, cron_js_1.cronInstall)();
112
+ if (values.json) {
113
+ console.log(JSON.stringify(result, null, 2));
114
+ }
115
+ else {
116
+ console.log(result.message);
117
+ if (result.error) {
118
+ console.error(result.error);
119
+ }
120
+ }
121
+ break;
122
+ }
123
+ case 'uninstall': {
124
+ const result = (0, cron_js_1.cronUninstall)();
125
+ if (values.json) {
126
+ console.log(JSON.stringify(result, null, 2));
127
+ }
128
+ else {
129
+ console.log(result.message);
130
+ }
131
+ break;
132
+ }
133
+ case 'status': {
134
+ const status = (0, cron_js_1.cronStatus)();
135
+ if (values.json) {
136
+ console.log(JSON.stringify(status, null, 2));
137
+ }
138
+ else {
139
+ if (status.installed) {
140
+ console.log('Cron job: INSTALLED');
141
+ console.log(` Entry: ${status.entry}`);
142
+ }
143
+ else {
144
+ console.log('Cron job: NOT INSTALLED');
145
+ if (status.error) {
146
+ console.log(` ${status.error}`);
147
+ }
148
+ }
149
+ }
150
+ break;
151
+ }
152
+ default:
153
+ console.error(`Unknown cron subcommand: ${subcommand}`);
154
+ process.exit(1);
155
+ }
156
+ }
157
+ //# sourceMappingURL=runners-wakeup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runners-wakeup.js","sourceRoot":"","sources":["../../src/commands/runners-wakeup.ts"],"names":[],"mappings":"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"}