fission-worker 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent.d.ts +2 -0
- package/dist/agent.js +92 -0
- package/dist/agent.js.map +1 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.js +29 -0
- package/dist/config.js.map +1 -0
- package/dist/docker.d.ts +16 -0
- package/dist/docker.js +86 -0
- package/dist/docker.js.map +1 -0
- package/dist/health.d.ts +7 -0
- package/dist/health.js +46 -0
- package/dist/health.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/setup.d.ts +1 -0
- package/dist/setup.js +141 -0
- package/dist/setup.js.map +1 -0
- package/package.json +27 -0
package/dist/agent.d.ts
ADDED
package/dist/agent.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.agentLoop = agentLoop;
|
|
4
|
+
const docker_1 = require("./docker");
|
|
5
|
+
const POLL_INTERVAL_MS = 5_000;
|
|
6
|
+
const HEARTBEAT_INTERVAL_MS = 30_000;
|
|
7
|
+
function sleep(ms) {
|
|
8
|
+
return new Promise((r) => setTimeout(r, ms));
|
|
9
|
+
}
|
|
10
|
+
async function agentLoop(config) {
|
|
11
|
+
const activeSessions = new Map();
|
|
12
|
+
let running = true;
|
|
13
|
+
// Graceful shutdown
|
|
14
|
+
const shutdown = () => {
|
|
15
|
+
console.log("\n[agent] Shutting down — waiting for active sessions to finish...");
|
|
16
|
+
running = false;
|
|
17
|
+
// Don't kill containers — let them finish
|
|
18
|
+
};
|
|
19
|
+
process.on("SIGTERM", shutdown);
|
|
20
|
+
process.on("SIGINT", shutdown);
|
|
21
|
+
// Heartbeat timer
|
|
22
|
+
const heartbeatTimer = setInterval(async () => {
|
|
23
|
+
try {
|
|
24
|
+
await fetch(`${config.fissionUrl}/api/worker/heartbeat`, {
|
|
25
|
+
method: "POST",
|
|
26
|
+
headers: {
|
|
27
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
},
|
|
30
|
+
body: JSON.stringify({ activeSessions: activeSessions.size }),
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Heartbeat failure is non-fatal
|
|
35
|
+
}
|
|
36
|
+
}, HEARTBEAT_INTERVAL_MS);
|
|
37
|
+
// Send initial heartbeat
|
|
38
|
+
try {
|
|
39
|
+
await fetch(`${config.fissionUrl}/api/worker/heartbeat`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: {
|
|
42
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify({ activeSessions: 0 }),
|
|
46
|
+
});
|
|
47
|
+
console.log(`[agent] Connected to ${config.fissionUrl}`);
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
console.error(`[agent] Failed to connect to Fission API: ${err}`);
|
|
51
|
+
}
|
|
52
|
+
console.log(`[agent] Polling for jobs (max concurrent: ${config.maxConcurrent})...`);
|
|
53
|
+
// Poll loop
|
|
54
|
+
while (running) {
|
|
55
|
+
if (activeSessions.size >= config.maxConcurrent) {
|
|
56
|
+
await sleep(POLL_INTERVAL_MS);
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const res = await fetch(`${config.fissionUrl}/api/worker/poll`, {
|
|
61
|
+
headers: { Authorization: `Bearer ${config.apiKey}` },
|
|
62
|
+
});
|
|
63
|
+
if (res.status === 204 || res.status === 200) {
|
|
64
|
+
const body = await res.json();
|
|
65
|
+
if (!body || body.status === 204 || body.data === null || !body.sessionId) {
|
|
66
|
+
await sleep(POLL_INTERVAL_MS);
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const job = body;
|
|
70
|
+
console.log(`[agent] Received job: session=${job.sessionId.slice(0, 8)} project=${job.project.name}`);
|
|
71
|
+
(0, docker_1.startSession)(job, config, activeSessions);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
await sleep(POLL_INTERVAL_MS);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
console.error(`[agent] Poll error: ${err}`);
|
|
79
|
+
await sleep(POLL_INTERVAL_MS);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Wait for active sessions to finish
|
|
83
|
+
clearInterval(heartbeatTimer);
|
|
84
|
+
if (activeSessions.size > 0) {
|
|
85
|
+
console.log(`[agent] Waiting for ${activeSessions.size} active session(s) to complete...`);
|
|
86
|
+
while (activeSessions.size > 0) {
|
|
87
|
+
await sleep(1000);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
console.log("[agent] Shutdown complete");
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface WorkerConfig {
|
|
2
|
+
fissionUrl: string;
|
|
3
|
+
apiKey: string;
|
|
4
|
+
workerId: string;
|
|
5
|
+
workerName: string;
|
|
6
|
+
maxConcurrent: number;
|
|
7
|
+
cacheDir: string;
|
|
8
|
+
}
|
|
9
|
+
export declare function configExists(): boolean;
|
|
10
|
+
export declare function readConfig(): WorkerConfig;
|
|
11
|
+
export declare function writeConfig(config: WorkerConfig): void;
|
|
12
|
+
export declare function getConfigPath(): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configExists = configExists;
|
|
4
|
+
exports.readConfig = readConfig;
|
|
5
|
+
exports.writeConfig = writeConfig;
|
|
6
|
+
exports.getConfigPath = getConfigPath;
|
|
7
|
+
const fs_1 = require("fs");
|
|
8
|
+
const path_1 = require("path");
|
|
9
|
+
const os_1 = require("os");
|
|
10
|
+
const CONFIG_DIR = (0, path_1.join)((0, os_1.homedir)(), ".fission");
|
|
11
|
+
const CONFIG_FILE = (0, path_1.join)(CONFIG_DIR, "worker.json");
|
|
12
|
+
function configExists() {
|
|
13
|
+
return (0, fs_1.existsSync)(CONFIG_FILE);
|
|
14
|
+
}
|
|
15
|
+
function readConfig() {
|
|
16
|
+
if (!(0, fs_1.existsSync)(CONFIG_FILE)) {
|
|
17
|
+
throw new Error("Worker not configured. Run: fission-worker setup");
|
|
18
|
+
}
|
|
19
|
+
const raw = (0, fs_1.readFileSync)(CONFIG_FILE, "utf-8");
|
|
20
|
+
return JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
function writeConfig(config) {
|
|
23
|
+
(0, fs_1.mkdirSync)(CONFIG_DIR, { recursive: true });
|
|
24
|
+
(0, fs_1.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
25
|
+
}
|
|
26
|
+
function getConfigPath() {
|
|
27
|
+
return CONFIG_FILE;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAgBA,oCAEC;AAED,gCAMC;AAED,kCAGC;AAED,sCAEC;AAnCD,2BAAwE;AACxE,+BAA4B;AAC5B,2BAA6B;AAW7B,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,IAAA,YAAO,GAAE,EAAE,UAAU,CAAC,CAAC;AAC/C,MAAM,WAAW,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,SAAgB,YAAY;IAC1B,OAAO,IAAA,eAAU,EAAC,WAAW,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,UAAU;IACxB,IAAI,CAAC,IAAA,eAAU,EAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,GAAG,GAAG,IAAA,iBAAY,EAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;AACzC,CAAC;AAED,SAAgB,WAAW,CAAC,MAAoB;IAC9C,IAAA,cAAS,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAA,kBAAa,EAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,SAAgB,aAAa;IAC3B,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
package/dist/docker.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { ChildProcess } from "child_process";
|
|
2
|
+
import { WorkerConfig } from "./config";
|
|
3
|
+
export interface PipelineJob {
|
|
4
|
+
sessionId: string;
|
|
5
|
+
projectId: string;
|
|
6
|
+
project: {
|
|
7
|
+
name: string;
|
|
8
|
+
repos: Array<{
|
|
9
|
+
name: string;
|
|
10
|
+
repoUrl: string;
|
|
11
|
+
repoPath: string;
|
|
12
|
+
branch: string;
|
|
13
|
+
}>;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
export declare function startSession(job: PipelineJob, config: WorkerConfig, activeSessions: Map<string, ChildProcess>): void;
|
package/dist/docker.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startSession = startSession;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
function startSession(job, config, activeSessions) {
|
|
6
|
+
const cacheDir = `${config.cacheDir}/${job.projectId}`;
|
|
7
|
+
(0, child_process_1.execSync)(`mkdir -p ${cacheDir}`);
|
|
8
|
+
// Resolve claude binary and config paths on host
|
|
9
|
+
let claudePath;
|
|
10
|
+
try {
|
|
11
|
+
claudePath = (0, child_process_1.execSync)("which claude").toString().trim();
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
console.error(`[${job.sessionId.slice(0, 8)}] Claude not found on host — skipping session`);
|
|
15
|
+
reportCompletion(config, job.sessionId, 1);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const claudeHome = `${process.env.HOME}/.claude`;
|
|
19
|
+
const repo = job.project.repos[0];
|
|
20
|
+
if (!repo) {
|
|
21
|
+
console.error(`[${job.sessionId.slice(0, 8)}] No repository found for project — skipping`);
|
|
22
|
+
reportCompletion(config, job.sessionId, 1);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const containerName = `fission-${job.sessionId.slice(0, 8)}`;
|
|
26
|
+
try {
|
|
27
|
+
// Create container
|
|
28
|
+
const createArgs = [
|
|
29
|
+
"create",
|
|
30
|
+
"--name", containerName,
|
|
31
|
+
"-v", `${claudePath}:/usr/local/bin/claude:ro`,
|
|
32
|
+
"-v", `${claudeHome}:/root/.claude:ro`,
|
|
33
|
+
"-v", `${cacheDir}:/workspace/.git-cache`,
|
|
34
|
+
"-e", `FISSION_API_URL=${config.fissionUrl}`,
|
|
35
|
+
"-e", `FISSION_API_KEY=${config.apiKey}`,
|
|
36
|
+
"-e", `SESSION_ID=${job.sessionId}`,
|
|
37
|
+
"-e", `PROJECT_ID=${job.projectId}`,
|
|
38
|
+
"-e", `REPO_URL=${repo.repoUrl}`,
|
|
39
|
+
"-e", `REPO_BRANCH=${repo.branch || "main"}`,
|
|
40
|
+
"-e", `GITHUB_TOKEN=`, // Token will be provided by API in future
|
|
41
|
+
"fission-runner:latest",
|
|
42
|
+
];
|
|
43
|
+
(0, child_process_1.execSync)(`docker ${createArgs.join(" ")}`, { stdio: "pipe" });
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
console.error(`[${containerName}] Failed to create container: ${err}`);
|
|
47
|
+
reportCompletion(config, job.sessionId, 1);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// Start and stream output
|
|
51
|
+
const proc = (0, child_process_1.spawn)("docker", ["start", "-a", containerName], {
|
|
52
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
53
|
+
});
|
|
54
|
+
activeSessions.set(job.sessionId, proc);
|
|
55
|
+
proc.stdout?.on("data", (chunk) => {
|
|
56
|
+
const text = chunk.toString().trim();
|
|
57
|
+
if (text)
|
|
58
|
+
console.log(`[${job.sessionId.slice(0, 8)}] ${text}`);
|
|
59
|
+
});
|
|
60
|
+
proc.stderr?.on("data", (chunk) => {
|
|
61
|
+
const text = chunk.toString().trim();
|
|
62
|
+
if (text)
|
|
63
|
+
console.error(`[${job.sessionId.slice(0, 8)}] ${text}`);
|
|
64
|
+
});
|
|
65
|
+
proc.on("close", (code) => {
|
|
66
|
+
console.log(`[${job.sessionId.slice(0, 8)}] Container exited with code ${code}`);
|
|
67
|
+
activeSessions.delete(job.sessionId);
|
|
68
|
+
// Cleanup container
|
|
69
|
+
try {
|
|
70
|
+
(0, child_process_1.execSync)(`docker rm -f ${containerName}`, { stdio: "pipe" });
|
|
71
|
+
}
|
|
72
|
+
catch { /* ignore */ }
|
|
73
|
+
reportCompletion(config, job.sessionId, code ?? 1);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function reportCompletion(config, sessionId, exitCode) {
|
|
77
|
+
fetch(`${config.fissionUrl}/api/worker/sessions/${sessionId}/complete`, {
|
|
78
|
+
method: "POST",
|
|
79
|
+
headers: {
|
|
80
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
81
|
+
"Content-Type": "application/json",
|
|
82
|
+
},
|
|
83
|
+
body: JSON.stringify({ exitCode }),
|
|
84
|
+
}).catch(() => { });
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"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"}
|
package/dist/health.d.ts
ADDED
package/dist/health.js
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkPrerequisites = checkPrerequisites;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
function checkPrerequisites() {
|
|
6
|
+
const checks = [];
|
|
7
|
+
// Docker
|
|
8
|
+
try {
|
|
9
|
+
const version = (0, child_process_1.execSync)("docker --version", { encoding: "utf-8" }).trim();
|
|
10
|
+
checks.push({ name: "Docker", ok: true, version });
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
checks.push({ name: "Docker", ok: false, error: "Docker not found" });
|
|
14
|
+
}
|
|
15
|
+
// Claude Code
|
|
16
|
+
try {
|
|
17
|
+
const version = (0, child_process_1.execSync)("claude --version 2>/dev/null || echo 'unknown'", { encoding: "utf-8" }).trim();
|
|
18
|
+
checks.push({ name: "Claude Code", ok: true, version });
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
checks.push({ name: "Claude Code", ok: false, error: "Claude Code not found" });
|
|
22
|
+
}
|
|
23
|
+
// Git
|
|
24
|
+
try {
|
|
25
|
+
const version = (0, child_process_1.execSync)("git --version", { encoding: "utf-8" }).trim();
|
|
26
|
+
checks.push({ name: "Git", ok: true, version });
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
checks.push({ name: "Git", ok: false, error: "Git not found" });
|
|
30
|
+
}
|
|
31
|
+
// Tailscale (optional)
|
|
32
|
+
try {
|
|
33
|
+
const version = (0, child_process_1.execSync)("tailscale version 2>/dev/null || echo ''", { encoding: "utf-8" }).trim();
|
|
34
|
+
if (version) {
|
|
35
|
+
checks.push({ name: "Tailscale", ok: true, version });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
checks.push({ name: "Tailscale", ok: true, version: "not installed (optional)" });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
checks.push({ name: "Tailscale", ok: true, version: "not installed (optional)" });
|
|
43
|
+
}
|
|
44
|
+
return checks;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":";;AASA,gDAwCC;AAjDD,iDAAyC;AASzC,SAAgB,kBAAkB;IAChC,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,SAAS;IACT,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,wBAAQ,EAAC,kBAAkB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3E,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,cAAc;IACd,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,wBAAQ,EAAC,gDAAgD,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACzG,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,MAAM;IACN,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,wBAAQ,EAAC,eAAe,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACxE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,eAAe,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,wBAAQ,EAAC,0CAA0C,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QACnG,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,0BAA0B,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const config_1 = require("./config");
|
|
6
|
+
const agent_1 = require("./agent");
|
|
7
|
+
const setup_1 = require("./setup");
|
|
8
|
+
const health_1 = require("./health");
|
|
9
|
+
const program = new commander_1.Command();
|
|
10
|
+
program
|
|
11
|
+
.name("fission-worker")
|
|
12
|
+
.description("Fission Worker Agent — runs pipeline sessions in Docker containers")
|
|
13
|
+
.version("0.1.0");
|
|
14
|
+
program
|
|
15
|
+
.command("setup")
|
|
16
|
+
.description("Interactive setup wizard — register this machine as a Fission worker")
|
|
17
|
+
.option("-u, --url <url>", "Fission API URL")
|
|
18
|
+
.action(async (opts) => {
|
|
19
|
+
await (0, setup_1.runSetup)(opts.url);
|
|
20
|
+
});
|
|
21
|
+
program
|
|
22
|
+
.command("start")
|
|
23
|
+
.description("Start polling for pipeline jobs")
|
|
24
|
+
.action(async () => {
|
|
25
|
+
if (!(0, config_1.configExists)()) {
|
|
26
|
+
console.error("Worker not configured. Run: fission-worker setup");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const config = (0, config_1.readConfig)();
|
|
30
|
+
console.log(`[fission-worker] Starting worker "${config.workerName}" (${config.workerId.slice(0, 8)})`);
|
|
31
|
+
await (0, agent_1.agentLoop)(config);
|
|
32
|
+
});
|
|
33
|
+
program
|
|
34
|
+
.command("status")
|
|
35
|
+
.description("Show current worker status")
|
|
36
|
+
.action(() => {
|
|
37
|
+
if (!(0, config_1.configExists)()) {
|
|
38
|
+
console.log("Worker not configured. Run: fission-worker setup");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const config = (0, config_1.readConfig)();
|
|
42
|
+
console.log(`Worker: ${config.workerName}`);
|
|
43
|
+
console.log(`ID: ${config.workerId}`);
|
|
44
|
+
console.log(`API: ${config.fissionUrl}`);
|
|
45
|
+
console.log(`Max: ${config.maxConcurrent} concurrent sessions`);
|
|
46
|
+
console.log(`Config: ${(0, config_1.getConfigPath)()}`);
|
|
47
|
+
console.log(`Cache: ${config.cacheDir}`);
|
|
48
|
+
});
|
|
49
|
+
program
|
|
50
|
+
.command("check")
|
|
51
|
+
.description("Check prerequisites (Docker, Claude, Git)")
|
|
52
|
+
.action(() => {
|
|
53
|
+
const checks = (0, health_1.checkPrerequisites)();
|
|
54
|
+
for (const check of checks) {
|
|
55
|
+
const icon = check.ok ? "✓" : "✗";
|
|
56
|
+
const detail = check.version || check.error || "";
|
|
57
|
+
console.log(`${icon} ${check.name}: ${detail}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
program.parse();
|
|
61
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,qCAAmE;AACnE,mCAAoC;AACpC,mCAAmC;AACnC,qCAA8C;AAE9C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,gBAAgB,CAAC;KACtB,WAAW,CAAC,oEAAoE,CAAC;KACjF,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sEAAsE,CAAC;KACnF,MAAM,CAAC,iBAAiB,EAAE,iBAAiB,CAAC;KAC5C,MAAM,CAAC,KAAK,EAAE,IAAsB,EAAE,EAAE;IACvC,MAAM,IAAA,gBAAQ,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC,IAAA,qBAAY,GAAE,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,qCAAqC,MAAM,CAAC,UAAU,MAAM,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC;IACxG,MAAM,IAAA,iBAAS,EAAC,MAAM,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,4BAA4B,CAAC;KACzC,MAAM,CAAC,GAAG,EAAE;IACX,IAAI,CAAC,IAAA,qBAAY,GAAE,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,OAAO;IACT,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;IAC5B,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,aAAa,sBAAsB,CAAC,CAAC;IACnE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAA,sBAAa,GAAE,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC5C,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,2CAA2C,CAAC;KACxD,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,MAAM,GAAG,IAAA,2BAAkB,GAAE,CAAC;IACpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAClC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/setup.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runSetup(fissionUrl?: string): Promise<void>;
|
package/dist/setup.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
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.runSetup = runSetup;
|
|
37
|
+
const os_1 = require("os");
|
|
38
|
+
const child_process_1 = require("child_process");
|
|
39
|
+
const config_1 = require("./config");
|
|
40
|
+
const health_1 = require("./health");
|
|
41
|
+
async function runSetup(fissionUrl) {
|
|
42
|
+
// Dynamic import for inquirer (ESM module)
|
|
43
|
+
const { default: inquirer } = await Promise.resolve().then(() => __importStar(require("inquirer")));
|
|
44
|
+
console.log("\n Fission Worker Setup\n ====================\n");
|
|
45
|
+
// Step 1: Connection
|
|
46
|
+
console.log(" Step 1/4 — Connection\n");
|
|
47
|
+
const { token } = await inquirer.prompt([{
|
|
48
|
+
type: "input",
|
|
49
|
+
name: "token",
|
|
50
|
+
message: "Paste your worker token from the Fission dashboard:",
|
|
51
|
+
validate: (v) => v.startsWith("wkr_") ? true : "Token should start with wkr_",
|
|
52
|
+
}]);
|
|
53
|
+
const baseUrl = fissionUrl || await inquirer.prompt([{
|
|
54
|
+
type: "input",
|
|
55
|
+
name: "url",
|
|
56
|
+
message: "Fission API URL:",
|
|
57
|
+
default: "https://app.fission.dev",
|
|
58
|
+
}]).then((a) => a.url);
|
|
59
|
+
// Step 2: Identity
|
|
60
|
+
console.log("\n Step 2/4 — Identity\n");
|
|
61
|
+
const { name } = await inquirer.prompt([{
|
|
62
|
+
type: "input",
|
|
63
|
+
name: "name",
|
|
64
|
+
message: 'Name this worker (e.g. "office-mac", "home-server"):',
|
|
65
|
+
default: (0, os_1.hostname)(),
|
|
66
|
+
}]);
|
|
67
|
+
// Step 3: Health checks
|
|
68
|
+
console.log("\n Step 3/4 — Prerequisite Checks\n");
|
|
69
|
+
const checks = (0, health_1.checkPrerequisites)();
|
|
70
|
+
let allOk = true;
|
|
71
|
+
for (const check of checks) {
|
|
72
|
+
const icon = check.ok ? "✓" : "✗";
|
|
73
|
+
const detail = check.version || check.error || "";
|
|
74
|
+
console.log(` ${icon} ${check.name}: ${detail}`);
|
|
75
|
+
if (!check.ok && check.name !== "Tailscale")
|
|
76
|
+
allOk = false;
|
|
77
|
+
}
|
|
78
|
+
if (!allOk) {
|
|
79
|
+
console.error("\n Some required prerequisites are missing. Install them and try again.");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
// Step 4: Capacity
|
|
83
|
+
console.log("\n Step 4/4 — Capacity\n");
|
|
84
|
+
const { maxConcurrent } = await inquirer.prompt([{
|
|
85
|
+
type: "number",
|
|
86
|
+
name: "maxConcurrent",
|
|
87
|
+
message: "Max concurrent pipelines for this machine?",
|
|
88
|
+
default: 3,
|
|
89
|
+
}]);
|
|
90
|
+
// Get system specs
|
|
91
|
+
let dockerVersion = "unknown";
|
|
92
|
+
try {
|
|
93
|
+
dockerVersion = (0, child_process_1.execSync)("docker --version", { encoding: "utf-8" }).trim();
|
|
94
|
+
}
|
|
95
|
+
catch { }
|
|
96
|
+
let claudeVersion = "unknown";
|
|
97
|
+
try {
|
|
98
|
+
claudeVersion = (0, child_process_1.execSync)("claude --version 2>/dev/null || echo 'unknown'", { encoding: "utf-8" }).trim();
|
|
99
|
+
}
|
|
100
|
+
catch { }
|
|
101
|
+
// Register with Fission API
|
|
102
|
+
console.log("\n Registering worker...");
|
|
103
|
+
const res = await fetch(`${baseUrl}/api/worker/register`, {
|
|
104
|
+
method: "POST",
|
|
105
|
+
headers: { "Content-Type": "application/json" },
|
|
106
|
+
body: JSON.stringify({
|
|
107
|
+
token,
|
|
108
|
+
hostname: (0, os_1.hostname)(),
|
|
109
|
+
name,
|
|
110
|
+
maxConcurrent,
|
|
111
|
+
specs: {
|
|
112
|
+
cpus: (0, os_1.cpus)().length,
|
|
113
|
+
memory: `${Math.round((0, os_1.totalmem)() / 1024 / 1024 / 1024)}GB`,
|
|
114
|
+
os: (0, os_1.platform)(),
|
|
115
|
+
dockerVersion,
|
|
116
|
+
claudeVersion,
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
});
|
|
120
|
+
if (!res.ok) {
|
|
121
|
+
const body = await res.text();
|
|
122
|
+
console.error(`\n Registration failed: ${res.status} ${body}`);
|
|
123
|
+
process.exit(1);
|
|
124
|
+
}
|
|
125
|
+
const result = await res.json();
|
|
126
|
+
const config = {
|
|
127
|
+
fissionUrl: baseUrl,
|
|
128
|
+
apiKey: result.apiKey,
|
|
129
|
+
workerId: result.workerId,
|
|
130
|
+
workerName: result.name,
|
|
131
|
+
maxConcurrent,
|
|
132
|
+
cacheDir: `${process.env.HOME}/.fission/cache`,
|
|
133
|
+
};
|
|
134
|
+
(0, config_1.writeConfig)(config);
|
|
135
|
+
console.log(`\n ✓ Worker registered successfully!`);
|
|
136
|
+
console.log(` ID: ${result.workerId}`);
|
|
137
|
+
console.log(` Tier: ${result.tier}`);
|
|
138
|
+
console.log(` Name: ${result.name}`);
|
|
139
|
+
console.log(`\n Run 'fission-worker start' to begin polling for jobs.\n`);
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../src/setup.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fission-worker",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Fission Worker Agent — polls Fission API for pipeline jobs, runs them in Docker containers",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"fission-worker": "dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"prepublishOnly": "npm run build",
|
|
12
|
+
"start": "node dist/index.js start",
|
|
13
|
+
"dev": "tsx src/index.ts start"
|
|
14
|
+
},
|
|
15
|
+
"keywords": ["fission", "pipeline", "worker", "docker", "claude"],
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"files": ["dist", "README.md"],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"commander": "^13.0.0",
|
|
20
|
+
"inquirer": "^12.0.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.0.0",
|
|
24
|
+
"typescript": "^5.7.0",
|
|
25
|
+
"tsx": "^4.19.0"
|
|
26
|
+
}
|
|
27
|
+
}
|