opencode-supertask 0.1.18 → 0.1.20

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 CHANGED
@@ -9,20 +9,9 @@ AI-powered task queue for [OpenCode](https://opencode.ai) agents — schedule, r
9
9
 
10
10
  ## Installation
11
11
 
12
- ### Let an LLM do it
12
+ ### Quick Install
13
13
 
14
- Paste this into any LLM agent (Claude Code, OpenCode, Cursor, etc.):
15
-
16
- ```
17
- Install the opencode-supertask plugin by following: https://raw.githubusercontent.com/vbgate/opencode-supertask/main/README.md
18
- ```
19
-
20
- <details>
21
- <summary><b>Instructions for LLM agents</b></summary>
22
-
23
- To install this plugin, perform these steps:
24
-
25
- 1. Add `"opencode-supertask"` to the `plugin` array in `~/.config/opencode/opencode.json`:
14
+ Add the plugin to `~/.config/opencode/opencode.json`:
26
15
 
27
16
  ```json
28
17
  {
@@ -30,26 +19,31 @@ To install this plugin, perform these steps:
30
19
  }
31
20
  ```
32
21
 
33
- 2. Tell the user to restart OpenCode.
22
+ Restart OpenCode. That's it.
34
23
 
35
- After restart, the plugin auto-injects:
24
+ The plugin auto-starts a Gateway process (via pm2) and injects:
36
25
  - 10 MCP tools (`supertask_add`, `supertask_next`, `supertask_start`, `supertask_done`, `supertask_fail`, `supertask_get`, `supertask_list`, `supertask_status`, `supertask_retry`, `supertask_schedule`)
37
26
  - A `supertask-runner` agent (used internally by the Gateway)
38
- - Usage instructions in the system prompt
27
+ - A Web Dashboard at http://localhost:4680
39
28
 
40
- </details>
29
+ ### Uninstall
41
30
 
42
- ### Manual Installation
31
+ 1. Run `supertask uninstall` to stop the Gateway and remove it from pm2
32
+ 2. Remove `"opencode-supertask"` from `~/.config/opencode/opencode.json`
33
+ 3. Restart OpenCode
43
34
 
44
- 1. Add the plugin to your `~/.config/opencode/opencode.json`:
35
+ To clean up all data, delete the database:
45
36
 
46
- ```json
47
- {
48
- "plugin": ["opencode-supertask"]
49
- }
37
+ ```bash
38
+ rm ~/.local/share/opencode/tasks.db
50
39
  ```
51
40
 
52
- 2. Restart OpenCode
41
+ ### CLI Install / Uninstall
42
+
43
+ ```bash
44
+ supertask install # Install Gateway as pm2 service (auto-start, crash recovery)
45
+ supertask uninstall # Stop and remove Gateway from pm2
46
+ ```
53
47
 
54
48
  ### From Source
55
49
 
@@ -70,39 +64,27 @@ Then add the local path to your config:
70
64
 
71
65
  ## Quick Start
72
66
 
73
- ```bash
74
- # Install globally for CLI + Gateway
75
- bun install -g opencode-supertask
76
-
77
- # Initialize (create config + run migrations)
78
- supertask init
79
-
80
- # Start Gateway (foreground)
81
- supertask gateway
67
+ After installation, the Gateway starts automatically. Use the MCP tools in OpenCode:
82
68
 
83
- # Start Web Dashboard
84
- supertask ui # http://localhost:3000
69
+ ```
70
+ Create a task: "帮我生成项目的 README" with agent "explore"
85
71
  ```
86
72
 
87
- ### Background Running
73
+ Or open the Web Dashboard:
88
74
 
89
75
  ```bash
90
- # pm2 (recommended)
91
- pm2 start "supertask gateway" --name supertask-gateway
92
-
93
- # systemd
94
- cp deploy/supertask-gateway.service ~/.config/systemd/user/
95
- systemctl --user enable --now supertask-gateway
76
+ supertask ui # Opens http://localhost:4680 in browser
96
77
  ```
97
78
 
98
79
  ## CLI Reference
99
80
 
100
81
  ```bash
101
- supertask init # init config + db
102
- supertask migrate # run migrations
103
- supertask gateway # start gateway (foreground)
104
- supertask ui # start web dashboard
105
- supertask config # show current config
82
+ # Gateway management
83
+ supertask install # install Gateway as pm2 service
84
+ supertask uninstall # stop and remove from pm2
85
+ supertask gateway # start Gateway in foreground
86
+ supertask ui # open Web Dashboard in browser
87
+ supertask config # show current config
106
88
 
107
89
  # Task management
108
90
  supertask add -n "Task" -a "agent" -p "prompt" --importance 5
@@ -112,33 +94,54 @@ supertask status
112
94
  supertask cancel --id 1
113
95
  supertask retry --id 1
114
96
 
115
- # Scheduled templates
97
+ # Scheduled templates (friendly duration format)
116
98
  supertask template add --name "Daily" --agent "gen" \
117
99
  --prompt "..." --type cron --cron "0 9 * * *"
100
+ supertask template add --name "Delayed" --agent "gen" \
101
+ --prompt "..." --type delayed --delay "30min"
102
+ supertask template add --name "Hourly" --agent "gen" \
103
+ --prompt "..." --type recurring --interval "1h"
118
104
  supertask template list
119
105
  supertask template enable --id 1
120
106
  ```
121
107
 
108
+ ### Duration Format
109
+
110
+ Schedule supports friendly duration strings:
111
+
112
+ | Format | Examples |
113
+ |--------|----------|
114
+ | Seconds | `30s`, `5sec` |
115
+ | Minutes | `5min`, `30minutes` |
116
+ | Hours | `1h`, `2hours` |
117
+ | Days | `1d`, `3days` |
118
+ | Weeks | `1w`, `2weeks` |
119
+ | ISO 8601 | `PT30M`, `PT1H30M` |
120
+
122
121
  ## Architecture
123
122
 
124
123
  ```
125
- Gateway (supertask gateway)
126
- ├── Worker → claim tasks, spawn supertask-runner via opencode
124
+ Gateway (auto-started by pm2)
125
+ ├── Worker → claim tasks, spawn supertask-runner via opencode run
127
126
  ├── Scheduler → clone tasks from templates (cron / delayed / recurring)
128
- └── Watchdog → heartbeat timeout, auto-retry, data cleanup
127
+ ├── Watchdog → heartbeat timeout, auto-retry, data cleanup
128
+ └── Dashboard → Web UI on port 4680 (Hono SSR)
129
129
  ```
130
130
 
131
131
  Config file: `~/.config/opencode/supertask.json`
132
132
 
133
133
  ```json
134
134
  {
135
- "worker": { "maxConcurrency": 2, "defaultModel": "zhipuai-coding-plan/glm-4.7" },
135
+ "worker": { "maxConcurrency": 2 },
136
136
  "scheduler": { "enabled": true, "catchUp": "next" },
137
- "watchdog": { "heartbeatTimeoutMs": 600000, "retentionDays": 30 }
137
+ "watchdog": { "heartbeatTimeoutMs": 600000, "retentionDays": 30 },
138
+ "dashboard": { "enabled": true, "port": 4680 }
138
139
  }
139
140
  ```
140
141
 
141
142
  Key mechanisms:
143
+ - **Auto-start** — Plugin auto-installs pm2 and starts Gateway on first use
144
+ - **Auto-upgrade** — Plugin detects version changes and auto-reloads Gateway
142
145
  - **Process lock** — SQLite `BEGIN IMMEDIATE` ensures single instance
143
146
  - **Heartbeat** — Worker updates every 30s; Watchdog kills stale processes
144
147
  - **Exponential backoff** — 30s × 2^n, capped at 30min
@@ -148,14 +151,14 @@ Key mechanisms:
148
151
 
149
152
  ## Web Dashboard
150
153
 
151
- `supertask ui` starts a dashboard at http://localhost:3000 with 4 pages:
154
+ http://localhost:4680 4 pages:
152
155
 
153
156
  | Page | Features |
154
157
  |------|----------|
155
158
  | Task Queue | Filter by status, retry, delete |
156
159
  | Scheduled Tasks | Template CRUD, enable/disable, manual trigger |
157
- | Execution Logs | task_runs history, log viewer |
158
- | System Status | Config editor, concurrency monitor, stats |
160
+ | Execution Logs | task_runs history with session tracking |
161
+ | System Status | Config editor, concurrency monitor, clear database |
159
162
 
160
163
  ## Data
161
164
 
@@ -181,16 +184,6 @@ SuperTask 是一个基于 SQLite 的 AI Agent 任务调度系统,专为 [OpenC
181
184
 
182
185
  ### 安装
183
186
 
184
- #### 让 AI 帮你装
185
-
186
- 把这段话粘贴到任意 LLM agent(Claude Code、OpenCode、Cursor 等):
187
-
188
- ```
189
- 安装 opencode-supertask 插件,参照:https://raw.githubusercontent.com/vbgate/opencode-supertask/main/README.md
190
- ```
191
-
192
- #### 手动安装
193
-
194
187
  在 `~/.config/opencode/opencode.json` 中添加:
195
188
 
196
189
  ```json
@@ -199,24 +192,42 @@ SuperTask 是一个基于 SQLite 的 AI Agent 任务调度系统,专为 [OpenC
199
192
  }
200
193
  ```
201
194
 
202
- 重启 OpenCode 即可。插件会自动注入 10 个 MCP 工具、supertask-runner Agent 和使用说明。
195
+ 重启 OpenCode 即可。插件会自动:
196
+ - 安装 pm2 并启动 Gateway 常驻进程
197
+ - 注入 10 个 MCP 工具和 supertask-runner Agent
198
+ - 启动 Web 控制台(http://localhost:4680)
199
+
200
+ ### 卸载
201
+
202
+ 1. 运行 `supertask uninstall` 停止 Gateway
203
+ 2. 从 `~/.config/opencode/opencode.json` 中移除 `"opencode-supertask"`
204
+ 3. 重启 OpenCode
203
205
 
204
- ### 快速开始
206
+ 清理所有数据:`rm ~/.local/share/opencode/tasks.db`
207
+
208
+ ### 定时任务
209
+
210
+ 支持友好的时间格式:
205
211
 
206
212
  ```bash
207
- bun install -g opencode-supertask
208
- supertask init # 初始化
209
- supertask gateway # 启动 Gateway
210
- supertask ui # Web 控制台
213
+ # 30秒后执行
214
+ supertask template add --type delayed --delay "30s" ...
215
+
216
+ # 每5分钟循环
217
+ supertask template add --type recurring --interval "5min" ...
218
+
219
+ # 每天上午9点(cron)
220
+ supertask template add --type cron --cron "0 9 * * *" ...
211
221
  ```
212
222
 
213
223
  ### 核心功能
214
224
 
215
225
  - **任务队列** — 优先级调度、批次隔离、依赖管理
216
- - **Gateway 常驻进程** Worker + Scheduler + Watchdog,自动重试 + 指数退避
217
- - **定时任务**支持 cron / delayed / recurring 三种调度类型
218
- - **Web 控制台** 任务监控、执行日志、在线配置
219
- - **CLI 工具**完整的命令行管理
226
+ - **自动启动**插件首次加载时自动安装 pm2 并启动 Gateway
227
+ - **自动升级**插件更新后自动检测版本变化并 reload Gateway
228
+ - **定时任务**cron / delayed / recurring,支持友好时间格式
229
+ - **Web 控制台**任务监控、执行日志、在线配置、清空数据库
230
+ - **Session 追踪** — 自动从 opencode run 输出中捕获 session ID
220
231
 
221
232
  ### 数据位置
222
233
 
package/dist/cli/index.js CHANGED
@@ -9400,6 +9400,14 @@ import { join, dirname } from "path";
9400
9400
  import { fileURLToPath } from "url";
9401
9401
  function getMigrationsFolder() {
9402
9402
  const __dirname2 = dirname(fileURLToPath(import.meta.url));
9403
+ let dir = __dirname2;
9404
+ for (let i = 0; i < 5; i++) {
9405
+ const candidate = join(dir, "drizzle", "meta", "_journal.json");
9406
+ if (existsSync(candidate)) {
9407
+ return join(dir, "drizzle");
9408
+ }
9409
+ dir = dirname(dir);
9410
+ }
9403
9411
  return join(__dirname2, "../../drizzle");
9404
9412
  }
9405
9413
  function initDb() {
@@ -9424,7 +9432,9 @@ function initDb() {
9424
9432
  try {
9425
9433
  migrate(_db, { migrationsFolder: getMigrationsFolder() });
9426
9434
  } catch (err) {
9427
- console.error("[supertask] migration failed:", err instanceof Error ? err.message : String(err));
9435
+ const msg = err instanceof Error ? err.message : String(err);
9436
+ console.error(`[supertask] migration failed: ${msg}`);
9437
+ throw new Error(`[supertask] DB migration failed: ${msg}`);
9428
9438
  }
9429
9439
  }
9430
9440
  return _db;
@@ -9444,14 +9454,15 @@ function closeDb() {
9444
9454
  _db = null;
9445
9455
  }
9446
9456
  }
9447
- var DB_FILE_PATH, _sqlite, _db, _migrationRan, db, sqlite;
9457
+ var DEFAULT_DB_PATH, DB_FILE_PATH, _sqlite, _db, _migrationRan, db, sqlite;
9448
9458
  var init_db2 = __esm({
9449
9459
  "src/core/db/index.ts"() {
9450
9460
  "use strict";
9451
9461
  init_bun_sqlite();
9452
9462
  init_migrator2();
9453
9463
  init_schema();
9454
- DB_FILE_PATH = join(homedir(), ".local/share/opencode/tasks.db");
9464
+ DEFAULT_DB_PATH = join(homedir(), ".local/share/opencode/tasks.db");
9465
+ DB_FILE_PATH = process.env.SUPERTASK_DB_PATH || DEFAULT_DB_PATH;
9455
9466
  _sqlite = null;
9456
9467
  _db = null;
9457
9468
  _migrationRan = false;
@@ -19306,10 +19317,13 @@ var init_worker = __esm({
19306
19317
  status: "running"
19307
19318
  });
19308
19319
  const modelToUse = this.resolveModel(task.model);
19309
- const modelArg = modelToUse ? ` -m "${modelToUse}"` : "";
19310
- const cmd = `opencode run --agent supertask-runner${modelArg} --format json "\u6267\u884C\u4EFB\u52A1 ID: ${task.id}${modelToUse ? ` OVERRIDE_MODEL=${modelToUse}` : ""}"`;
19320
+ const args = ["run", "--agent", "supertask-runner", "--format", "json"];
19321
+ if (modelToUse) {
19322
+ args.push("-m", modelToUse);
19323
+ }
19324
+ args.push(`\u6267\u884C\u4EFB\u52A1 ID: ${task.id}${modelToUse ? ` OVERRIDE_MODEL=${modelToUse}` : ""}`);
19311
19325
  const cwd = task.cwd || process.cwd();
19312
- const child = spawn("sh", ["-c", cmd], { cwd, stdio: ["ignore", "pipe", "pipe"] });
19326
+ const child = spawn("opencode", args, { cwd, stdio: ["ignore", "pipe", "pipe"] });
19313
19327
  await TaskRunService.updatePid(run.id, process.pid, child.pid ?? 0);
19314
19328
  let output = "";
19315
19329
  const handleData = (data) => {
@@ -22102,6 +22116,10 @@ function formatDate(ts) {
22102
22116
  const d = ts instanceof Date ? ts : new Date(ts);
22103
22117
  return d.toLocaleString("zh-CN", { month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit" });
22104
22118
  }
22119
+ function esc(s) {
22120
+ if (!s) return "";
22121
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
22122
+ }
22105
22123
  function readCurrentConfig() {
22106
22124
  if (!existsSync3(CONFIG_PATH)) return {};
22107
22125
  try {
@@ -22122,6 +22140,7 @@ async function retryTask(id){if(!confirm('\u786E\u5B9A\u91CD\u8BD5\u4EFB\u52A1 #
22122
22140
  async function deleteTask(id){if(!confirm('\u786E\u5B9A\u5220\u9664\u4EFB\u52A1 #'+id+'?'))return;await fetch('/api/tasks/'+id,{method:'DELETE'});location.reload();}
22123
22141
  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');}}
22124
22142
  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');}}
22143
+ 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');}}
22125
22144
  async function enableTmpl(id){await fetch('/api/templates/'+id+'/enable',{method:'POST'});location.reload();}
22126
22145
  async function disableTmpl(id){if(!confirm('\u786E\u5B9A\u7981\u7528\u6B64\u6A21\u677F?'))return;await fetch('/api/templates/'+id+'/disable',{method:'POST'});location.reload();}
22127
22146
  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();}
@@ -22306,8 +22325,8 @@ var init_web = __esm({
22306
22325
  const st = (task.status ?? "").toUpperCase();
22307
22326
  rows += `<tr>
22308
22327
  <td class="mu">#${task.id}</td>
22309
- <td><div style="font-weight:500">${task.name}</div><div class="mu sm el">${task.prompt.substring(0, 120)}</div></td>
22310
- <td><span class="tag">${task.agent}</span></td>
22328
+ <td><div style="font-weight:500">${esc(task.name)}</div><div class="mu sm el">${esc(task.prompt.substring(0, 120))}</div></td>
22329
+ <td><span class="tag">${esc(task.agent)}</span></td>
22311
22330
  <td><span class="badge b-${task.status}">${st}</span></td>
22312
22331
  <td class="sm ${task.status === "running" ? "" : "mu"}">${formatDuration(task.startedAt, task.finishedAt)}</td>
22313
22332
  <td class="mu sm">${(task.retryCount ?? 0) > 0 ? task.retryCount : "-"}</td>
@@ -22363,15 +22382,15 @@ var init_web = __esm({
22363
22382
  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>`;
22364
22383
  rows += `<tr>
22365
22384
  <td class="mu">#${t.id}</td>
22366
- <td><div style="font-weight:500">${t.name}</div><div class="mu sm el">${t.prompt.substring(0, 100)}</div>
22367
- <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>
22385
+ <td><div style="font-weight:500">${esc(t.name)}</div><div class="mu sm el">${esc(t.prompt.substring(0, 100))}</div>
22386
+ <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>
22368
22387
  <td><span class="${typeClass}">${typeLabel}</span></td>
22369
22388
  <td class="m sm">${rule}</td>
22370
22389
  <td>${statusBadge}</td>
22371
22390
  <td class="sm">${t.lastRunAt ? timeAgo(t.lastRunAt) : "-"}</td>
22372
22391
  <td class="sm">${t.nextRunAt ? timeUntil(t.nextRunAt) : "-"}</td>
22373
22392
  <td>
22374
- <button class="btn btn-sm" onclick="showDetail(${t.id})">\u8BE6\u60C5</button>
22393
+ <button class="btn btn-sm" onclick="showTemplateDetail(${t.id})">\u8BE6\u60C5</button>
22375
22394
  <button class="btn btn-sm btn-primary" onclick="triggerTmpl(${t.id})">\u89E6\u53D1</button>
22376
22395
  ${toggleBtn}
22377
22396
  <button class="btn btn-sm btn-danger" onclick="deleteTmpl(${t.id})">\u5220\u9664</button>
@@ -22423,9 +22442,9 @@ var init_web = __esm({
22423
22442
  const logBtn = run.log ? `<button class="btn btn-sm" onclick="toggleLog(${run.id})">\u65E5\u5FD7</button>` : "";
22424
22443
  rows += `<tr>
22425
22444
  <td class="mu">#${run.id}</td>
22426
- <td><div style="font-weight:500">${run.taskName} <span class="mu">(#${run.taskId})</span></div>
22427
- ${run.model ? `<div class="sm"><span class="tag">${run.model}</span></div>` : ""}</td>
22428
- <td><span class="tag">${run.taskAgent}</span></td>
22445
+ <td><div style="font-weight:500">${esc(run.taskName)} <span class="mu">(#${run.taskId})</span></div>
22446
+ ${run.model ? `<div class="sm"><span class="tag">${esc(run.model)}</span></div>` : ""}</td>
22447
+ <td><span class="tag">${esc(run.taskAgent)}</span></td>
22429
22448
  <td><span class="badge b-${run.status}">${(run.status ?? "").toUpperCase()}</span></td>
22430
22449
  <td class="sm">${formatDuration(run.startedAt, run.finishedAt)}</td>
22431
22450
  <td class="sm mu">${run.heartbeatAt ? timeAgo(run.heartbeatAt) : "-"}</td>
@@ -22471,7 +22490,7 @@ var init_web = __esm({
22471
22490
  runRows += `<tr>
22472
22491
  <td class="mu">#${run.id}</td><td>#${run.taskId}</td>
22473
22492
  <td class="m sm">${shortS}</td>
22474
- <td class="sm">${run.model || "-"}</td>
22493
+ <td class="sm">${esc(run.model) || "-"}</td>
22475
22494
  <td class="sm">${formatDate(run.startedAt)}</td>
22476
22495
  <td class="sm">${run.heartbeatAt ? timeAgo(run.heartbeatAt) : "-"}</td>
22477
22496
  <td class="m sm">W:${run.workerPid ?? "-"} C:${run.childPid ?? "-"}</td>
@@ -22560,6 +22579,12 @@ var init_web = __esm({
22560
22579
  if (!run) return c.json({ error: "not found" }, 404);
22561
22580
  return c.json(run);
22562
22581
  });
22582
+ app.get("/api/templates/:id", async (c) => {
22583
+ const id = Number(c.req.param("id"));
22584
+ const tmpl = await TaskTemplateService.getById(id);
22585
+ if (!tmpl) return c.json({ error: "not found" }, 404);
22586
+ return c.json(tmpl);
22587
+ });
22563
22588
  app.post("/api/tasks/:id/retry", async (c) => {
22564
22589
  await TaskService.retry(Number(c.req.param("id")));
22565
22590
  return c.json({ success: true });
@@ -22709,7 +22734,11 @@ async function main() {
22709
22734
  await scheduler.start();
22710
22735
  if (cfg.dashboard.enabled) {
22711
22736
  const { dashboardApp: dashboardApp2 } = await Promise.resolve().then(() => (init_web(), web_exports));
22712
- Bun.serve({ port: cfg.dashboard.port, fetch: dashboardApp2.fetch });
22737
+ Bun.serve({
22738
+ hostname: "127.0.0.1",
22739
+ port: cfg.dashboard.port,
22740
+ fetch: dashboardApp2.fetch
22741
+ });
22713
22742
  console.log(JSON.stringify({
22714
22743
  ts: (/* @__PURE__ */ new Date()).toISOString(),
22715
22744
  level: "info",
@@ -22751,9 +22780,11 @@ async function main() {
22751
22780
  process.on("SIGINT", () => shutdown("SIGINT"));
22752
22781
  process.on("uncaughtException", (err) => {
22753
22782
  console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "uncaughtException", error: err.message, stack: err.stack }));
22783
+ process.exit(1);
22754
22784
  });
22755
22785
  process.on("unhandledRejection", (reason) => {
22756
22786
  console.error(JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), level: "fatal", msg: "unhandledRejection", reason: String(reason) }));
22787
+ process.exit(1);
22757
22788
  });
22758
22789
  }
22759
22790
  var STALE_THRESHOLD_MS;
@@ -23279,7 +23310,7 @@ program2.command("init").description("Initialize SuperTask (create config + run
23279
23310
  const dir = dirname4(CONFIG_PATH2);
23280
23311
  if (!existsSync5(dir)) mkdirSync3(dir, { recursive: true });
23281
23312
  writeFileSync3(CONFIG_PATH2, JSON.stringify({
23282
- worker: { maxConcurrency: 2, defaultModel: "zhipuai-coding-plan/glm-4.7" },
23313
+ worker: { maxConcurrency: 2 },
23283
23314
  scheduler: { enabled: true }
23284
23315
  }, null, 2) + "\n");
23285
23316
  console.log(JSON.stringify({ created: CONFIG_PATH2 }));