opencode-supertask 0.1.17 → 0.1.19

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.
@@ -1,5 +1,3 @@
1
- #!/usr/bin/env bun
2
-
3
1
  var __create = Object.create;
4
2
  var __defProp = Object.defineProperty;
5
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -6086,7 +6084,7 @@ import { join, dirname } from "path";
6086
6084
  import { fileURLToPath } from "url";
6087
6085
  function getMigrationsFolder() {
6088
6086
  const __dirname = dirname(fileURLToPath(import.meta.url));
6089
- return join(__dirname, "../../drizzle");
6087
+ return join(__dirname, "../../../drizzle");
6090
6088
  }
6091
6089
  function initDb() {
6092
6090
  const dataDir = dirname(DB_FILE_PATH);
@@ -6110,7 +6108,9 @@ function initDb() {
6110
6108
  try {
6111
6109
  migrate(_db, { migrationsFolder: getMigrationsFolder() });
6112
6110
  } catch (err) {
6113
- console.error("[supertask] migration failed:", err instanceof Error ? err.message : String(err));
6111
+ const msg = err instanceof Error ? err.message : String(err);
6112
+ console.error(`[supertask] migration failed: ${msg}`);
6113
+ throw new Error(`[supertask] DB migration failed: ${msg}`);
6114
6114
  }
6115
6115
  }
6116
6116
  return _db;
@@ -6130,14 +6130,15 @@ function closeDb() {
6130
6130
  _db = null;
6131
6131
  }
6132
6132
  }
