@cliangdev/conductor 0.1.2
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/README.md +141 -0
- package/assets/claude/agents/researcher.md +147 -0
- package/assets/claude/commands/conductor/implement.md +393 -0
- package/assets/claude/commands/conductor/prd.md +291 -0
- package/assets/claude/skills/conductor-coder/SKILL.md +214 -0
- package/assets/claude/skills/ux-ui-design/SKILL.md +346 -0
- package/assets/claude/skills/ux-ui-design/references/design-tokens.md +359 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +106 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/dashboard.d.ts +9 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +159 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/doctor.d.ts +6 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +126 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/init.d.ts +19 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +276 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +161 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +14 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/mcp.d.ts +3 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +10 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/start.d.ts +7 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +74 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +9 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +126 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +4 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +30 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/daemon/poller.d.ts +18 -0
- package/dist/daemon/poller.d.ts.map +1 -0
- package/dist/daemon/poller.js +96 -0
- package/dist/daemon/poller.js.map +1 -0
- package/dist/daemon/run-lifecycle.d.ts +21 -0
- package/dist/daemon/run-lifecycle.d.ts.map +1 -0
- package/dist/daemon/run-lifecycle.js +53 -0
- package/dist/daemon/run-lifecycle.js.map +1 -0
- package/dist/daemon/run-queue.d.ts +12 -0
- package/dist/daemon/run-queue.d.ts.map +1 -0
- package/dist/daemon/run-queue.js +59 -0
- package/dist/daemon/run-queue.js.map +1 -0
- package/dist/daemon/runner.d.ts +31 -0
- package/dist/daemon/runner.d.ts.map +1 -0
- package/dist/daemon/runner.js +91 -0
- package/dist/daemon/runner.js.map +1 -0
- package/dist/daemon/state.d.ts +22 -0
- package/dist/daemon/state.d.ts.map +1 -0
- package/dist/daemon/state.js +29 -0
- package/dist/daemon/state.js.map +1 -0
- package/dist/daemon/watcher.d.ts +26 -0
- package/dist/daemon/watcher.d.ts.map +1 -0
- package/dist/daemon/watcher.js +330 -0
- package/dist/daemon/watcher.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +55 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/config.d.ts +16 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +48 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/next-steps.d.ts +2 -0
- package/dist/lib/next-steps.d.ts.map +1 -0
- package/dist/lib/next-steps.js +11 -0
- package/dist/lib/next-steps.js.map +1 -0
- package/dist/lib/oauth-server.d.ts +10 -0
- package/dist/lib/oauth-server.d.ts.map +1 -0
- package/dist/lib/oauth-server.js +67 -0
- package/dist/lib/oauth-server.js.map +1 -0
- package/dist/lib/plugin-assets.d.ts +19 -0
- package/dist/lib/plugin-assets.d.ts.map +1 -0
- package/dist/lib/plugin-assets.js +121 -0
- package/dist/lib/plugin-assets.js.map +1 -0
- package/dist/mcp/api.d.ts +7 -0
- package/dist/mcp/api.d.ts.map +1 -0
- package/dist/mcp/api.js +36 -0
- package/dist/mcp/api.js.map +1 -0
- package/dist/mcp/config.d.ts +11 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +31 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/files.d.ts +9 -0
- package/dist/mcp/files.d.ts.map +1 -0
- package/dist/mcp/files.js +43 -0
- package/dist/mcp/files.js.map +1 -0
- package/dist/mcp/index.d.ts +3 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +234 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/queue.d.ts +8 -0
- package/dist/mcp/queue.d.ts.map +1 -0
- package/dist/mcp/queue.js +19 -0
- package/dist/mcp/queue.js.map +1 -0
- package/dist/mcp/tools/comments.d.ts +6 -0
- package/dist/mcp/tools/comments.d.ts.map +1 -0
- package/dist/mcp/tools/comments.js +21 -0
- package/dist/mcp/tools/comments.js.map +1 -0
- package/dist/mcp/tools/documents.d.ts +11 -0
- package/dist/mcp/tools/documents.d.ts.map +1 -0
- package/dist/mcp/tools/documents.js +44 -0
- package/dist/mcp/tools/documents.js.map +1 -0
- package/dist/mcp/tools/issues.d.ts +23 -0
- package/dist/mcp/tools/issues.d.ts.map +1 -0
- package/dist/mcp/tools/issues.js +141 -0
- package/dist/mcp/tools/issues.js.map +1 -0
- package/package.json +40 -0
- package/scripts/postinstall.js +81 -0
- package/scripts/preuninstall.js +175 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
export function formatRelativeTime(dateStr) {
|
|
5
|
+
const diffMs = Date.now() - new Date(dateStr).getTime();
|
|
6
|
+
const diffSec = Math.floor(diffMs / 1000);
|
|
7
|
+
if (diffSec < 60)
|
|
8
|
+
return `${diffSec}s ago`;
|
|
9
|
+
if (diffSec < 3600)
|
|
10
|
+
return `${Math.floor(diffSec / 60)}m ago`;
|
|
11
|
+
return `${Math.floor(diffSec / 3600)}h ago`;
|
|
12
|
+
}
|
|
13
|
+
const CONDUCTOR_DIR = path.join(os.homedir(), '.conductor');
|
|
14
|
+
const DAEMON_PID_PATH = path.join(CONDUCTOR_DIR, 'daemon.pid');
|
|
15
|
+
const SYNC_QUEUE_PATH = path.join(CONDUCTOR_DIR, 'sync-queue.json');
|
|
16
|
+
export const DAEMON_LOG_PATH = path.join(CONDUCTOR_DIR, 'daemon.log');
|
|
17
|
+
export function isDaemonRunning() {
|
|
18
|
+
try {
|
|
19
|
+
const raw = fs.readFileSync(DAEMON_PID_PATH, 'utf8').trim();
|
|
20
|
+
const pid = parseInt(raw, 10);
|
|
21
|
+
if (isNaN(pid)) {
|
|
22
|
+
fs.unlinkSync(DAEMON_PID_PATH);
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
process.kill(pid, 0);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
// Process not found — clean up stale PID file
|
|
30
|
+
if (err.code === 'ESRCH') {
|
|
31
|
+
try {
|
|
32
|
+
fs.unlinkSync(DAEMON_PID_PATH);
|
|
33
|
+
}
|
|
34
|
+
catch { /* already gone */ }
|
|
35
|
+
}
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export function getDaemonPid() {
|
|
40
|
+
try {
|
|
41
|
+
const raw = fs.readFileSync(DAEMON_PID_PATH, 'utf8').trim();
|
|
42
|
+
const pid = parseInt(raw, 10);
|
|
43
|
+
if (isNaN(pid))
|
|
44
|
+
return null;
|
|
45
|
+
process.kill(pid, 0);
|
|
46
|
+
return pid;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
export function getQueueCount() {
|
|
53
|
+
try {
|
|
54
|
+
const raw = fs.readFileSync(SYNC_QUEUE_PATH, 'utf8');
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
if (Array.isArray(parsed))
|
|
57
|
+
return parsed.length;
|
|
58
|
+
return 0;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return 0;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export function getLogFileSizeMb() {
|
|
65
|
+
try {
|
|
66
|
+
const stat = fs.statSync(DAEMON_LOG_PATH);
|
|
67
|
+
return Math.round((stat.size / (1024 * 1024)) * 10) / 10;
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export function registerStatus(program) {
|
|
74
|
+
program
|
|
75
|
+
.command('status')
|
|
76
|
+
.description('Show daemon and sync queue status')
|
|
77
|
+
.option('--json', 'Output status as JSON')
|
|
78
|
+
.addHelpText('after', `
|
|
79
|
+
Examples:
|
|
80
|
+
conductor status
|
|
81
|
+
conductor status --json`)
|
|
82
|
+
.action((options) => {
|
|
83
|
+
const running = isDaemonRunning();
|
|
84
|
+
const pid = getDaemonPid();
|
|
85
|
+
const queueSize = getQueueCount();
|
|
86
|
+
const logSizeMb = getLogFileSizeMb();
|
|
87
|
+
if (options.json) {
|
|
88
|
+
let uptime = null;
|
|
89
|
+
if (running && pid !== null) {
|
|
90
|
+
// Uptime is best-effort; daemon.log is not the source — use state file if needed
|
|
91
|
+
uptime = null;
|
|
92
|
+
}
|
|
93
|
+
const output = {
|
|
94
|
+
daemon: {
|
|
95
|
+
running,
|
|
96
|
+
pid: running ? pid : null,
|
|
97
|
+
uptime,
|
|
98
|
+
},
|
|
99
|
+
syncQueue: {
|
|
100
|
+
size: queueSize,
|
|
101
|
+
},
|
|
102
|
+
log: {
|
|
103
|
+
path: DAEMON_LOG_PATH,
|
|
104
|
+
sizeMb: logSizeMb,
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
process.stdout.write(JSON.stringify(output, null, 2) + '\n');
|
|
108
|
+
process.exit(0);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
if (running) {
|
|
112
|
+
console.log(`Daemon: running (PID ${pid})`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.log('Daemon: not running');
|
|
116
|
+
}
|
|
117
|
+
console.log(`Sync queue: ${queueSize} item(s)`);
|
|
118
|
+
if (logSizeMb !== null) {
|
|
119
|
+
console.log(`Log: ${DAEMON_LOG_PATH} (${logSizeMb.toFixed(1)} MB)`);
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
console.log(`Log: ${DAEMON_LOG_PATH} (not found)`);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC,eAAO,MAAM,QAAQ,QAAyC,CAAA;AAE9D,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwBnD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as os from 'os';
|
|
4
|
+
const CONDUCTOR_DIR = path.join(os.homedir(), '.conductor');
|
|
5
|
+
export const PID_FILE = path.join(CONDUCTOR_DIR, 'daemon.pid');
|
|
6
|
+
export function registerStop(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('stop')
|
|
9
|
+
.description('Stop the file watcher daemon')
|
|
10
|
+
.addHelpText('after', `
|
|
11
|
+
Examples:
|
|
12
|
+
conductor stop`)
|
|
13
|
+
.action(() => {
|
|
14
|
+
if (!fs.existsSync(PID_FILE)) {
|
|
15
|
+
console.log('Daemon is not running');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const pid = parseInt(fs.readFileSync(PID_FILE, 'utf8').trim(), 10);
|
|
19
|
+
try {
|
|
20
|
+
process.kill(pid, 'SIGTERM');
|
|
21
|
+
fs.unlinkSync(PID_FILE);
|
|
22
|
+
console.log(`Daemon stopped (PID ${pid})`);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
fs.unlinkSync(PID_FILE);
|
|
26
|
+
console.log('Daemon was not running (removed stale PID file)');
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AACxB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAA;AAGxB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAA;AAC3D,MAAM,CAAC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,YAAY,CAAC,CAAA;AAE9D,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,8BAA8B,CAAC;SAC3C,WAAW,CAAC,OAAO,EAAE;;iBAET,CAAC;SACb,MAAM,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;YACpC,OAAM;QACR,CAAC;QAED,MAAM,GAAG,GAAG,QAAQ,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;QAElE,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;YAC5B,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YACvB,OAAO,CAAC,GAAG,CAAC,uBAAuB,GAAG,GAAG,CAAC,CAAA;QAC5C,CAAC;QAAC,MAAM,CAAC;YACP,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAA;YACvB,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAA;QAChE,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Config } from '../lib/config.js';
|
|
2
|
+
export type PollMode = 'idle' | 'active';
|
|
3
|
+
export interface PollConfig {
|
|
4
|
+
idleIntervalMs: number;
|
|
5
|
+
activeIntervalMs: number;
|
|
6
|
+
activeWindowMs: number;
|
|
7
|
+
maxConsecutiveErrors: number;
|
|
8
|
+
}
|
|
9
|
+
export type EventHandler = (events: DaemonEvent[]) => Promise<void>;
|
|
10
|
+
export interface DaemonEvent {
|
|
11
|
+
eventId: string;
|
|
12
|
+
type: string;
|
|
13
|
+
payload: Record<string, unknown>;
|
|
14
|
+
}
|
|
15
|
+
export declare function startPoller(getConfig: () => Config, onEvent: EventHandler, options?: Partial<PollConfig>): {
|
|
16
|
+
stop: () => void;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=poller.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poller.d.ts","sourceRoot":"","sources":["../../src/daemon/poller.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAGzC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,MAAM,WAAW,UAAU;IACzB,cAAc,EAAE,MAAM,CAAA;IACtB,gBAAgB,EAAE,MAAM,CAAA;IACxB,cAAc,EAAE,MAAM,CAAA;IACtB,oBAAoB,EAAE,MAAM,CAAA;CAC7B;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;AAEnE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACjC;AASD,wBAAgB,WAAW,CACzB,SAAS,EAAE,MAAM,MAAM,EACvB,OAAO,EAAE,YAAY,EACrB,OAAO,CAAC,EAAE,OAAO,CAAC,UAAU,CAAC,GAC5B;IAAE,IAAI,EAAE,MAAM,IAAI,CAAA;CAAE,CA+FtB"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { writeDaemonState, readDaemonState } from './state.js';
|
|
2
|
+
const DEFAULT_CONFIG = {
|
|
3
|
+
idleIntervalMs: 60000,
|
|
4
|
+
activeIntervalMs: 5000,
|
|
5
|
+
activeWindowMs: 300000,
|
|
6
|
+
maxConsecutiveErrors: 3,
|
|
7
|
+
};
|
|
8
|
+
export function startPoller(getConfig, onEvent, options) {
|
|
9
|
+
const pollConfig = { ...DEFAULT_CONFIG, ...options };
|
|
10
|
+
let stopped = false;
|
|
11
|
+
let timer = null;
|
|
12
|
+
let mode = 'idle';
|
|
13
|
+
let lastEventAt = null;
|
|
14
|
+
let consecutiveErrors = 0;
|
|
15
|
+
let eventsThisSession = 0;
|
|
16
|
+
async function poll() {
|
|
17
|
+
if (stopped)
|
|
18
|
+
return;
|
|
19
|
+
const config = getConfig();
|
|
20
|
+
const url = `${config.apiUrl}/api/v1/projects/${config.projectId}/daemon/events`;
|
|
21
|
+
try {
|
|
22
|
+
const response = await fetch(url, {
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
if (!response.ok) {
|
|
29
|
+
throw new Error(`Poll failed with status ${response.status}`);
|
|
30
|
+
}
|
|
31
|
+
const data = (await response.json());
|
|
32
|
+
const events = data.events ?? [];
|
|
33
|
+
consecutiveErrors = 0;
|
|
34
|
+
if (events.length > 0) {
|
|
35
|
+
mode = 'active';
|
|
36
|
+
lastEventAt = Date.now();
|
|
37
|
+
eventsThisSession += events.length;
|
|
38
|
+
await onEvent(events);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
// No events — determine mode based on activeWindowMs
|
|
42
|
+
if (lastEventAt !== null && Date.now() - lastEventAt < pollConfig.activeWindowMs) {
|
|
43
|
+
mode = 'active';
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
mode = 'idle';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
consecutiveErrors++;
|
|
52
|
+
mode = 'idle';
|
|
53
|
+
if (consecutiveErrors >= pollConfig.maxConsecutiveErrors) {
|
|
54
|
+
console.warn('Poll endpoint returning errors, continuing at idle interval');
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
console.error(`Poll error: ${err.message}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
// Update daemon-state.json after every poll
|
|
61
|
+
const existingState = readDaemonState();
|
|
62
|
+
writeDaemonState({
|
|
63
|
+
pid: existingState?.pid ?? process.pid,
|
|
64
|
+
startedAt: existingState?.startedAt ?? new Date().toISOString(),
|
|
65
|
+
pollMode: mode,
|
|
66
|
+
lastPollAt: new Date().toISOString(),
|
|
67
|
+
consecutiveErrors,
|
|
68
|
+
eventsThisSession,
|
|
69
|
+
activeRuns: existingState?.activeRuns ?? [],
|
|
70
|
+
syncQueueSize: existingState?.syncQueueSize ?? 0,
|
|
71
|
+
});
|
|
72
|
+
if (!stopped) {
|
|
73
|
+
scheduleNext();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function scheduleNext() {
|
|
77
|
+
if (stopped)
|
|
78
|
+
return;
|
|
79
|
+
const intervalMs = mode === 'active' ? pollConfig.activeIntervalMs : pollConfig.idleIntervalMs;
|
|
80
|
+
timer = setTimeout(() => {
|
|
81
|
+
poll().catch(console.error);
|
|
82
|
+
}, intervalMs);
|
|
83
|
+
}
|
|
84
|
+
// Start the polling loop
|
|
85
|
+
scheduleNext();
|
|
86
|
+
return {
|
|
87
|
+
stop() {
|
|
88
|
+
stopped = true;
|
|
89
|
+
if (timer !== null) {
|
|
90
|
+
clearTimeout(timer);
|
|
91
|
+
timer = null;
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=poller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poller.js","sourceRoot":"","sources":["../../src/daemon/poller.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Config } from '../lib/config.js';
|
|
2
|
+
import type { WorkflowTriggerEvent } from './runner.js';
|
|
3
|
+
/**
|
|
4
|
+
* PATCH /api/v1/workflow-runs/{runId}
|
|
5
|
+
* Updates the status of a WorkflowRun. Errors are swallowed and logged.
|
|
6
|
+
*/
|
|
7
|
+
export declare function updateRunStatus(runId: string, status: 'SUCCESS' | 'FAILED', config: Config): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* POST /api/v1/projects/{projectId}/daemon/events/ack
|
|
10
|
+
* Marks a daemon event as processed. Errors are swallowed and logged.
|
|
11
|
+
*/
|
|
12
|
+
export declare function acknowledgeEvent(projectId: string, eventId: string, config: Config): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Finalises a workflow run after Docker container exit:
|
|
15
|
+
* 1. PATCH the WorkflowRun status to SUCCESS or FAILED
|
|
16
|
+
* 2. POST to the ack endpoint to mark the event as processed
|
|
17
|
+
*
|
|
18
|
+
* Used by the run queue orchestrator.
|
|
19
|
+
*/
|
|
20
|
+
export declare function completeRun(event: WorkflowTriggerEvent, status: 'SUCCESS' | 'FAILED', config: Config): Promise<void>;
|
|
21
|
+
//# sourceMappingURL=run-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-lifecycle.d.ts","sourceRoot":"","sources":["../../src/daemon/run-lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAIvD;;;GAGG;AACH,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,SAAS,GAAG,QAAQ,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAaf;AAID;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAaf;AAID;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,oBAAoB,EAC3B,MAAM,EAAE,SAAS,GAAG,QAAQ,EAC5B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAGf"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// ─── updateRunStatus ──────────────────────────────────────────────────────────
|
|
2
|
+
/**
|
|
3
|
+
* PATCH /api/v1/workflow-runs/{runId}
|
|
4
|
+
* Updates the status of a WorkflowRun. Errors are swallowed and logged.
|
|
5
|
+
*/
|
|
6
|
+
export async function updateRunStatus(runId, status, config) {
|
|
7
|
+
try {
|
|
8
|
+
await fetch(`${config.apiUrl}/api/v1/workflow-runs/${runId}`, {
|
|
9
|
+
method: 'PATCH',
|
|
10
|
+
headers: {
|
|
11
|
+
'Content-Type': 'application/json',
|
|
12
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
13
|
+
},
|
|
14
|
+
body: JSON.stringify({ status }),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
console.error('[run-lifecycle] Failed to update run status:', err);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
// ─── acknowledgeEvent ─────────────────────────────────────────────────────────
|
|
22
|
+
/**
|
|
23
|
+
* POST /api/v1/projects/{projectId}/daemon/events/ack
|
|
24
|
+
* Marks a daemon event as processed. Errors are swallowed and logged.
|
|
25
|
+
*/
|
|
26
|
+
export async function acknowledgeEvent(projectId, eventId, config) {
|
|
27
|
+
try {
|
|
28
|
+
await fetch(`${config.apiUrl}/api/v1/projects/${projectId}/daemon/events/ack`, {
|
|
29
|
+
method: 'POST',
|
|
30
|
+
headers: {
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
33
|
+
},
|
|
34
|
+
body: JSON.stringify({ eventIds: [eventId] }),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
console.error('[run-lifecycle] Failed to acknowledge event:', err);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// ─── completeRun ──────────────────────────────────────────────────────────────
|
|
42
|
+
/**
|
|
43
|
+
* Finalises a workflow run after Docker container exit:
|
|
44
|
+
* 1. PATCH the WorkflowRun status to SUCCESS or FAILED
|
|
45
|
+
* 2. POST to the ack endpoint to mark the event as processed
|
|
46
|
+
*
|
|
47
|
+
* Used by the run queue orchestrator.
|
|
48
|
+
*/
|
|
49
|
+
export async function completeRun(event, status, config) {
|
|
50
|
+
await updateRunStatus(event.workflowRunId, status, config);
|
|
51
|
+
await acknowledgeEvent(event.projectId, event.eventId, config);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=run-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-lifecycle.js","sourceRoot":"","sources":["../../src/daemon/run-lifecycle.ts"],"names":[],"mappings":"AAGA,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,KAAa,EACb,MAA4B,EAC5B,MAAc;IAEd,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,yBAAyB,KAAK,EAAE,EAAE;YAC5D,MAAM,EAAE,OAAO;YACf,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;aACzC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;SACjC,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAA;IACpE,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,SAAiB,EACjB,OAAe,EACf,MAAc;IAEd,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,GAAG,MAAM,CAAC,MAAM,oBAAoB,SAAS,oBAAoB,EAAE;YAC7E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,MAAM,CAAC,MAAM,EAAE;aACzC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC;SAC9C,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,8CAA8C,EAAE,GAAG,CAAC,CAAA;IACpE,CAAC;AACH,CAAC;AAED,iFAAiF;AAEjF;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAA2B,EAC3B,MAA4B,EAC5B,MAAc;IAEd,MAAM,eAAe,CAAC,KAAK,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1D,MAAM,gBAAgB,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAChE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Config } from '../lib/config.js';
|
|
2
|
+
import { type WorkflowTriggerEvent } from './runner.js';
|
|
3
|
+
export declare class RunQueue {
|
|
4
|
+
private maxConcurrent;
|
|
5
|
+
private activeCount;
|
|
6
|
+
private queue;
|
|
7
|
+
constructor(maxConcurrent?: number);
|
|
8
|
+
enqueue(event: WorkflowTriggerEvent, getConfig: () => Config): void;
|
|
9
|
+
private processNext;
|
|
10
|
+
private runItem;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=run-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-queue.d.ts","sourceRoot":"","sources":["../../src/daemon/run-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAU,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAI/D,qBAAa,QAAQ;IACnB,OAAO,CAAC,aAAa,CAAQ;IAC7B,OAAO,CAAC,WAAW,CAAY;IAC/B,OAAO,CAAC,KAAK,CAAsE;gBAEvE,aAAa,GAAE,MAAU;IAIrC,OAAO,CAAC,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,MAAM,GAAG,IAAI;IAKnE,OAAO,CAAC,WAAW;YAUL,OAAO;CAqCtB"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { runJob } from './runner.js';
|
|
2
|
+
import { completeRun } from './run-lifecycle.js';
|
|
3
|
+
import { readDaemonState, writeDaemonState } from './state.js';
|
|
4
|
+
export class RunQueue {
|
|
5
|
+
constructor(maxConcurrent = 1) {
|
|
6
|
+
this.activeCount = 0;
|
|
7
|
+
this.queue = [];
|
|
8
|
+
this.maxConcurrent = maxConcurrent;
|
|
9
|
+
}
|
|
10
|
+
enqueue(event, getConfig) {
|
|
11
|
+
this.queue.push({ event, getConfig });
|
|
12
|
+
this.processNext();
|
|
13
|
+
}
|
|
14
|
+
processNext() {
|
|
15
|
+
if (this.activeCount >= this.maxConcurrent || this.queue.length === 0)
|
|
16
|
+
return;
|
|
17
|
+
const item = this.queue.shift();
|
|
18
|
+
this.activeCount++;
|
|
19
|
+
this.runItem(item).finally(() => {
|
|
20
|
+
this.activeCount--;
|
|
21
|
+
this.processNext();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
async runItem(item) {
|
|
25
|
+
const { event, getConfig } = item;
|
|
26
|
+
const config = getConfig();
|
|
27
|
+
const selfHostedJobs = event.jobs.filter((j) => j.runsOn === 'self-hosted');
|
|
28
|
+
for (const job of selfHostedJobs) {
|
|
29
|
+
// Add to activeRuns in daemon-state.json
|
|
30
|
+
const stateBefore = readDaemonState();
|
|
31
|
+
if (stateBefore) {
|
|
32
|
+
writeDaemonState({
|
|
33
|
+
...stateBefore,
|
|
34
|
+
activeRuns: [
|
|
35
|
+
...stateBefore.activeRuns,
|
|
36
|
+
{
|
|
37
|
+
runId: event.workflowRunId,
|
|
38
|
+
issueTitle: event.issueTitle,
|
|
39
|
+
jobName: job.id,
|
|
40
|
+
status: 'running',
|
|
41
|
+
startedAt: new Date().toISOString(),
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
const status = await runJob(event, job, config);
|
|
47
|
+
await completeRun(event, status, config);
|
|
48
|
+
// Remove from activeRuns in daemon-state.json
|
|
49
|
+
const stateAfter = readDaemonState();
|
|
50
|
+
if (stateAfter) {
|
|
51
|
+
writeDaemonState({
|
|
52
|
+
...stateAfter,
|
|
53
|
+
activeRuns: stateAfter.activeRuns.filter((r) => r.runId !== event.workflowRunId),
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=run-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-queue.js","sourceRoot":"","sources":["../../src/daemon/run-queue.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAA6B,MAAM,aAAa,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAChD,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAE9D,MAAM,OAAO,QAAQ;IAKnB,YAAY,gBAAwB,CAAC;QAH7B,gBAAW,GAAW,CAAC,CAAA;QACvB,UAAK,GAAoE,EAAE,CAAA;QAGjF,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;IACpC,CAAC;IAED,OAAO,CAAC,KAA2B,EAAE,SAAuB;QAC1D,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAA;QACrC,IAAI,CAAC,WAAW,EAAE,CAAA;IACpB,CAAC;IAEO,WAAW;QACjB,IAAI,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC7E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAA;QAChC,IAAI,CAAC,WAAW,EAAE,CAAA;QAClB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE;YAC9B,IAAI,CAAC,WAAW,EAAE,CAAA;YAClB,IAAI,CAAC,WAAW,EAAE,CAAA;QACpB,CAAC,CAAC,CAAA;IACJ,CAAC;IAEO,KAAK,CAAC,OAAO,CAAC,IAA8D;QAClF,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;QACjC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;QAC1B,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAA;QAE3E,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,yCAAyC;YACzC,MAAM,WAAW,GAAG,eAAe,EAAE,CAAA;YACrC,IAAI,WAAW,EAAE,CAAC;gBAChB,gBAAgB,CAAC;oBACf,GAAG,WAAW;oBACd,UAAU,EAAE;wBACV,GAAG,WAAW,CAAC,UAAU;wBACzB;4BACE,KAAK,EAAE,KAAK,CAAC,aAAa;4BAC1B,UAAU,EAAE,KAAK,CAAC,UAAU;4BAC5B,OAAO,EAAE,GAAG,CAAC,EAAE;4BACf,MAAM,EAAE,SAAS;4BACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;yBACpC;qBACF;iBACF,CAAC,CAAA;YACJ,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,CAAA;YAC/C,MAAM,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;YAExC,8CAA8C;YAC9C,MAAM,UAAU,GAAG,eAAe,EAAE,CAAA;YACpC,IAAI,UAAU,EAAE,CAAC;gBACf,gBAAgB,CAAC;oBACf,GAAG,UAAU;oBACb,UAAU,EAAE,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,KAAK,CAAC,aAAa,CAAC;iBACjF,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Config } from '../lib/config.js';
|
|
2
|
+
export interface JobConfig {
|
|
3
|
+
id: string;
|
|
4
|
+
runsOn: string;
|
|
5
|
+
container?: {
|
|
6
|
+
image: string;
|
|
7
|
+
};
|
|
8
|
+
steps?: Array<{
|
|
9
|
+
name: string;
|
|
10
|
+
run?: string;
|
|
11
|
+
}>;
|
|
12
|
+
env?: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export interface WorkflowTriggerEvent {
|
|
15
|
+
eventId: string;
|
|
16
|
+
type: string;
|
|
17
|
+
workflowRunId: string;
|
|
18
|
+
workflowId: string;
|
|
19
|
+
workflowName: string;
|
|
20
|
+
issueId: string;
|
|
21
|
+
issueTitle: string;
|
|
22
|
+
projectId: string;
|
|
23
|
+
trigger: {
|
|
24
|
+
type: string;
|
|
25
|
+
fromStatus?: string;
|
|
26
|
+
toStatus?: string;
|
|
27
|
+
};
|
|
28
|
+
jobs: JobConfig[];
|
|
29
|
+
}
|
|
30
|
+
export declare function runJob(event: WorkflowTriggerEvent, job: JobConfig, config: Config): Promise<'SUCCESS' | 'FAILED'>;
|
|
31
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/daemon/runner.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAI9C,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAA;KAClB,CAAA;IACD,IAAI,EAAE,SAAS,EAAE,CAAA;CAClB;AA4DD,wBAAsB,MAAM,CAC1B,KAAK,EAAE,oBAAoB,EAC3B,GAAG,EAAE,SAAS,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC,CAqD/B"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
// ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
3
|
+
async function streamLogChunk(runId, chunk, config) {
|
|
4
|
+
try {
|
|
5
|
+
await fetch(`${config.apiUrl}/internal/workflow-runs/${runId}/log-chunk`, {
|
|
6
|
+
method: 'POST',
|
|
7
|
+
headers: {
|
|
8
|
+
'Content-Type': 'application/json',
|
|
9
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
10
|
+
},
|
|
11
|
+
body: JSON.stringify({ chunk }),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
catch (err) {
|
|
15
|
+
console.error('[runner] Failed to stream log chunk:', err);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Spawns a command and returns its exit code. Streams stdout/stderr lines to
|
|
20
|
+
* the log-chunk endpoint if a runId and config are provided.
|
|
21
|
+
*/
|
|
22
|
+
function spawnAndWait(cmd, args, opts) {
|
|
23
|
+
return new Promise((resolve) => {
|
|
24
|
+
const proc = spawn(cmd, args);
|
|
25
|
+
proc.stdout?.on('data', (data) => {
|
|
26
|
+
const line = data.toString();
|
|
27
|
+
if (opts?.runId && opts?.config) {
|
|
28
|
+
void streamLogChunk(opts.runId, line, opts.config);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
proc.stderr?.on('data', (data) => {
|
|
32
|
+
const line = data.toString();
|
|
33
|
+
if (opts?.runId && opts?.config) {
|
|
34
|
+
void streamLogChunk(opts.runId, line, opts.config);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
proc.on('error', () => {
|
|
38
|
+
resolve(1);
|
|
39
|
+
});
|
|
40
|
+
proc.on('close', (code) => {
|
|
41
|
+
resolve(code ?? 1);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
// ─── Main ────────────────────────────────────────────────────────────────────
|
|
46
|
+
export async function runJob(event, job, config) {
|
|
47
|
+
const { workflowRunId } = event;
|
|
48
|
+
// Step 1: Check Docker is available
|
|
49
|
+
const dockerInfoCode = await spawnAndWait('docker', ['info']);
|
|
50
|
+
if (dockerInfoCode !== 0) {
|
|
51
|
+
await streamLogChunk(workflowRunId, 'Docker not available on this host', config);
|
|
52
|
+
return 'FAILED';
|
|
53
|
+
}
|
|
54
|
+
// Step 2: Validate container image
|
|
55
|
+
if (!job.container?.image) {
|
|
56
|
+
await streamLogChunk(workflowRunId, 'No container image specified for this job', config);
|
|
57
|
+
return 'FAILED';
|
|
58
|
+
}
|
|
59
|
+
const image = job.container.image;
|
|
60
|
+
// Step 3: Pull image
|
|
61
|
+
const pullCode = await spawnAndWait('docker', ['pull', image]);
|
|
62
|
+
if (pullCode !== 0) {
|
|
63
|
+
await streamLogChunk(workflowRunId, `Failed to pull image: ${image}`, config);
|
|
64
|
+
return 'FAILED';
|
|
65
|
+
}
|
|
66
|
+
// Step 4: Build env args
|
|
67
|
+
const conductorEnv = {
|
|
68
|
+
CONDUCTOR_ISSUE_ID: event.issueId,
|
|
69
|
+
CONDUCTOR_PROJECT_ID: event.projectId,
|
|
70
|
+
CONDUCTOR_WORKFLOW_RUN_ID: event.workflowRunId,
|
|
71
|
+
CONDUCTOR_API_KEY: config.apiKey,
|
|
72
|
+
CONDUCTOR_API_URL: config.apiUrl,
|
|
73
|
+
};
|
|
74
|
+
const allEnv = {
|
|
75
|
+
...conductorEnv,
|
|
76
|
+
...(job.env ?? {}),
|
|
77
|
+
};
|
|
78
|
+
const envArgs = [];
|
|
79
|
+
for (const [key, value] of Object.entries(allEnv)) {
|
|
80
|
+
envArgs.push('-e', `${key}=${value}`);
|
|
81
|
+
}
|
|
82
|
+
// Step 5: Run container
|
|
83
|
+
const runArgs = ['run', '--rm', ...envArgs, image];
|
|
84
|
+
const runCode = await spawnAndWait('docker', runArgs, {
|
|
85
|
+
runId: workflowRunId,
|
|
86
|
+
config,
|
|
87
|
+
});
|
|
88
|
+
// Step 6: Return result
|
|
89
|
+
return runCode === 0 ? 'SUCCESS' : 'FAILED';
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../src/daemon/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const STATE_FILE_PATH: string;
|
|
2
|
+
export interface ActiveRun {
|
|
3
|
+
runId: string;
|
|
4
|
+
issueTitle: string;
|
|
5
|
+
jobName: string;
|
|
6
|
+
status: 'running' | 'completed' | 'failed';
|
|
7
|
+
startedAt: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DaemonState {
|
|
10
|
+
pid: number;
|
|
11
|
+
startedAt: string;
|
|
12
|
+
pollMode: 'idle' | 'active';
|
|
13
|
+
lastPollAt: string | null;
|
|
14
|
+
consecutiveErrors: number;
|
|
15
|
+
eventsThisSession: number;
|
|
16
|
+
activeRuns: ActiveRun[];
|
|
17
|
+
syncQueueSize: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function writeDaemonState(state: DaemonState): void;
|
|
20
|
+
export declare function readDaemonState(): DaemonState | null;
|
|
21
|
+
export declare function deleteDaemonState(): void;
|
|
22
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/daemon/state.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,eAAe,QAAgD,CAAA;AAE5E,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;IAC1C,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAAA;IAC3B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,iBAAiB,EAAE,MAAM,CAAA;IACzB,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;CACtB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAGzD;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAOpD;AAED,wBAAgB,iBAAiB,IAAI,IAAI,CAQxC"}
|