steroids-cli 0.4.47
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.
- package/LICENSE +21 -0
- package/README.md +640 -0
- package/dist/cli/colors.d.ts +110 -0
- package/dist/cli/colors.d.ts.map +1 -0
- package/dist/cli/colors.js +228 -0
- package/dist/cli/colors.js.map +1 -0
- package/dist/cli/env.d.ts +159 -0
- package/dist/cli/env.d.ts.map +1 -0
- package/dist/cli/env.js +227 -0
- package/dist/cli/env.js.map +1 -0
- package/dist/cli/errors.d.ts +166 -0
- package/dist/cli/errors.d.ts.map +1 -0
- package/dist/cli/errors.js +244 -0
- package/dist/cli/errors.js.map +1 -0
- package/dist/cli/flags.d.ts +75 -0
- package/dist/cli/flags.d.ts.map +1 -0
- package/dist/cli/flags.js +232 -0
- package/dist/cli/flags.js.map +1 -0
- package/dist/cli/help.d.ts +97 -0
- package/dist/cli/help.d.ts.map +1 -0
- package/dist/cli/help.js +275 -0
- package/dist/cli/help.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/interactive.d.ts +58 -0
- package/dist/cli/interactive.d.ts.map +1 -0
- package/dist/cli/interactive.js +127 -0
- package/dist/cli/interactive.js.map +1 -0
- package/dist/cli/output.d.ts +116 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +178 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/commands/about.d.ts +7 -0
- package/dist/commands/about.d.ts.map +1 -0
- package/dist/commands/about.js +259 -0
- package/dist/commands/about.js.map +1 -0
- package/dist/commands/ai.d.ts +6 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +382 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/backup.d.ts +3 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +528 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/completion.d.ts +3 -0
- package/dist/commands/completion.d.ts.map +1 -0
- package/dist/commands/completion.js +405 -0
- package/dist/commands/completion.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +665 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/disputes.d.ts +3 -0
- package/dist/commands/disputes.d.ts.map +1 -0
- package/dist/commands/disputes.js +499 -0
- package/dist/commands/disputes.js.map +1 -0
- package/dist/commands/gc.d.ts +3 -0
- package/dist/commands/gc.d.ts.map +1 -0
- package/dist/commands/gc.js +300 -0
- package/dist/commands/gc.js.map +1 -0
- package/dist/commands/git.d.ts +3 -0
- package/dist/commands/git.d.ts.map +1 -0
- package/dist/commands/git.js +458 -0
- package/dist/commands/git.js.map +1 -0
- package/dist/commands/health.d.ts +3 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +604 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/hooks.d.ts +6 -0
- package/dist/commands/hooks.d.ts.map +1 -0
- package/dist/commands/hooks.js +529 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/init.d.ts +6 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +200 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/llm.d.ts +7 -0
- package/dist/commands/llm.d.ts.map +1 -0
- package/dist/commands/llm.js +285 -0
- package/dist/commands/llm.js.map +1 -0
- package/dist/commands/locks.d.ts +3 -0
- package/dist/commands/locks.d.ts.map +1 -0
- package/dist/commands/locks.js +431 -0
- package/dist/commands/locks.js.map +1 -0
- package/dist/commands/logs.d.ts +3 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +487 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/loop-phases.d.ts +11 -0
- package/dist/commands/loop-phases.d.ts.map +1 -0
- package/dist/commands/loop-phases.js +204 -0
- package/dist/commands/loop-phases.js.map +1 -0
- package/dist/commands/loop.d.ts +3 -0
- package/dist/commands/loop.d.ts.map +1 -0
- package/dist/commands/loop.js +396 -0
- package/dist/commands/loop.js.map +1 -0
- package/dist/commands/projects.d.ts +6 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +362 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/purge.d.ts +3 -0
- package/dist/commands/purge.d.ts.map +1 -0
- package/dist/commands/purge.js +516 -0
- package/dist/commands/purge.js.map +1 -0
- package/dist/commands/runners.d.ts +3 -0
- package/dist/commands/runners.d.ts.map +1 -0
- package/dist/commands/runners.js +1076 -0
- package/dist/commands/runners.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +291 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/sections-commands.d.ts +9 -0
- package/dist/commands/sections-commands.d.ts.map +1 -0
- package/dist/commands/sections-commands.js +282 -0
- package/dist/commands/sections-commands.js.map +1 -0
- package/dist/commands/sections-graph.d.ts +25 -0
- package/dist/commands/sections-graph.d.ts.map +1 -0
- package/dist/commands/sections-graph.js +180 -0
- package/dist/commands/sections-graph.js.map +1 -0
- package/dist/commands/sections.d.ts +3 -0
- package/dist/commands/sections.d.ts.map +1 -0
- package/dist/commands/sections.js +376 -0
- package/dist/commands/sections.js.map +1 -0
- package/dist/commands/stats.d.ts +6 -0
- package/dist/commands/stats.d.ts.map +1 -0
- package/dist/commands/stats.js +324 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/tasks.d.ts +3 -0
- package/dist/commands/tasks.d.ts.map +1 -0
- package/dist/commands/tasks.js +1115 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/web.d.ts +7 -0
- package/dist/commands/web.d.ts.map +1 -0
- package/dist/commands/web.js +204 -0
- package/dist/commands/web.js.map +1 -0
- package/dist/config/ai-setup.d.ts +27 -0
- package/dist/config/ai-setup.d.ts.map +1 -0
- package/dist/config/ai-setup.js +432 -0
- package/dist/config/ai-setup.js.map +1 -0
- package/dist/config/browser.d.ts +9 -0
- package/dist/config/browser.d.ts.map +1 -0
- package/dist/config/browser.js +200 -0
- package/dist/config/browser.js.map +1 -0
- package/dist/config/json-schema.d.ts +28 -0
- package/dist/config/json-schema.d.ts.map +1 -0
- package/dist/config/json-schema.js +84 -0
- package/dist/config/json-schema.js.map +1 -0
- package/dist/config/loader.d.ts +152 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +270 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +34 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +437 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/validator.d.ts +32 -0
- package/dist/config/validator.d.ts.map +1 -0
- package/dist/config/validator.js +187 -0
- package/dist/config/validator.js.map +1 -0
- package/dist/database/connection.d.ts +35 -0
- package/dist/database/connection.d.ts.map +1 -0
- package/dist/database/connection.js +208 -0
- package/dist/database/connection.js.map +1 -0
- package/dist/database/queries.d.ts +218 -0
- package/dist/database/queries.d.ts.map +1 -0
- package/dist/database/queries.js +613 -0
- package/dist/database/queries.js.map +1 -0
- package/dist/database/schema.d.ts +8 -0
- package/dist/database/schema.d.ts.map +1 -0
- package/dist/database/schema.js +160 -0
- package/dist/database/schema.js.map +1 -0
- package/dist/disputes/behavior.d.ts +106 -0
- package/dist/disputes/behavior.d.ts.map +1 -0
- package/dist/disputes/behavior.js +150 -0
- package/dist/disputes/behavior.js.map +1 -0
- package/dist/disputes/create.d.ts +59 -0
- package/dist/disputes/create.d.ts.map +1 -0
- package/dist/disputes/create.js +222 -0
- package/dist/disputes/create.js.map +1 -0
- package/dist/disputes/index.d.ts +21 -0
- package/dist/disputes/index.d.ts.map +1 -0
- package/dist/disputes/index.js +76 -0
- package/dist/disputes/index.js.map +1 -0
- package/dist/disputes/markdown.d.ts +41 -0
- package/dist/disputes/markdown.d.ts.map +1 -0
- package/dist/disputes/markdown.js +261 -0
- package/dist/disputes/markdown.js.map +1 -0
- package/dist/disputes/queries.d.ts +83 -0
- package/dist/disputes/queries.d.ts.map +1 -0
- package/dist/disputes/queries.js +180 -0
- package/dist/disputes/queries.js.map +1 -0
- package/dist/disputes/resolve.d.ts +57 -0
- package/dist/disputes/resolve.d.ts.map +1 -0
- package/dist/disputes/resolve.js +171 -0
- package/dist/disputes/resolve.js.map +1 -0
- package/dist/disputes/stale.d.ts +98 -0
- package/dist/disputes/stale.d.ts.map +1 -0
- package/dist/disputes/stale.js +205 -0
- package/dist/disputes/stale.js.map +1 -0
- package/dist/disputes/types.d.ts +92 -0
- package/dist/disputes/types.d.ts.map +1 -0
- package/dist/disputes/types.js +100 -0
- package/dist/disputes/types.js.map +1 -0
- package/dist/git/push.d.ts +26 -0
- package/dist/git/push.d.ts.map +1 -0
- package/dist/git/push.js +97 -0
- package/dist/git/push.js.map +1 -0
- package/dist/git/status.d.ts +61 -0
- package/dist/git/status.d.ts.map +1 -0
- package/dist/git/status.js +251 -0
- package/dist/git/status.js.map +1 -0
- package/dist/hooks/events.d.ts +72 -0
- package/dist/hooks/events.d.ts.map +1 -0
- package/dist/hooks/events.js +120 -0
- package/dist/hooks/events.js.map +1 -0
- package/dist/hooks/index.d.ts +19 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +48 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/integration.d.ts +69 -0
- package/dist/hooks/integration.d.ts.map +1 -0
- package/dist/hooks/integration.js +179 -0
- package/dist/hooks/integration.js.map +1 -0
- package/dist/hooks/merge.d.ts +115 -0
- package/dist/hooks/merge.d.ts.map +1 -0
- package/dist/hooks/merge.js +161 -0
- package/dist/hooks/merge.js.map +1 -0
- package/dist/hooks/orchestrator.d.ts +115 -0
- package/dist/hooks/orchestrator.d.ts.map +1 -0
- package/dist/hooks/orchestrator.js +226 -0
- package/dist/hooks/orchestrator.js.map +1 -0
- package/dist/hooks/payload.d.ts +294 -0
- package/dist/hooks/payload.d.ts.map +1 -0
- package/dist/hooks/payload.js +267 -0
- package/dist/hooks/payload.js.map +1 -0
- package/dist/hooks/script-runner.d.ts +63 -0
- package/dist/hooks/script-runner.d.ts.map +1 -0
- package/dist/hooks/script-runner.js +221 -0
- package/dist/hooks/script-runner.js.map +1 -0
- package/dist/hooks/templates.d.ts +104 -0
- package/dist/hooks/templates.d.ts.map +1 -0
- package/dist/hooks/templates.js +327 -0
- package/dist/hooks/templates.js.map +1 -0
- package/dist/hooks/webhook-runner.d.ts +69 -0
- package/dist/hooks/webhook-runner.d.ts.map +1 -0
- package/dist/hooks/webhook-runner.js +208 -0
- package/dist/hooks/webhook-runner.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +281 -0
- package/dist/index.js.map +1 -0
- package/dist/locking/cleanup.d.ts +70 -0
- package/dist/locking/cleanup.d.ts.map +1 -0
- package/dist/locking/cleanup.js +157 -0
- package/dist/locking/cleanup.js.map +1 -0
- package/dist/locking/queries.d.ts +116 -0
- package/dist/locking/queries.d.ts.map +1 -0
- package/dist/locking/queries.js +255 -0
- package/dist/locking/queries.js.map +1 -0
- package/dist/locking/section-lock.d.ts +74 -0
- package/dist/locking/section-lock.d.ts.map +1 -0
- package/dist/locking/section-lock.js +207 -0
- package/dist/locking/section-lock.js.map +1 -0
- package/dist/locking/task-lock.d.ts +92 -0
- package/dist/locking/task-lock.d.ts.map +1 -0
- package/dist/locking/task-lock.js +246 -0
- package/dist/locking/task-lock.js.map +1 -0
- package/dist/migrations/index.d.ts +7 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +37 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/manifest.d.ts +92 -0
- package/dist/migrations/manifest.d.ts.map +1 -0
- package/dist/migrations/manifest.js +270 -0
- package/dist/migrations/manifest.js.map +1 -0
- package/dist/migrations/runner.d.ts +84 -0
- package/dist/migrations/runner.d.ts.map +1 -0
- package/dist/migrations/runner.js +351 -0
- package/dist/migrations/runner.js.map +1 -0
- package/dist/orchestrator/coder.d.ts +32 -0
- package/dist/orchestrator/coder.d.ts.map +1 -0
- package/dist/orchestrator/coder.js +174 -0
- package/dist/orchestrator/coder.js.map +1 -0
- package/dist/orchestrator/coordinator.d.ts +28 -0
- package/dist/orchestrator/coordinator.d.ts.map +1 -0
- package/dist/orchestrator/coordinator.js +256 -0
- package/dist/orchestrator/coordinator.js.map +1 -0
- package/dist/orchestrator/reviewer.d.ts +35 -0
- package/dist/orchestrator/reviewer.d.ts.map +1 -0
- package/dist/orchestrator/reviewer.js +241 -0
- package/dist/orchestrator/reviewer.js.map +1 -0
- package/dist/orchestrator/task-selector.d.ts +102 -0
- package/dist/orchestrator/task-selector.d.ts.map +1 -0
- package/dist/orchestrator/task-selector.js +341 -0
- package/dist/orchestrator/task-selector.js.map +1 -0
- package/dist/prompts/coder.d.ts +36 -0
- package/dist/prompts/coder.d.ts.map +1 -0
- package/dist/prompts/coder.js +315 -0
- package/dist/prompts/coder.js.map +1 -0
- package/dist/prompts/prompt-helpers.d.ts +51 -0
- package/dist/prompts/prompt-helpers.d.ts.map +1 -0
- package/dist/prompts/prompt-helpers.js +312 -0
- package/dist/prompts/prompt-helpers.js.map +1 -0
- package/dist/prompts/reviewer.d.ts +40 -0
- package/dist/prompts/reviewer.d.ts.map +1 -0
- package/dist/prompts/reviewer.js +438 -0
- package/dist/prompts/reviewer.js.map +1 -0
- package/dist/providers/api-models.d.ts +65 -0
- package/dist/providers/api-models.d.ts.map +1 -0
- package/dist/providers/api-models.js +323 -0
- package/dist/providers/api-models.js.map +1 -0
- package/dist/providers/claude.d.ts +53 -0
- package/dist/providers/claude.d.ts.map +1 -0
- package/dist/providers/claude.js +229 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +53 -0
- package/dist/providers/codex.d.ts.map +1 -0
- package/dist/providers/codex.js +214 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/gemini.d.ts +58 -0
- package/dist/providers/gemini.d.ts.map +1 -0
- package/dist/providers/gemini.js +242 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +13 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +49 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/interface.d.ts +173 -0
- package/dist/providers/interface.d.ts.map +1 -0
- package/dist/providers/interface.js +96 -0
- package/dist/providers/interface.js.map +1 -0
- package/dist/providers/invocation-logger.d.ts +114 -0
- package/dist/providers/invocation-logger.d.ts.map +1 -0
- package/dist/providers/invocation-logger.js +298 -0
- package/dist/providers/invocation-logger.js.map +1 -0
- package/dist/providers/openai.d.ts +53 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +232 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/registry.d.ts +100 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +178 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/runners/activity-log.d.ts +65 -0
- package/dist/runners/activity-log.d.ts.map +1 -0
- package/dist/runners/activity-log.js +148 -0
- package/dist/runners/activity-log.js.map +1 -0
- package/dist/runners/cron.d.ts +26 -0
- package/dist/runners/cron.d.ts.map +1 -0
- package/dist/runners/cron.js +176 -0
- package/dist/runners/cron.js.map +1 -0
- package/dist/runners/daemon.d.ts +71 -0
- package/dist/runners/daemon.d.ts.map +1 -0
- package/dist/runners/daemon.js +245 -0
- package/dist/runners/daemon.js.map +1 -0
- package/dist/runners/global-db.d.ts +31 -0
- package/dist/runners/global-db.d.ts.map +1 -0
- package/dist/runners/global-db.js +230 -0
- package/dist/runners/global-db.js.map +1 -0
- package/dist/runners/hang-detector.d.ts +38 -0
- package/dist/runners/hang-detector.d.ts.map +1 -0
- package/dist/runners/hang-detector.js +136 -0
- package/dist/runners/hang-detector.js.map +1 -0
- package/dist/runners/heartbeat.d.ts +39 -0
- package/dist/runners/heartbeat.d.ts.map +1 -0
- package/dist/runners/heartbeat.js +79 -0
- package/dist/runners/heartbeat.js.map +1 -0
- package/dist/runners/lock.d.ts +47 -0
- package/dist/runners/lock.d.ts.map +1 -0
- package/dist/runners/lock.js +150 -0
- package/dist/runners/lock.js.map +1 -0
- package/dist/runners/orchestrator-loop.d.ts +20 -0
- package/dist/runners/orchestrator-loop.d.ts.map +1 -0
- package/dist/runners/orchestrator-loop.js +285 -0
- package/dist/runners/orchestrator-loop.js.map +1 -0
- package/dist/runners/projects.d.ts +96 -0
- package/dist/runners/projects.d.ts.map +1 -0
- package/dist/runners/projects.js +255 -0
- package/dist/runners/projects.js.map +1 -0
- package/dist/runners/wakeup.d.ts +34 -0
- package/dist/runners/wakeup.d.ts.map +1 -0
- package/dist/runners/wakeup.js +291 -0
- package/dist/runners/wakeup.js.map +1 -0
- package/migrations/001_initial_schema.sql +106 -0
- package/migrations/002_add_commit_sha.sql +12 -0
- package/migrations/003_add_section_priority.sql +13 -0
- package/migrations/004_add_section_dependencies.sql +18 -0
- package/migrations/005_add_audit_actor_model.sql +10 -0
- package/migrations/006_add_task_invocations.sql +33 -0
- package/migrations/007_add_file_anchor.sql +14 -0
- package/migrations/manifest.json +62 -0
- package/package.json +49 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Global database for runner state
|
|
4
|
+
* Located at ~/.steroids/steroids.db (user home, not project)
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.getGlobalSteroidsDir = getGlobalSteroidsDir;
|
|
11
|
+
exports.getGlobalDbPath = getGlobalDbPath;
|
|
12
|
+
exports.isGlobalDbInitialized = isGlobalDbInitialized;
|
|
13
|
+
exports.openGlobalDatabase = openGlobalDatabase;
|
|
14
|
+
exports.getGlobalSchemaVersion = getGlobalSchemaVersion;
|
|
15
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
16
|
+
const node_fs_1 = require("node:fs");
|
|
17
|
+
const node_path_1 = require("node:path");
|
|
18
|
+
const node_os_1 = require("node:os");
|
|
19
|
+
const STEROIDS_DIR = '.steroids';
|
|
20
|
+
const DB_NAME = 'steroids.db';
|
|
21
|
+
/**
|
|
22
|
+
* Schema for global database (runners and locks)
|
|
23
|
+
*/
|
|
24
|
+
const GLOBAL_SCHEMA_SQL = `
|
|
25
|
+
-- Runners table for tracking runner state
|
|
26
|
+
CREATE TABLE IF NOT EXISTS runners (
|
|
27
|
+
id TEXT PRIMARY KEY,
|
|
28
|
+
status TEXT NOT NULL DEFAULT 'idle',
|
|
29
|
+
pid INTEGER,
|
|
30
|
+
project_path TEXT,
|
|
31
|
+
current_task_id TEXT,
|
|
32
|
+
started_at TEXT,
|
|
33
|
+
heartbeat_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
-- Runner lock for singleton enforcement
|
|
37
|
+
-- Only one row allowed (id = 1)
|
|
38
|
+
CREATE TABLE IF NOT EXISTS runner_lock (
|
|
39
|
+
id INTEGER PRIMARY KEY CHECK (id = 1),
|
|
40
|
+
runner_id TEXT NOT NULL,
|
|
41
|
+
acquired_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
-- Schema metadata
|
|
45
|
+
CREATE TABLE IF NOT EXISTS _global_schema (
|
|
46
|
+
key TEXT PRIMARY KEY,
|
|
47
|
+
value TEXT NOT NULL
|
|
48
|
+
);
|
|
49
|
+
`;
|
|
50
|
+
/**
|
|
51
|
+
* Schema upgrade from version 1 to version 2: Add projects table
|
|
52
|
+
*/
|
|
53
|
+
const GLOBAL_SCHEMA_V2_SQL = `
|
|
54
|
+
-- Projects table for tracking registered projects
|
|
55
|
+
CREATE TABLE IF NOT EXISTS projects (
|
|
56
|
+
path TEXT PRIMARY KEY,
|
|
57
|
+
name TEXT,
|
|
58
|
+
registered_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
59
|
+
last_seen_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
60
|
+
enabled INTEGER NOT NULL DEFAULT 1
|
|
61
|
+
);
|
|
62
|
+
`;
|
|
63
|
+
/**
|
|
64
|
+
* Schema upgrade from version 2 to version 3: Add stats columns to projects table
|
|
65
|
+
*/
|
|
66
|
+
const GLOBAL_SCHEMA_V3_SQL = `
|
|
67
|
+
-- Add task stats columns (for API/WebUI display without accessing project DBs)
|
|
68
|
+
ALTER TABLE projects ADD COLUMN pending_count INTEGER DEFAULT 0;
|
|
69
|
+
ALTER TABLE projects ADD COLUMN in_progress_count INTEGER DEFAULT 0;
|
|
70
|
+
ALTER TABLE projects ADD COLUMN review_count INTEGER DEFAULT 0;
|
|
71
|
+
ALTER TABLE projects ADD COLUMN completed_count INTEGER DEFAULT 0;
|
|
72
|
+
ALTER TABLE projects ADD COLUMN stats_updated_at TEXT;
|
|
73
|
+
`;
|
|
74
|
+
/**
|
|
75
|
+
* Schema upgrade from version 3 to version 4: Add section_id to runners table
|
|
76
|
+
*/
|
|
77
|
+
const GLOBAL_SCHEMA_V4_SQL = `
|
|
78
|
+
-- Add section_id column to runners for section focus feature
|
|
79
|
+
ALTER TABLE runners ADD COLUMN section_id TEXT;
|
|
80
|
+
`;
|
|
81
|
+
/**
|
|
82
|
+
* Schema upgrade from version 4 to version 5: Add activity_log table
|
|
83
|
+
*/
|
|
84
|
+
const GLOBAL_SCHEMA_V5_SQL = `
|
|
85
|
+
-- Activity log for tracking task completions across all projects
|
|
86
|
+
CREATE TABLE IF NOT EXISTS activity_log (
|
|
87
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
88
|
+
project_path TEXT NOT NULL,
|
|
89
|
+
runner_id TEXT NOT NULL,
|
|
90
|
+
task_id TEXT NOT NULL,
|
|
91
|
+
task_title TEXT NOT NULL,
|
|
92
|
+
section_name TEXT,
|
|
93
|
+
final_status TEXT NOT NULL,
|
|
94
|
+
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
95
|
+
);
|
|
96
|
+
CREATE INDEX IF NOT EXISTS idx_activity_log_created_at ON activity_log(created_at);
|
|
97
|
+
CREATE INDEX IF NOT EXISTS idx_activity_log_project ON activity_log(project_path);
|
|
98
|
+
`;
|
|
99
|
+
/**
|
|
100
|
+
* Schema upgrade from version 5 to version 6: Add commit_message to activity_log
|
|
101
|
+
*/
|
|
102
|
+
const GLOBAL_SCHEMA_V6_SQL = `
|
|
103
|
+
-- Add commit_message column to activity_log for storing coder's final message
|
|
104
|
+
ALTER TABLE activity_log ADD COLUMN commit_message TEXT;
|
|
105
|
+
`;
|
|
106
|
+
/**
|
|
107
|
+
* Schema upgrade from version 6 to version 7: Add commit_sha to activity_log
|
|
108
|
+
*/
|
|
109
|
+
const GLOBAL_SCHEMA_V7_SQL = `
|
|
110
|
+
-- Add commit_sha column to activity_log for GitHub links
|
|
111
|
+
ALTER TABLE activity_log ADD COLUMN commit_sha TEXT;
|
|
112
|
+
`;
|
|
113
|
+
const GLOBAL_SCHEMA_VERSION = '7';
|
|
114
|
+
/**
|
|
115
|
+
* Get the path to the global steroids directory
|
|
116
|
+
*/
|
|
117
|
+
function getGlobalSteroidsDir() {
|
|
118
|
+
return (0, node_path_1.join)((0, node_os_1.homedir)(), STEROIDS_DIR);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get the path to the global database
|
|
122
|
+
*/
|
|
123
|
+
function getGlobalDbPath() {
|
|
124
|
+
return (0, node_path_1.join)(getGlobalSteroidsDir(), DB_NAME);
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Check if global database exists
|
|
128
|
+
*/
|
|
129
|
+
function isGlobalDbInitialized() {
|
|
130
|
+
return (0, node_fs_1.existsSync)(getGlobalDbPath());
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Initialize and open the global database
|
|
134
|
+
* Creates it if it doesn't exist
|
|
135
|
+
*/
|
|
136
|
+
function openGlobalDatabase() {
|
|
137
|
+
const dbPath = getGlobalDbPath();
|
|
138
|
+
const steroidsDir = getGlobalSteroidsDir();
|
|
139
|
+
// Create ~/.steroids directory if it doesn't exist
|
|
140
|
+
if (!(0, node_fs_1.existsSync)(steroidsDir)) {
|
|
141
|
+
(0, node_fs_1.mkdirSync)(steroidsDir, { recursive: true });
|
|
142
|
+
}
|
|
143
|
+
const db = new better_sqlite3_1.default(dbPath);
|
|
144
|
+
// Configure SQLite for optimal performance and safety
|
|
145
|
+
db.pragma('journal_mode = WAL');
|
|
146
|
+
db.pragma('busy_timeout = 5000');
|
|
147
|
+
// Create base schema (IF NOT EXISTS makes this idempotent)
|
|
148
|
+
db.exec(GLOBAL_SCHEMA_SQL);
|
|
149
|
+
// Get current version
|
|
150
|
+
const versionRow = db
|
|
151
|
+
.prepare('SELECT value FROM _global_schema WHERE key = ?')
|
|
152
|
+
.get('version');
|
|
153
|
+
const currentVersion = versionRow?.value;
|
|
154
|
+
if (!currentVersion) {
|
|
155
|
+
// Fresh database - apply all schemas and set to latest version
|
|
156
|
+
db.exec(GLOBAL_SCHEMA_V2_SQL);
|
|
157
|
+
db.exec(GLOBAL_SCHEMA_V3_SQL);
|
|
158
|
+
db.exec(GLOBAL_SCHEMA_V4_SQL);
|
|
159
|
+
db.exec(GLOBAL_SCHEMA_V5_SQL);
|
|
160
|
+
db.exec(GLOBAL_SCHEMA_V6_SQL);
|
|
161
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
162
|
+
db.prepare('INSERT INTO _global_schema (key, value) VALUES (?, ?)').run('version', GLOBAL_SCHEMA_VERSION);
|
|
163
|
+
db.prepare('INSERT INTO _global_schema (key, value) VALUES (?, ?)').run('created_at', new Date().toISOString());
|
|
164
|
+
}
|
|
165
|
+
else if (currentVersion === '1') {
|
|
166
|
+
// Upgrade from version 1 to latest
|
|
167
|
+
db.exec(GLOBAL_SCHEMA_V2_SQL);
|
|
168
|
+
db.exec(GLOBAL_SCHEMA_V3_SQL);
|
|
169
|
+
db.exec(GLOBAL_SCHEMA_V4_SQL);
|
|
170
|
+
db.exec(GLOBAL_SCHEMA_V5_SQL);
|
|
171
|
+
db.exec(GLOBAL_SCHEMA_V6_SQL);
|
|
172
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
173
|
+
db.prepare('UPDATE _global_schema SET value = ? WHERE key = ?').run(GLOBAL_SCHEMA_VERSION, 'version');
|
|
174
|
+
}
|
|
175
|
+
else if (currentVersion === '2') {
|
|
176
|
+
// Upgrade from version 2 to latest
|
|
177
|
+
db.exec(GLOBAL_SCHEMA_V3_SQL);
|
|
178
|
+
db.exec(GLOBAL_SCHEMA_V4_SQL);
|
|
179
|
+
db.exec(GLOBAL_SCHEMA_V5_SQL);
|
|
180
|
+
db.exec(GLOBAL_SCHEMA_V6_SQL);
|
|
181
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
182
|
+
db.prepare('UPDATE _global_schema SET value = ? WHERE key = ?').run(GLOBAL_SCHEMA_VERSION, 'version');
|
|
183
|
+
}
|
|
184
|
+
else if (currentVersion === '3') {
|
|
185
|
+
// Upgrade from version 3 to latest
|
|
186
|
+
db.exec(GLOBAL_SCHEMA_V4_SQL);
|
|
187
|
+
db.exec(GLOBAL_SCHEMA_V5_SQL);
|
|
188
|
+
db.exec(GLOBAL_SCHEMA_V6_SQL);
|
|
189
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
190
|
+
db.prepare('UPDATE _global_schema SET value = ? WHERE key = ?').run(GLOBAL_SCHEMA_VERSION, 'version');
|
|
191
|
+
}
|
|
192
|
+
else if (currentVersion === '4') {
|
|
193
|
+
// Upgrade from version 4 to latest
|
|
194
|
+
db.exec(GLOBAL_SCHEMA_V5_SQL);
|
|
195
|
+
db.exec(GLOBAL_SCHEMA_V6_SQL);
|
|
196
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
197
|
+
db.prepare('UPDATE _global_schema SET value = ? WHERE key = ?').run(GLOBAL_SCHEMA_VERSION, 'version');
|
|
198
|
+
}
|
|
199
|
+
else if (currentVersion === '5') {
|
|
200
|
+
// Upgrade from version 5 to latest
|
|
201
|
+
db.exec(GLOBAL_SCHEMA_V6_SQL);
|
|
202
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
203
|
+
db.prepare('UPDATE _global_schema SET value = ? WHERE key = ?').run(GLOBAL_SCHEMA_VERSION, 'version');
|
|
204
|
+
}
|
|
205
|
+
else if (currentVersion === '6') {
|
|
206
|
+
// Upgrade from version 6 to version 7
|
|
207
|
+
db.exec(GLOBAL_SCHEMA_V7_SQL);
|
|
208
|
+
db.prepare('UPDATE _global_schema SET value = ? WHERE key = ?').run(GLOBAL_SCHEMA_VERSION, 'version');
|
|
209
|
+
}
|
|
210
|
+
// Future upgrades would be handled here with additional conditions
|
|
211
|
+
return {
|
|
212
|
+
db,
|
|
213
|
+
close: () => db.close(),
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Get global schema version
|
|
218
|
+
*/
|
|
219
|
+
function getGlobalSchemaVersion(db) {
|
|
220
|
+
try {
|
|
221
|
+
const row = db
|
|
222
|
+
.prepare('SELECT value FROM _global_schema WHERE key = ?')
|
|
223
|
+
.get('version');
|
|
224
|
+
return row?.value ?? null;
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=global-db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-db.js","sourceRoot":"","sources":["../../src/runners/global-db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Subprocess hang detection
|
|
3
|
+
* Monitors log output and kills processes that appear stuck
|
|
4
|
+
*/
|
|
5
|
+
import type { ChildProcess } from 'node:child_process';
|
|
6
|
+
export interface HangDetectorOptions {
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
onHang?: (lastOutput: Date, elapsedMs: number) => void;
|
|
9
|
+
onOutput?: () => void;
|
|
10
|
+
}
|
|
11
|
+
export interface HangDetector {
|
|
12
|
+
recordOutput: () => void;
|
|
13
|
+
isHung: () => boolean;
|
|
14
|
+
getLastOutputTime: () => Date;
|
|
15
|
+
getElapsedSinceOutput: () => number;
|
|
16
|
+
stop: () => void;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create a hang detector for a subprocess
|
|
20
|
+
* Monitors output activity and detects when a process appears stuck
|
|
21
|
+
*/
|
|
22
|
+
export declare function createHangDetector(options?: HangDetectorOptions): HangDetector;
|
|
23
|
+
/**
|
|
24
|
+
* Attach hang detection to a child process
|
|
25
|
+
* Monitors stdout/stderr for output activity
|
|
26
|
+
*/
|
|
27
|
+
export declare function attachHangDetector(child: ChildProcess, options?: HangDetectorOptions & {
|
|
28
|
+
killOnHang?: boolean;
|
|
29
|
+
}): HangDetector;
|
|
30
|
+
/**
|
|
31
|
+
* Get default hang timeout in milliseconds
|
|
32
|
+
*/
|
|
33
|
+
export declare function getDefaultHangTimeout(): number;
|
|
34
|
+
/**
|
|
35
|
+
* Format elapsed time for display
|
|
36
|
+
*/
|
|
37
|
+
export declare function formatElapsed(ms: number): string;
|
|
38
|
+
//# sourceMappingURL=hang-detector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hang-detector.d.ts","sourceRoot":"","sources":["../../src/runners/hang-detector.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIvD,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,OAAO,CAAC;IACtB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,qBAAqB,EAAE,MAAM,MAAM,CAAC;IACpC,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,GAAE,mBAAwB,GAChC,YAAY,CAmDd;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,mBAAmB,GAAG;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,YAAY,CA2Dd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAYhD"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Subprocess hang detection
|
|
4
|
+
* Monitors log output and kills processes that appear stuck
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createHangDetector = createHangDetector;
|
|
8
|
+
exports.attachHangDetector = attachHangDetector;
|
|
9
|
+
exports.getDefaultHangTimeout = getDefaultHangTimeout;
|
|
10
|
+
exports.formatElapsed = formatElapsed;
|
|
11
|
+
const DEFAULT_HANG_TIMEOUT_MS = 15 * 60 * 1000; // 15 minutes
|
|
12
|
+
/**
|
|
13
|
+
* Create a hang detector for a subprocess
|
|
14
|
+
* Monitors output activity and detects when a process appears stuck
|
|
15
|
+
*/
|
|
16
|
+
function createHangDetector(options = {}) {
|
|
17
|
+
const { timeoutMs = DEFAULT_HANG_TIMEOUT_MS, onHang, onOutput } = options;
|
|
18
|
+
let lastOutputTime = new Date();
|
|
19
|
+
let checkInterval = null;
|
|
20
|
+
let hasNotifiedHang = false;
|
|
21
|
+
const recordOutput = () => {
|
|
22
|
+
lastOutputTime = new Date();
|
|
23
|
+
hasNotifiedHang = false;
|
|
24
|
+
if (onOutput) {
|
|
25
|
+
onOutput();
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
const getElapsedSinceOutput = () => {
|
|
29
|
+
return Date.now() - lastOutputTime.getTime();
|
|
30
|
+
};
|
|
31
|
+
const isHung = () => {
|
|
32
|
+
return getElapsedSinceOutput() > timeoutMs;
|
|
33
|
+
};
|
|
34
|
+
const getLastOutputTime = () => {
|
|
35
|
+
return lastOutputTime;
|
|
36
|
+
};
|
|
37
|
+
// Start periodic check
|
|
38
|
+
checkInterval = setInterval(() => {
|
|
39
|
+
if (isHung() && !hasNotifiedHang) {
|
|
40
|
+
hasNotifiedHang = true;
|
|
41
|
+
if (onHang) {
|
|
42
|
+
onHang(lastOutputTime, getElapsedSinceOutput());
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}, 60 * 1000); // Check every minute
|
|
46
|
+
const stop = () => {
|
|
47
|
+
if (checkInterval) {
|
|
48
|
+
clearInterval(checkInterval);
|
|
49
|
+
checkInterval = null;
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
return {
|
|
53
|
+
recordOutput,
|
|
54
|
+
isHung,
|
|
55
|
+
getLastOutputTime,
|
|
56
|
+
getElapsedSinceOutput,
|
|
57
|
+
stop,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Attach hang detection to a child process
|
|
62
|
+
* Monitors stdout/stderr for output activity
|
|
63
|
+
*/
|
|
64
|
+
function attachHangDetector(child, options = {}) {
|
|
65
|
+
const { killOnHang = true, ...detectorOptions } = options;
|
|
66
|
+
const detector = createHangDetector({
|
|
67
|
+
...detectorOptions,
|
|
68
|
+
onHang: (lastOutput, elapsed) => {
|
|
69
|
+
const minutes = Math.floor(elapsed / 60000);
|
|
70
|
+
console.error(`Process appears hung (no output for ${minutes} minutes)`);
|
|
71
|
+
if (killOnHang && child.pid) {
|
|
72
|
+
console.error(`Killing hung process (PID: ${child.pid})`);
|
|
73
|
+
try {
|
|
74
|
+
child.kill('SIGTERM');
|
|
75
|
+
// Force kill after 10 seconds if still alive
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
try {
|
|
78
|
+
child.kill('SIGKILL');
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
// Process already dead
|
|
82
|
+
}
|
|
83
|
+
}, 10000);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
// Process already dead
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (detectorOptions.onHang) {
|
|
90
|
+
detectorOptions.onHang(lastOutput, elapsed);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
// Monitor stdout
|
|
95
|
+
if (child.stdout) {
|
|
96
|
+
child.stdout.on('data', () => {
|
|
97
|
+
detector.recordOutput();
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// Monitor stderr
|
|
101
|
+
if (child.stderr) {
|
|
102
|
+
child.stderr.on('data', () => {
|
|
103
|
+
detector.recordOutput();
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
// Clean up on process exit
|
|
107
|
+
child.on('exit', () => {
|
|
108
|
+
detector.stop();
|
|
109
|
+
});
|
|
110
|
+
child.on('error', () => {
|
|
111
|
+
detector.stop();
|
|
112
|
+
});
|
|
113
|
+
return detector;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get default hang timeout in milliseconds
|
|
117
|
+
*/
|
|
118
|
+
function getDefaultHangTimeout() {
|
|
119
|
+
return DEFAULT_HANG_TIMEOUT_MS;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Format elapsed time for display
|
|
123
|
+
*/
|
|
124
|
+
function formatElapsed(ms) {
|
|
125
|
+
const seconds = Math.floor(ms / 1000);
|
|
126
|
+
const minutes = Math.floor(seconds / 60);
|
|
127
|
+
const hours = Math.floor(minutes / 60);
|
|
128
|
+
if (hours > 0) {
|
|
129
|
+
return `${hours}h ${minutes % 60}m`;
|
|
130
|
+
}
|
|
131
|
+
if (minutes > 0) {
|
|
132
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
133
|
+
}
|
|
134
|
+
return `${seconds}s`;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=hang-detector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hang-detector.js","sourceRoot":"","sources":["../../src/runners/hang-detector.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAwBH,gDAqDC;AAMD,gDA8DC;AAKD,sDAEC;AAKD,sCAYC;AArKD,MAAM,uBAAuB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AAgB7D;;;GAGG;AACH,SAAgB,kBAAkB,CAChC,UAA+B,EAAE;IAEjC,MAAM,EAAE,SAAS,GAAG,uBAAuB,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAE1E,IAAI,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;IAChC,IAAI,aAAa,GAA0B,IAAI,CAAC;IAChD,IAAI,eAAe,GAAG,KAAK,CAAC;IAE5B,MAAM,YAAY,GAAG,GAAS,EAAE;QAC9B,cAAc,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,eAAe,GAAG,KAAK,CAAC;QACxB,IAAI,QAAQ,EAAE,CAAC;YACb,QAAQ,EAAE,CAAC;QACb,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,qBAAqB,GAAG,GAAW,EAAE;QACzC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,CAAC;IAC/C,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,GAAY,EAAE;QAC3B,OAAO,qBAAqB,EAAE,GAAG,SAAS,CAAC;IAC7C,CAAC,CAAC;IAEF,MAAM,iBAAiB,GAAG,GAAS,EAAE;QACnC,OAAO,cAAc,CAAC;IACxB,CAAC,CAAC;IAEF,uBAAuB;IACvB,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,IAAI,MAAM,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;YACjC,eAAe,GAAG,IAAI,CAAC;YACvB,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,cAAc,EAAE,qBAAqB,EAAE,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,qBAAqB;IAEpC,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,aAAa,EAAE,CAAC;YAClB,aAAa,CAAC,aAAa,CAAC,CAAC;YAC7B,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO;QACL,YAAY;QACZ,MAAM;QACN,iBAAiB;QACjB,qBAAqB;QACrB,IAAI;KACL,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,SAAgB,kBAAkB,CAChC,KAAmB,EACnB,UAA0D,EAAE;IAE5D,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC;IAE1D,MAAM,QAAQ,GAAG,kBAAkB,CAAC;QAClC,GAAG,eAAe;QAClB,MAAM,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;YAC5C,OAAO,CAAC,KAAK,CACX,uCAAuC,OAAO,WAAW,CAC1D,CAAC;YAEF,IAAI,UAAU,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;gBAC5B,OAAO,CAAC,KAAK,CAAC,8BAA8B,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC;gBAC1D,IAAI,CAAC;oBACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;oBAEtB,6CAA6C;oBAC7C,UAAU,CAAC,GAAG,EAAE;wBACd,IAAI,CAAC;4BACH,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;wBACxB,CAAC;wBAAC,MAAM,CAAC;4BACP,uBAAuB;wBACzB,CAAC;oBACH,CAAC,EAAE,KAAK,CAAC,CAAC;gBACZ,CAAC;gBAAC,MAAM,CAAC;oBACP,uBAAuB;gBACzB,CAAC;YACH,CAAC;YAED,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;gBAC3B,eAAe,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,iBAAiB;IACjB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YAC3B,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,iBAAiB;IACjB,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjB,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YAC3B,QAAQ,CAAC,YAAY,EAAE,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;QACpB,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACrB,QAAQ,CAAC,IAAI,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAgB,qBAAqB;IACnC,OAAO,uBAAuB,CAAC;AACjC,CAAC;AAED;;GAEG;AACH,SAAgB,aAAa,CAAC,EAAU;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IAEvC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,OAAO,GAAG,KAAK,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;IACtC,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,OAAO,GAAG,OAAO,KAAK,OAAO,GAAG,EAAE,GAAG,CAAC;IACxC,CAAC;IACD,OAAO,GAAG,OAAO,GAAG,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heartbeat system for runner liveness detection
|
|
3
|
+
*/
|
|
4
|
+
import type Database from 'better-sqlite3';
|
|
5
|
+
export interface HeartbeatManager {
|
|
6
|
+
start: () => void;
|
|
7
|
+
stop: () => void;
|
|
8
|
+
beat: () => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Update heartbeat timestamp for a runner
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateHeartbeat(db: Database.Database, runnerId: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a runner's heartbeat is stale
|
|
16
|
+
*/
|
|
17
|
+
export declare function isHeartbeatStale(db: Database.Database, runnerId: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Find stale runners (no heartbeat for > 5 minutes)
|
|
20
|
+
*/
|
|
21
|
+
export declare function findStaleRunners(db: Database.Database): Array<{
|
|
22
|
+
id: string;
|
|
23
|
+
pid: number | null;
|
|
24
|
+
heartbeat_at: string;
|
|
25
|
+
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Create a heartbeat manager for a runner
|
|
28
|
+
* Automatically updates heartbeat at regular intervals
|
|
29
|
+
*/
|
|
30
|
+
export declare function createHeartbeatManager(db: Database.Database, runnerId: string): HeartbeatManager;
|
|
31
|
+
/**
|
|
32
|
+
* Get heartbeat interval in milliseconds
|
|
33
|
+
*/
|
|
34
|
+
export declare function getHeartbeatInterval(): number;
|
|
35
|
+
/**
|
|
36
|
+
* Get stale timeout in milliseconds
|
|
37
|
+
*/
|
|
38
|
+
export declare function getStaleTimeout(): number;
|
|
39
|
+
//# sourceMappingURL=heartbeat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/runners/heartbeat.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAK3C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAI7E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,GACf,OAAO,CAWT;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,QAAQ,CAAC,QAAQ,GACpB,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CAUjE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,GACf,gBAAgB,CAuBlB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAExC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Heartbeat system for runner liveness detection
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.updateHeartbeat = updateHeartbeat;
|
|
7
|
+
exports.isHeartbeatStale = isHeartbeatStale;
|
|
8
|
+
exports.findStaleRunners = findStaleRunners;
|
|
9
|
+
exports.createHeartbeatManager = createHeartbeatManager;
|
|
10
|
+
exports.getHeartbeatInterval = getHeartbeatInterval;
|
|
11
|
+
exports.getStaleTimeout = getStaleTimeout;
|
|
12
|
+
const HEARTBEAT_INTERVAL_MS = 30 * 1000; // 30 seconds
|
|
13
|
+
const STALE_TIMEOUT_MS = 5 * 60 * 1000; // 5 minutes
|
|
14
|
+
/**
|
|
15
|
+
* Update heartbeat timestamp for a runner
|
|
16
|
+
*/
|
|
17
|
+
function updateHeartbeat(db, runnerId) {
|
|
18
|
+
db.prepare(`UPDATE runners SET heartbeat_at = datetime('now') WHERE id = ?`).run(runnerId);
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Check if a runner's heartbeat is stale
|
|
22
|
+
*/
|
|
23
|
+
function isHeartbeatStale(db, runnerId) {
|
|
24
|
+
// Use SQLite's datetime comparison to avoid JavaScript/SQLite format issues
|
|
25
|
+
const result = db
|
|
26
|
+
.prepare(`SELECT 1 FROM runners
|
|
27
|
+
WHERE id = ? AND heartbeat_at >= datetime('now', '-5 minutes')`)
|
|
28
|
+
.get(runnerId);
|
|
29
|
+
// If no row returned, either runner doesn't exist or heartbeat is stale
|
|
30
|
+
return result === undefined;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Find stale runners (no heartbeat for > 5 minutes)
|
|
34
|
+
*/
|
|
35
|
+
function findStaleRunners(db) {
|
|
36
|
+
// Use SQLite's datetime function to avoid timestamp format mismatches
|
|
37
|
+
// JavaScript ISO format ("2026-02-08T22:28:49.000Z") differs from
|
|
38
|
+
// SQLite datetime format ("2026-02-08 22:33:49"), breaking string comparison
|
|
39
|
+
return db
|
|
40
|
+
.prepare(`SELECT id, pid, heartbeat_at FROM runners
|
|
41
|
+
WHERE heartbeat_at < datetime('now', '-5 minutes') AND status != 'idle'`)
|
|
42
|
+
.all();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Create a heartbeat manager for a runner
|
|
46
|
+
* Automatically updates heartbeat at regular intervals
|
|
47
|
+
*/
|
|
48
|
+
function createHeartbeatManager(db, runnerId) {
|
|
49
|
+
let intervalId = null;
|
|
50
|
+
const beat = () => {
|
|
51
|
+
updateHeartbeat(db, runnerId);
|
|
52
|
+
};
|
|
53
|
+
const start = () => {
|
|
54
|
+
// Update immediately
|
|
55
|
+
beat();
|
|
56
|
+
// Then update every 30 seconds
|
|
57
|
+
intervalId = setInterval(beat, HEARTBEAT_INTERVAL_MS);
|
|
58
|
+
};
|
|
59
|
+
const stop = () => {
|
|
60
|
+
if (intervalId) {
|
|
61
|
+
clearInterval(intervalId);
|
|
62
|
+
intervalId = null;
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
return { start, stop, beat };
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get heartbeat interval in milliseconds
|
|
69
|
+
*/
|
|
70
|
+
function getHeartbeatInterval() {
|
|
71
|
+
return HEARTBEAT_INTERVAL_MS;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Get stale timeout in milliseconds
|
|
75
|
+
*/
|
|
76
|
+
function getStaleTimeout() {
|
|
77
|
+
return STALE_TIMEOUT_MS;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=heartbeat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../src/runners/heartbeat.ts"],"names":[],"mappings":";AAAA;;GAEG;;AAgBH,0CAIC;AAKD,4CAcC;AAKD,4CAYC;AAMD,wDA0BC;AAKD,oDAEC;AAKD,0CAEC;AAlGD,MAAM,qBAAqB,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,aAAa;AACtD,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAQpD;;GAEG;AACH,SAAgB,eAAe,CAAC,EAAqB,EAAE,QAAgB;IACrE,EAAE,CAAC,OAAO,CACR,gEAAgE,CACjE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAC9B,EAAqB,EACrB,QAAgB;IAEhB,4EAA4E;IAC5E,MAAM,MAAM,GAAG,EAAE;SACd,OAAO,CACN;sEACgE,CACjE;SACA,GAAG,CAAC,QAAQ,CAA8B,CAAC;IAE9C,wEAAwE;IACxE,OAAO,MAAM,KAAK,SAAS,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAC9B,EAAqB;IAErB,sEAAsE;IACtE,kEAAkE;IAClE,6EAA6E;IAC7E,OAAO,EAAE;SACN,OAAO,CACN;+EACyE,CAC1E;SACA,GAAG,EAAqE,CAAC;AAC9E,CAAC;AAED;;;GAGG;AACH,SAAgB,sBAAsB,CACpC,EAAqB,EACrB,QAAgB;IAEhB,IAAI,UAAU,GAA0B,IAAI,CAAC;IAE7C,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,eAAe,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,GAAS,EAAE;QACvB,qBAAqB;QACrB,IAAI,EAAE,CAAC;QAEP,+BAA+B;QAC/B,UAAU,GAAG,WAAW,CAAC,IAAI,EAAE,qBAAqB,CAAC,CAAC;IACxD,CAAC,CAAC;IAEF,MAAM,IAAI,GAAG,GAAS,EAAE;QACtB,IAAI,UAAU,EAAE,CAAC;YACf,aAAa,CAAC,UAAU,CAAC,CAAC;YAC1B,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC;IACH,CAAC,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB;IAClC,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe;IAC7B,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Singleton lock for runner daemon
|
|
3
|
+
* Uses directory-based locking with PID file
|
|
4
|
+
*/
|
|
5
|
+
export interface LockResult {
|
|
6
|
+
acquired: boolean;
|
|
7
|
+
existingPid?: number;
|
|
8
|
+
isZombie?: boolean;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Get the lock directory path
|
|
12
|
+
*/
|
|
13
|
+
export declare function getLockDir(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Get the PID file path
|
|
16
|
+
*/
|
|
17
|
+
export declare function getPidFilePath(): string;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a process with given PID is running
|
|
20
|
+
*/
|
|
21
|
+
export declare function isProcessAlive(pid: number): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Read the PID from lock file
|
|
24
|
+
*/
|
|
25
|
+
export declare function readLockPid(): number | null;
|
|
26
|
+
/**
|
|
27
|
+
* Remove the lock directory
|
|
28
|
+
*/
|
|
29
|
+
export declare function removeLock(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Attempt to acquire the singleton lock
|
|
32
|
+
* Returns result indicating success or existing lock holder
|
|
33
|
+
*/
|
|
34
|
+
export declare function acquireLock(): LockResult;
|
|
35
|
+
/**
|
|
36
|
+
* Release the lock (should be called on shutdown)
|
|
37
|
+
*/
|
|
38
|
+
export declare function releaseLock(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Check lock status without acquiring
|
|
41
|
+
*/
|
|
42
|
+
export declare function checkLockStatus(): {
|
|
43
|
+
locked: boolean;
|
|
44
|
+
pid: number | null;
|
|
45
|
+
isZombie: boolean;
|
|
46
|
+
};
|
|
47
|
+
//# sourceMappingURL=lock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock.d.ts","sourceRoot":"","sources":["../../src/runners/lock.ts"],"names":[],"mappings":"AAAA;;;GAGG;AASH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQnD;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAa3C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAKjC;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,UAAU,CAiDxC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAOlC;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAkBA"}
|