6133
- var DB_FILE_PATH, _sqlite, _db, _migrationRan, db, sqlite;
6133
+ var DEFAULT_DB_PATH, DB_FILE_PATH, _sqlite, _db, _migrationRan, db, sqlite;
6134
6134
  var init_db2 = __esm({
6135
6135
  "src/core/db/index.ts"() {
6136
6136
  "use strict";
6137
6137
  init_bun_sqlite();
6138
6138
  init_migrator2();
6139
6139
  init_schema();
6140
- DB_FILE_PATH = join(homedir(), ".local/share/opencode/tasks.db");
6140
+ DEFAULT_DB_PATH = join(homedir(), ".local/share/opencode/tasks.db");
6141
+ DB_FILE_PATH = process.env.SUPERTASK_DB_PATH || DEFAULT_DB_PATH;
6141
6142
  _sqlite = null;
6142
6143
  _db = null;
6143
6144
  _migrationRan = false;
@@ -18291,6 +18292,10 @@ function formatDate(ts) {
18291
18292
  const d = ts instanceof Date ? ts : new Date(ts);
18292
18293
  return d.toLocaleString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" });
18293
18294
  }
18295
+ function esc(s) {
18296
+ if (!s) return "";
18297
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
18298
+ }
18294
18299
  function readCurrentConfig() {
18295
18300
  if (!existsSync3(CONFIG_PATH)) return {};
18296
18301
  try {
@@ -18311,6 +18316,7 @@ async function retryTask(id){if(!confirm('\u786E\u5B9A\u91CD\u8BD5\u4EFB\u52A1 #
18311
18316
  async function deleteTask(id){if(!confirm('\u786E\u5B9A\u5220\u9664\u4EFB\u52A1 #'+id+'?'))return;await fetch('/api/tasks/'+id,{method:'DELETE'});location.reload();}
18312
18317
  async function showDetail(id){try{const r=await fetch('/api/tasks/'+id);const t=await r.json();document.getElementById('dc').textContent=JSON.stringify(t,null,2);document.getElementById('dd').showModal();}catch(e){alert('\u83B7\u53D6\u8BE6\u60C5\u5931\u8D25');}}
18313
18318
  async function showRunDetail(id){try{const r=await fetch('/api/runs/'+id);const t=await r.json();document.getElementById('dc').textContent=JSON.stringify(t,null,2);document.getElementById('dd').showModal();}catch(e){alert('\u83B7\u53D6\u8BE6\u60C5\u5931\u8D25');}}
18319
+ async function showTemplateDetail(id){try{const r=await fetch('/api/templates/'+id);const t=await r.json();document.getElementById('dc').textContent=JSON.stringify(t,null,2);document.getElementById('dd').showModal();}catch(e){alert('\u83B7\u53D6\u8BE6\u60C5\u5931\u8D25');}}
18314
18320
  async function enableTmpl(id){await fetch('/api/templates/'+id+'/enable',{method:'POST'});location.reload();}
18315
18321
  async function disableTmpl(id){if(!confirm('\u786E\u5B9A\u7981\u7528\u6B64\u6A21\u677F?'))return;await fetch('/api/templates/'+id+'/disable',{method:'POST'});location.reload();}
18316
18322
  async function deleteTmpl(id){if(!confirm('\u786E\u5B9A\u5220\u9664\u6B64\u6A21\u677F? \u6B64\u64CD\u4F5C\u4E0D\u53EF\u6062\u590D!'))return;await fetch('/api/templates/'+id,{method:'DELETE'});location.reload();}
@@ -18495,8 +18501,8 @@ var init_web = __esm({
18495
18501
  const st = (task.status ?? "").toUpperCase();
18496
18502
  rows += `<tr>
18497
18503
  <td class="mu">#${task.id}</td>
18498
- <td><div style="font-weight:500">${task.name}</div><div class="mu sm el">${task.prompt.substring(0, 120)}</div></td>
18499
- <td><span class="tag">${task.agent}</span></td>
18504
+ <td><div style="font-weight:500">${esc(task.name)}</div><div class="mu sm el">${esc(task.prompt.substring(0, 120))}</div></td>
18505
+ <td><span class="tag">${esc(task.agent)}</span></td>
18500
18506
  <td><span class="badge b-${task.status}">${st}</span></td>
18501
18507
  <td class="sm ${task.status === "running" ? "" : "mu"}">${formatDuration(task.startedAt, task.finishedAt)}</td>
18502
18508
  <td class="mu sm">${(task.retryCount ?? 0) > 0 ? task.retryCount : "-"}</td>
@@ -18552,15 +18558,15 @@ var init_web = __esm({
18552
18558
  const toggleBtn = t.enabled ? `<button class="btn btn-sm btn-warn" onclick="disableTmpl(${t.id})">\u7981\u7528</button>` : `<button class="btn btn-sm" onclick="enableTmpl(${t.id})">\u542F\u7528</button>`;
18553
18559
  rows += `<tr>
18554
18560
  <td class="mu">#${t.id}</td>
18555
- <td><div style="font-weight:500">${t.name}</div><div class="mu sm el">${t.prompt.substring(0, 100)}</div>
18556
- <div class="sm" style="margin-top:2px"><span class="tag">${t.agent}</span>${t.model && t.model !== "default" ? ` <span class="tag">${t.model}</span>` : ""}</div></td>
18561
+ <td><div style="font-weight:500">${esc(t.name)}</div><div class="mu sm el">${esc(t.prompt.substring(0, 100))}</div>
18562
+ <div class="sm" style="margin-top:2px"><span class="tag">${esc(t.agent)}</span>${t.model && t.model !== "default" ? ` <span class="tag">${esc(t.model)}</span>` : ""}</div></td>
18557
18563
  <td><span class="${typeClass}">${typeLabel}</span></td>
18558
18564
  <td class="m sm">${rule}</td>
18559
18565
  <td>${statusBadge}</td>
18560
18566
  <td class="sm">${t.lastRunAt ? timeAgo(t.lastRunAt) : "-"}</td>
18561
18567
  <td class="sm">${t.nextRunAt ? timeUntil(t.nextRunAt) : "-"}</td>
18562
18568
  <td>
18563
- <button class="btn btn-sm" onclick="showDetail(${t.id})">\u8BE6\u60C5</button>
18569
+ <button class="btn btn-sm" onclick="showTemplateDetail(${t.id})">\u8BE6\u60C5</button>
18564
18570
  <button class="btn btn-sm btn-primary" onclick="triggerTmpl(${t.id})">\u89E6\u53D1</button>
18565
18571
  ${toggleBtn}
18566
18572
  <button class="btn btn-sm btn-danger" onclick="deleteTmpl(${t.id})">\u5220\u9664</button>
@@ -18612,9 +18618,9 @@ var init_web = __esm({
18612
18618
  const logBtn = run.log ? `<button class="btn btn-sm" onclick="toggleLog(${run.id})">\u65E5\u5FD7</button>` : "";
18613
18619
  rows += `<tr>
18614
18620
  <td class="mu">#${run.id}</td>
18615
- <td><div style="font-weight:500">${run.taskName} <span class="mu">(#${run.taskId})</span></div>
18616
- ${run.model ? `<div class="sm"><span class="tag">${run.model}</span></div>` : ""}</td>
18617
- <td><span class="tag">${run.taskAgent}</span></td>
18621
+ <td><div style="font-weight:500">${esc(run.taskName)} <span class="mu">(#${run.taskId})</span></div>
18622
+ ${run.model ? `<div class="sm"><span class="tag">${esc(run.model)}</span></div>` : ""}</td>
18623
+ <td><span class="tag">${esc(run.taskAgent)}</span></td>
18618
18624
  <td><span class="badge b-${run.status}">${(run.status ?? "").toUpperCase()}</span></td>
18619
18625
  <td class="sm">${formatDuration(run.startedAt, run.finishedAt)}</td>
18620
18626
  <td class="sm mu">${run.heartbeatAt ? timeAgo(run.heartbeatAt) : "-"}</td>
@@ -18660,7 +18666,7 @@ var init_web = __esm({
18660
18666
  runRows += `<tr>
18661
18667
  <td class="mu">#${run.id}</td><td>#${run.taskId}</td>
18662
18668
  <td class="m sm">${shortS}</td>
18663
- <td class="sm">${run.model || "-"}</td>
18669
+ <td class="sm">${esc(run.model) || "-"}</td>
18664
18670
  <td class="sm">${formatDate(run.startedAt)}</td>
18665
18671
  <td class="sm">${run.heartbeatAt ? timeAgo(run.heartbeatAt) : "-"}</td>
18666
18672
  <td class="m sm">W:${run.workerPid ?? "-"} C:${run.childPid ?? "-"}</td>
@@ -18749,6 +18755,12 @@ var init_web = __esm({
18749
18755
  if (!run) return c.json({ error: "not found" }, 404);
18750
18756
  return c.json(run);
18751
18757
  });
18758
+ app.get("/api/templates/:id", async (c) => {
18759
+ const id = Number(c.req.param("id"));
18760
+ const tmpl = await TaskTemplateService.getById(id);
18761
+ if (!tmpl) return c.json({ error: "not found" }, 404);
18762
+ return c.json(tmpl);
18763
+ });
18752
18764
  app.post("/api/tasks/:id/retry", async (c) => {
18753
18765
  await TaskService.retry(Number(c.req.param("id")));
18754
18766
  return c.json({ success: true });
@@ -18893,10 +18905,13 @@ var WorkerEngine = class {
18893
18905
  status: "running"
18894
18906
  });
18895
18907
  const modelToUse = this.resolveModel(task.model);
18896
- const modelArg = modelToUse ? ` -m "${modelToUse}"` : "";
18897
- const cmd = `opencode run --agent supertask-runner${modelArg} --format json "\u6267\u884C\u4EFB\u52A1 ID: ${task.id}${modelToUse ? ` OVERRIDE_MODEL=${modelToUse}` : ""}"`;
18908
+ const args = ["run", "--agent", "supertask-runner", "--format", "json"];
18909
+ if (modelToUse) {
18910
+ args.push("-m", modelToUse);
18911
+ }
18912
+ args.push(`\u6267\u884C\u4EFB\u52A1 ID: ${task.id}${modelToUse ? ` OVERRIDE_MODEL=${modelToUse}` : ""}`);
18898
18913
  const cwd = task.cwd || process.cwd();
18899
- const child = spawn("sh", ["-c", cmd], { cwd, stdio: ["ignore", "pipe", "pipe"] });
18914
+ const child = spawn("opencode", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
18900
18915
  await TaskRunService.updatePid(run.id, process.pid, child.pid ?? 0);
18901
18916
  let output = "";
18902
18917
  const handleData = (data) => {
@@ -19357,7 +19372,16 @@ async function main() {
19357
19372
  await scheduler.start();
19358
19373
  if (cfg.dashboard.enabled) {
19359
19374
  const { dashboardApp: dashboardApp2 } = await Promise.resolve().then(() => (init_web(), web_exports));
19360
- Bun.serve({ port: cfg.dashboard.port, fetch: dashboardApp2.fetch });
19375
+ Bun.serve({
19376
+ port: cfg.dashboard.port,
19377
+ fetch(req) {
19378
+ const url = new URL(req.url);
19379
+ if (url.hostname !== "localhost" && url.hostname !== "127.0.0.1" && url.hostname !== "::1") {
19380
+ return new Response("Forbidden", { status: 403 });
19381
+ }
19382
+ return dashboardApp2.fetch(req);
19383
+ }
19384
+ });
19361
19385
  console.log(JSON.stringify({
19362
19386
  ts: (/* @__PURE__ */ new Date()).toISOString(),
19363
19387
  level: "info",
@@ -19399,9 +19423,11 @@ async function main() {
19399
19423
  process.on("SIGINT", () => shutdown("SIGINT"));
19400
19424
  process.on("uncaughtException", (err) => {
19401
19425
  console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "uncaughtException", error: err.message, stack: err.stack }));
19426
+ process.exit(1);
19402
19427
  });
19403
19428
  process.on("unhandledRejection", (reason) => {
19404
19429
  console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "unhandledRejection", reason: String(reason) }));
19430
+ process.exit(1);
19405
19431
  });
19406
19432
  }
19407
19433
  if (import.meta.main) {