opencode-supertask 0.1.4 → 0.1.5
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/cli/index.js +160 -135
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/index.js +17547 -13672
- package/dist/gateway/index.js.map +1 -1
- package/dist/web/index.d.ts +4 -1
- package/dist/web/index.js +7 -1
- package/dist/web/index.js.map +1 -1
- package/dist/worker/index.d.ts +4 -0
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -19106,6 +19106,10 @@ var init_config = __esm({
|
|
|
19106
19106
|
cleanupIntervalMs: 6e4,
|
|
19107
19107
|
retentionDays: 30
|
|
19108
19108
|
},
|
|
19109
|
+
dashboard: {
|
|
19110
|
+
enabled: true,
|
|
19111
|
+
port: 4680
|
|
19112
|
+
},
|
|
19109
19113
|
logging: {
|
|
19110
19114
|
level: "info",
|
|
19111
19115
|
format: "json"
|
|
@@ -19723,137 +19727,6 @@ var init_scheduler = __esm({
|
|
|
19723
19727
|
}
|
|
19724
19728
|
});
|
|
19725
19729
|
|
|
19726
|
-
// src/gateway/index.ts
|
|
19727
|
-
var gateway_exports = {};
|
|
19728
|
-
__export(gateway_exports, {
|
|
19729
|
-
main: () => main
|
|
19730
|
-
});
|
|
19731
|
-
function acquireLock() {
|
|
19732
|
-
const now = Date.now();
|
|
19733
|
-
const pid = process.pid;
|
|
19734
|
-
try {
|
|
19735
|
-
sqlite.exec("BEGIN IMMEDIATE");
|
|
19736
|
-
const existing = sqlite.prepare("SELECT id, pid, heartbeat_at FROM gateway_lock WHERE id = 1").get();
|
|
19737
|
-
if (existing) {
|
|
19738
|
-
if (now - existing.heartbeat_at < STALE_THRESHOLD_MS) {
|
|
19739
|
-
sqlite.exec("ROLLBACK");
|
|
19740
|
-
console.error(JSON.stringify({
|
|
19741
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19742
|
-
level: "fatal",
|
|
19743
|
-
msg: "another Gateway instance is already running",
|
|
19744
|
-
existingPid: existing.pid
|
|
19745
|
-
}));
|
|
19746
|
-
return false;
|
|
19747
|
-
}
|
|
19748
|
-
sqlite.exec("DELETE FROM gateway_lock WHERE id = 1");
|
|
19749
|
-
}
|
|
19750
|
-
sqlite.exec(
|
|
19751
|
-
"INSERT INTO gateway_lock (id, pid, acquired_at, heartbeat_at) VALUES (1, ?, ?, ?)",
|
|
19752
|
-
[pid, now, now]
|
|
19753
|
-
);
|
|
19754
|
-
sqlite.exec("COMMIT");
|
|
19755
|
-
return true;
|
|
19756
|
-
} catch (err) {
|
|
19757
|
-
try {
|
|
19758
|
-
sqlite.exec("ROLLBACK");
|
|
19759
|
-
} catch {
|
|
19760
|
-
}
|
|
19761
|
-
console.error(JSON.stringify({
|
|
19762
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19763
|
-
level: "fatal",
|
|
19764
|
-
msg: "failed to acquire lock",
|
|
19765
|
-
error: err instanceof Error ? err.message : String(err)
|
|
19766
|
-
}));
|
|
19767
|
-
return false;
|
|
19768
|
-
}
|
|
19769
|
-
}
|
|
19770
|
-
function releaseLock() {
|
|
19771
|
-
try {
|
|
19772
|
-
sqlite.exec("DELETE FROM gateway_lock WHERE pid = ?", [process.pid]);
|
|
19773
|
-
} catch {
|
|
19774
|
-
}
|
|
19775
|
-
}
|
|
19776
|
-
function updateLockHeartbeat() {
|
|
19777
|
-
try {
|
|
19778
|
-
sqlite.exec(
|
|
19779
|
-
"UPDATE gateway_lock SET heartbeat_at = ? WHERE pid = ?",
|
|
19780
|
-
[Date.now(), process.pid]
|
|
19781
|
-
);
|
|
19782
|
-
} catch {
|
|
19783
|
-
}
|
|
19784
|
-
}
|
|
19785
|
-
async function main() {
|
|
19786
|
-
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: "SuperTask Gateway starting", pid: process.pid }));
|
|
19787
|
-
if (!acquireLock()) {
|
|
19788
|
-
process.exit(1);
|
|
19789
|
-
}
|
|
19790
|
-
const heartbeatTimer = setInterval(updateLockHeartbeat, 1e4);
|
|
19791
|
-
heartbeatTimer.unref();
|
|
19792
|
-
const cfg = loadConfig();
|
|
19793
|
-
const worker = new WorkerEngine(cfg);
|
|
19794
|
-
const watchdog = new Watchdog(cfg);
|
|
19795
|
-
const scheduler = new Scheduler(cfg);
|
|
19796
|
-
worker.start();
|
|
19797
|
-
watchdog.start();
|
|
19798
|
-
await scheduler.start();
|
|
19799
|
-
console.log(JSON.stringify({
|
|
19800
|
-
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
19801
|
-
level: "info",
|
|
19802
|
-
msg: "Gateway started",
|
|
19803
|
-
maxConcurrency: cfg.worker.maxConcurrency,
|
|
19804
|
-
schedulerEnabled: cfg.scheduler.enabled
|
|
19805
|
-
}));
|
|
19806
|
-
let shuttingDown = false;
|
|
19807
|
-
const shutdown = async (signal) => {
|
|
19808
|
-
if (shuttingDown) return;
|
|
19809
|
-
shuttingDown = true;
|
|
19810
|
-
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: `received ${signal}, shutting down...` }));
|
|
19811
|
-
clearInterval(heartbeatTimer);
|
|
19812
|
-
scheduler.stop();
|
|
19813
|
-
watchdog.stop();
|
|
19814
|
-
const runningIds = worker.getRunningTaskIds();
|
|
19815
|
-
await worker.stop();
|
|
19816
|
-
if (runningIds.length > 0) {
|
|
19817
|
-
const resetCount = await TaskService.resetRunningToPending(runningIds);
|
|
19818
|
-
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: "reset running tasks to pending", count: resetCount }));
|
|
19819
|
-
}
|
|
19820
|
-
const allRunningRuns = await TaskRunService.getAllRunningRuns();
|
|
19821
|
-
for (const run of allRunningRuns) {
|
|
19822
|
-
await TaskRunService.fail(run.id, "Gateway shutdown");
|
|
19823
|
-
}
|
|
19824
|
-
releaseLock();
|
|
19825
|
-
closeDb();
|
|
19826
|
-
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: "Gateway stopped" }));
|
|
19827
|
-
process.exit(0);
|
|
19828
|
-
};
|
|
19829
|
-
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
19830
|
-
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
19831
|
-
process.on("uncaughtException", (err) => {
|
|
19832
|
-
console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "uncaughtException", error: err.message, stack: err.stack }));
|
|
19833
|
-
});
|
|
19834
|
-
process.on("unhandledRejection", (reason) => {
|
|
19835
|
-
console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "unhandledRejection", reason: String(reason) }));
|
|
19836
|
-
});
|
|
19837
|
-
}
|
|
19838
|
-
var STALE_THRESHOLD_MS;
|
|
19839
|
-
var init_gateway = __esm({
|
|
19840
|
-
"src/gateway/index.ts"() {
|
|
19841
|
-
"use strict";
|
|
19842
|
-
init_db2();
|
|
19843
|
-
init_config();
|
|
19844
|
-
init_worker();
|
|
19845
|
-
init_watchdog();
|
|
19846
|
-
init_scheduler();
|
|
19847
|
-
init_db2();
|
|
19848
|
-
init_task_service();
|
|
19849
|
-
init_task_run_service();
|
|
19850
|
-
STALE_THRESHOLD_MS = 3e4;
|
|
19851
|
-
if (import.meta.main) {
|
|
19852
|
-
main();
|
|
19853
|
-
}
|
|
19854
|
-
}
|
|
19855
|
-
});
|
|
19856
|
-
|
|
19857
19730
|
// node_modules/hono/dist/compose.js
|
|
19858
19731
|
var compose;
|
|
19859
19732
|
var init_compose = __esm({
|
|
@@ -22191,6 +22064,7 @@ var init_html2 = __esm({
|
|
|
22191
22064
|
// src/web/index.tsx
|
|
22192
22065
|
var web_exports = {};
|
|
22193
22066
|
__export(web_exports, {
|
|
22067
|
+
dashboardApp: () => dashboardApp,
|
|
22194
22068
|
default: () => web_default
|
|
22195
22069
|
});
|
|
22196
22070
|
import { existsSync as existsSync3, readFileSync as readFileSync2, writeFileSync, mkdirSync as mkdirSync2 } from "fs";
|
|
@@ -22301,7 +22175,7 @@ async function saveConfig(){
|
|
|
22301
22175
|
<dialog id="dd"><div class="dh"><h3 style="margin:0">\u8BE6\u60C5</h3><button class="cb" onclick="document.getElementById('dd').close()">×</button></div><div class="db"><pre id="dc"></pre></div></dialog>
|
|
22302
22176
|
</body></html>`;
|
|
22303
22177
|
}
|
|
22304
|
-
var app, SHARED_STYLES, web_default;
|
|
22178
|
+
var app, SHARED_STYLES, dashboardApp, web_default;
|
|
22305
22179
|
var init_web = __esm({
|
|
22306
22180
|
"src/web/index.tsx"() {
|
|
22307
22181
|
"use strict";
|
|
@@ -22725,13 +22599,155 @@ var init_web = __esm({
|
|
|
22725
22599
|
return c.json({ success: false, error: err instanceof Error ? err.message : String(err) });
|
|
22726
22600
|
}
|
|
22727
22601
|
});
|
|
22602
|
+
dashboardApp = app;
|
|
22728
22603
|
web_default = {
|
|
22729
|
-
port:
|
|
22604
|
+
port: 4680,
|
|
22730
22605
|
fetch: app.fetch
|
|
22731
22606
|
};
|
|
22732
22607
|
}
|
|
22733
22608
|
});
|
|
22734
22609
|
|
|
22610
|
+
// src/gateway/index.ts
|
|
22611
|
+
var gateway_exports = {};
|
|
22612
|
+
__export(gateway_exports, {
|
|
22613
|
+
main: () => main
|
|
22614
|
+
});
|
|
22615
|
+
function acquireLock() {
|
|
22616
|
+
const now = Date.now();
|
|
22617
|
+
const pid = process.pid;
|
|
22618
|
+
try {
|
|
22619
|
+
sqlite.exec("BEGIN IMMEDIATE");
|
|
22620
|
+
const existing = sqlite.prepare("SELECT id, pid, heartbeat_at FROM gateway_lock WHERE id = 1").get();
|
|
22621
|
+
if (existing) {
|
|
22622
|
+
if (now - existing.heartbeat_at < STALE_THRESHOLD_MS) {
|
|
22623
|
+
sqlite.exec("ROLLBACK");
|
|
22624
|
+
console.error(JSON.stringify({
|
|
22625
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22626
|
+
level: "fatal",
|
|
22627
|
+
msg: "another Gateway instance is already running",
|
|
22628
|
+
existingPid: existing.pid
|
|
22629
|
+
}));
|
|
22630
|
+
return false;
|
|
22631
|
+
}
|
|
22632
|
+
sqlite.exec("DELETE FROM gateway_lock WHERE id = 1");
|
|
22633
|
+
}
|
|
22634
|
+
sqlite.exec(
|
|
22635
|
+
"INSERT INTO gateway_lock (id, pid, acquired_at, heartbeat_at) VALUES (1, ?, ?, ?)",
|
|
22636
|
+
[pid, now, now]
|
|
22637
|
+
);
|
|
22638
|
+
sqlite.exec("COMMIT");
|
|
22639
|
+
return true;
|
|
22640
|
+
} catch (err) {
|
|
22641
|
+
try {
|
|
22642
|
+
sqlite.exec("ROLLBACK");
|
|
22643
|
+
} catch {
|
|
22644
|
+
}
|
|
22645
|
+
console.error(JSON.stringify({
|
|
22646
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22647
|
+
level: "fatal",
|
|
22648
|
+
msg: "failed to acquire lock",
|
|
22649
|
+
error: err instanceof Error ? err.message : String(err)
|
|
22650
|
+
}));
|
|
22651
|
+
return false;
|
|
22652
|
+
}
|
|
22653
|
+
}
|
|
22654
|
+
function releaseLock() {
|
|
22655
|
+
try {
|
|
22656
|
+
sqlite.exec("DELETE FROM gateway_lock WHERE pid = ?", [process.pid]);
|
|
22657
|
+
} catch {
|
|
22658
|
+
}
|
|
22659
|
+
}
|
|
22660
|
+
function updateLockHeartbeat() {
|
|
22661
|
+
try {
|
|
22662
|
+
sqlite.exec(
|
|
22663
|
+
"UPDATE gateway_lock SET heartbeat_at = ? WHERE pid = ?",
|
|
22664
|
+
[Date.now(), process.pid]
|
|
22665
|
+
);
|
|
22666
|
+
} catch {
|
|
22667
|
+
}
|
|
22668
|
+
}
|
|
22669
|
+
async function main() {
|
|
22670
|
+
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: "SuperTask Gateway starting", pid: process.pid }));
|
|
22671
|
+
if (!acquireLock()) {
|
|
22672
|
+
process.exit(1);
|
|
22673
|
+
}
|
|
22674
|
+
const heartbeatTimer = setInterval(updateLockHeartbeat, 1e4);
|
|
22675
|
+
heartbeatTimer.unref();
|
|
22676
|
+
const cfg = loadConfig();
|
|
22677
|
+
const worker = new WorkerEngine(cfg);
|
|
22678
|
+
const watchdog = new Watchdog(cfg);
|
|
22679
|
+
const scheduler = new Scheduler(cfg);
|
|
22680
|
+
worker.start();
|
|
22681
|
+
watchdog.start();
|
|
22682
|
+
await scheduler.start();
|
|
22683
|
+
if (cfg.dashboard.enabled) {
|
|
22684
|
+
const { dashboardApp: dashboardApp2 } = await Promise.resolve().then(() => (init_web(), web_exports));
|
|
22685
|
+
Bun.serve({ port: cfg.dashboard.port, fetch: dashboardApp2.fetch });
|
|
22686
|
+
console.log(JSON.stringify({
|
|
22687
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22688
|
+
level: "info",
|
|
22689
|
+
msg: "Dashboard started",
|
|
22690
|
+
url: `http://localhost:${cfg.dashboard.port}`
|
|
22691
|
+
}));
|
|
22692
|
+
}
|
|
22693
|
+
console.log(JSON.stringify({
|
|
22694
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
22695
|
+
level: "info",
|
|
22696
|
+
msg: "Gateway started",
|
|
22697
|
+
maxConcurrency: cfg.worker.maxConcurrency,
|
|
22698
|
+
schedulerEnabled: cfg.scheduler.enabled
|
|
22699
|
+
}));
|
|
22700
|
+
let shuttingDown = false;
|
|
22701
|
+
const shutdown = async (signal) => {
|
|
22702
|
+
if (shuttingDown) return;
|
|
22703
|
+
shuttingDown = true;
|
|
22704
|
+
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: `received ${signal}, shutting down...` }));
|
|
22705
|
+
clearInterval(heartbeatTimer);
|
|
22706
|
+
scheduler.stop();
|
|
22707
|
+
watchdog.stop();
|
|
22708
|
+
const runningIds = worker.getRunningTaskIds();
|
|
22709
|
+
await worker.stop();
|
|
22710
|
+
if (runningIds.length > 0) {
|
|
22711
|
+
const resetCount = await TaskService.resetRunningToPending(runningIds);
|
|
22712
|
+
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: "reset running tasks to pending", count: resetCount }));
|
|
22713
|
+
}
|
|
22714
|
+
const allRunningRuns = await TaskRunService.getAllRunningRuns();
|
|
22715
|
+
for (const run of allRunningRuns) {
|
|
22716
|
+
await TaskRunService.fail(run.id, "Gateway shutdown");
|
|
22717
|
+
}
|
|
22718
|
+
releaseLock();
|
|
22719
|
+
closeDb();
|
|
22720
|
+
console.log(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "info", msg: "Gateway stopped" }));
|
|
22721
|
+
process.exit(0);
|
|
22722
|
+
};
|
|
22723
|
+
process.on("SIGTERM", () => shutdown("SIGTERM"));
|
|
22724
|
+
process.on("SIGINT", () => shutdown("SIGINT"));
|
|
22725
|
+
process.on("uncaughtException", (err) => {
|
|
22726
|
+
console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "uncaughtException", error: err.message, stack: err.stack }));
|
|
22727
|
+
});
|
|
22728
|
+
process.on("unhandledRejection", (reason) => {
|
|
22729
|
+
console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "unhandledRejection", reason: String(reason) }));
|
|
22730
|
+
});
|
|
22731
|
+
}
|
|
22732
|
+
var STALE_THRESHOLD_MS;
|
|
22733
|
+
var init_gateway = __esm({
|
|
22734
|
+
"src/gateway/index.ts"() {
|
|
22735
|
+
"use strict";
|
|
22736
|
+
init_db2();
|
|
22737
|
+
init_config();
|
|
22738
|
+
init_worker();
|
|
22739
|
+
init_watchdog();
|
|
22740
|
+
init_scheduler();
|
|
22741
|
+
init_db2();
|
|
22742
|
+
init_task_service();
|
|
22743
|
+
init_task_run_service();
|
|
22744
|
+
STALE_THRESHOLD_MS = 3e4;
|
|
22745
|
+
if (import.meta.main) {
|
|
22746
|
+
main();
|
|
22747
|
+
}
|
|
22748
|
+
}
|
|
22749
|
+
});
|
|
22750
|
+
|
|
22735
22751
|
// src/daemon/pm2.ts
|
|
22736
22752
|
var pm2_exports = {};
|
|
22737
22753
|
__export(pm2_exports, {
|
|
@@ -23162,8 +23178,17 @@ program2.command("gateway").description("Start the Gateway process (foreground)"
|
|
|
23162
23178
|
const { main: main2 } = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
|
|
23163
23179
|
await main2();
|
|
23164
23180
|
});
|
|
23165
|
-
program2.command("ui").description("
|
|
23166
|
-
await Promise.resolve().then(() => (
|
|
23181
|
+
program2.command("ui").description("Open Web Dashboard (embedded in Gateway)").action(async () => {
|
|
23182
|
+
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|
|
23183
|
+
const cfg = loadConfig2();
|
|
23184
|
+
const url = `http://localhost:${cfg.dashboard.port}`;
|
|
23185
|
+
console.log(`Dashboard: ${url}`);
|
|
23186
|
+
try {
|
|
23187
|
+
const { execSync: execSync2 } = await import("child_process");
|
|
23188
|
+
const cmd = process.platform === "win32" ? `start ${url}` : process.platform === "darwin" ? `open ${url}` : `xdg-open ${url}`;
|
|
23189
|
+
execSync2(cmd, { stdio: "ignore" });
|
|
23190
|
+
} catch {
|
|
23191
|
+
}
|
|
23167
23192
|
});
|
|
23168
23193
|
program2.command("config").description("Show current configuration").action(async () => {
|
|
23169
23194
|
const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
|