opencode-supertask 0.1.25 → 0.1.26
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 +14 -0
- package/dist/cli/index.js +113 -14
- package/dist/cli/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -127,6 +127,13 @@ supertask db restore --from /path/to/tasks-backup.db --confirm RESTORE [--keep-s
|
|
|
127
127
|
|
|
128
128
|
`db backup` creates and validates a standalone SQLite snapshot. For `db clear` and `db restore`, the CLI automatically stops a PM2 Gateway whose PID matches the current database's fresh ready lock, then restores its previous running state. Both commands create a safety backup before changing data and still refuse active tasks or an unverified/foreground Gateway. Use `--keep-stopped` to leave a previously running PM2 Gateway stopped.
|
|
129
129
|
|
|
130
|
+
All four `db` commands print a concise human-readable summary when stdout is an interactive terminal. Pipes, command substitution, and other non-interactive callers continue to receive JSON; pass `--json` to force JSON in a terminal:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
supertask db check --json
|
|
134
|
+
supertask db check | jq '.counts'
|
|
135
|
+
```
|
|
136
|
+
|
|
130
137
|
### Duration Format
|
|
131
138
|
|
|
132
139
|
Schedule supports friendly duration strings:
|
|
@@ -294,6 +301,13 @@ supertask db restore --from /path/to/tasks-backup.db --confirm RESTORE [--keep-s
|
|
|
294
301
|
|
|
295
302
|
`db backup` 会生成并校验可独立恢复的 SQLite 快照。CLI 清空和恢复会先确认 PM2 PID 与当前数据库的新鲜 ready 锁一致,再自动停止并按原状态重启 Gateway;操作失败时也会尝试恢复 Gateway。它们仍会拒绝运行中任务、前台 Gateway 或无法确认归属的进程,并在修改数据前自动保留安全备份。传入 `--keep-stopped` 可让原本运行的 PM2 Gateway 保持停止。
|
|
296
303
|
|
|
304
|
+
四个 `db` 命令在交互式终端默认输出简洁的人类可读摘要;管道、命令替换和其他非交互调用继续得到 JSON。终端内需要 JSON 时传入 `--json`:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
supertask db check --json
|
|
308
|
+
supertask db check | jq '.counts'
|
|
309
|
+
```
|
|
310
|
+
|
|
297
311
|
### 数据位置
|
|
298
312
|
|
|
299
313
|
- 数据库:`~/.local/share/opencode/tasks.db`
|
package/dist/cli/index.js
CHANGED
|
@@ -24297,11 +24297,108 @@ function parseDuration(input) {
|
|
|
24297
24297
|
|
|
24298
24298
|
// src/cli/index.ts
|
|
24299
24299
|
init_pm2();
|
|
24300
|
-
|
|
24300
|
+
|
|
24301
|
+
// src/cli/database-output.ts
|
|
24302
|
+
function useJson(options) {
|
|
24303
|
+
const isTTY = options.isTTY ?? process.stdout.isTTY === true;
|
|
24304
|
+
return options.forceJson === true || !isTTY;
|
|
24305
|
+
}
|
|
24306
|
+
function formatBytes(bytes) {
|
|
24307
|
+
const units = ["B", "KiB", "MiB", "GiB"];
|
|
24308
|
+
let value = bytes;
|
|
24309
|
+
let unit = 0;
|
|
24310
|
+
while (value >= 1024 && unit < units.length - 1) {
|
|
24311
|
+
value /= 1024;
|
|
24312
|
+
unit += 1;
|
|
24313
|
+
}
|
|
24314
|
+
const rendered = Number.isInteger(value) ? String(value) : value.toFixed(1);
|
|
24315
|
+
return `${rendered} ${units[unit]}`;
|
|
24316
|
+
}
|
|
24317
|
+
function formatCounts(counts) {
|
|
24318
|
+
return `\u4EFB\u52A1 ${counts.tasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${counts.taskRuns} \xB7 \u8C03\u5EA6\u6A21\u677F ${counts.taskTemplates}`;
|
|
24319
|
+
}
|
|
24320
|
+
function formatGateway(gateway) {
|
|
24321
|
+
if (gateway.restarted) return "\u5DF2\u81EA\u52A8\u505C\u6B62\u3001\u91CD\u542F\u5E76\u6062\u590D\u5C31\u7EEA";
|
|
24322
|
+
if (gateway.keptStopped) return "\u5DF2\u81EA\u52A8\u505C\u6B62\uFF0C\u6309\u8981\u6C42\u4FDD\u6301\u505C\u6B62";
|
|
24323
|
+
if (!gateway.wasRunning) return "\u65E0\u9700\u81EA\u52A8\u505C\u542F\uFF08\u672A\u53D1\u73B0\u5339\u914D\u5F53\u524D\u6570\u636E\u5E93\u7684 PM2 Gateway\uFF09";
|
|
24324
|
+
return "\u539F Gateway \u672A\u6062\u590D\u8FD0\u884C";
|
|
24325
|
+
}
|
|
24326
|
+
function formatCheck(result) {
|
|
24327
|
+
const lines = [
|
|
24328
|
+
result.ok ? "\u2713 \u6570\u636E\u5E93\u68C0\u67E5\u901A\u8FC7" : "\u2717 \u6570\u636E\u5E93\u68C0\u67E5\u672A\u901A\u8FC7",
|
|
24329
|
+
"",
|
|
24330
|
+
`\u6570\u636E\u5E93\uFF1A${result.path}`,
|
|
24331
|
+
`\u5927\u5C0F\uFF1A${formatBytes(result.sizeBytes)}`,
|
|
24332
|
+
`\u65E5\u5FD7\u6A21\u5F0F\uFF1A${result.journalMode}`,
|
|
24333
|
+
`\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(result.counts)}`,
|
|
24334
|
+
`\u8FD0\u884C\u4E2D\uFF1A\u4EFB\u52A1 ${result.runningTasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${result.runningRuns}`
|
|
24335
|
+
];
|
|
24336
|
+
if (!result.ok) {
|
|
24337
|
+
lines.push(
|
|
24338
|
+
`\u5B8C\u6574\u6027\uFF1A${result.integrityMessages.join("\uFF1B") || "\u65E0\u7ED3\u679C"}`,
|
|
24339
|
+
`\u5916\u952E\u8FDD\u89C4\uFF1A${result.foreignKeyViolations}`,
|
|
24340
|
+
`\u7F3A\u5931\u8868\uFF1A${result.missingTables.join("\u3001") || "\u65E0"}`
|
|
24341
|
+
);
|
|
24342
|
+
}
|
|
24343
|
+
return lines.join("\n");
|
|
24344
|
+
}
|
|
24345
|
+
function formatHuman(operation, result) {
|
|
24346
|
+
switch (operation) {
|
|
24347
|
+
case "check":
|
|
24348
|
+
return formatCheck(result);
|
|
24349
|
+
case "backup": {
|
|
24350
|
+
const backup = result;
|
|
24351
|
+
return [
|
|
24352
|
+
"\u2713 \u6570\u636E\u5E93\u5907\u4EFD\u5B8C\u6210",
|
|
24353
|
+
"",
|
|
24354
|
+
`\u5907\u4EFD\u6587\u4EF6\uFF1A${backup.path}`,
|
|
24355
|
+
`\u5927\u5C0F\uFF1A${formatBytes(backup.sizeBytes)}`,
|
|
24356
|
+
`\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(backup.check.counts)}`,
|
|
24357
|
+
`\u6570\u636E\u5E93\u5B8C\u6574\u6027\uFF1A${backup.check.ok ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7"}`
|
|
24358
|
+
].join("\n");
|
|
24359
|
+
}
|
|
24360
|
+
case "clear": {
|
|
24361
|
+
const cleared = result;
|
|
24362
|
+
return [
|
|
24363
|
+
"\u2713 \u6570\u636E\u5E93\u5DF2\u5B89\u5168\u6E05\u7A7A",
|
|
24364
|
+
"",
|
|
24365
|
+
`\u5DF2\u5220\u9664\uFF1A${formatCounts(cleared.deleted)}`,
|
|
24366
|
+
`\u5B89\u5168\u5907\u4EFD\uFF1A${cleared.backupPath}`,
|
|
24367
|
+
`Gateway\uFF1A${formatGateway(cleared.gateway)}`,
|
|
24368
|
+
`\u6570\u636E\u5E93\u5B8C\u6574\u6027\uFF1A${cleared.check.ok ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7"}`
|
|
24369
|
+
].join("\n");
|
|
24370
|
+
}
|
|
24371
|
+
case "restore": {
|
|
24372
|
+
const restored = result;
|
|
24373
|
+
return [
|
|
24374
|
+
"\u2713 \u6570\u636E\u5E93\u6062\u590D\u5B8C\u6210",
|
|
24375
|
+
"",
|
|
24376
|
+
`\u6062\u590D\u6765\u6E90\uFF1A${restored.sourcePath}`,
|
|
24377
|
+
`\u6062\u590D\u524D\u5B89\u5168\u5907\u4EFD\uFF1A${restored.safetyBackupPath}`,
|
|
24378
|
+
`\u8FD0\u884C\u6001\u6536\u655B\uFF1A\u4EFB\u52A1 ${restored.recoveredRunningTasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${restored.closedRunningRuns}`,
|
|
24379
|
+
`\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(restored.check.counts)}`,
|
|
24380
|
+
`Gateway\uFF1A${formatGateway(restored.gateway)}`,
|
|
24381
|
+
`\u6570\u636E\u5E93\u5B8C\u6574\u6027\uFF1A${restored.check.ok ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7"}`
|
|
24382
|
+
].join("\n");
|
|
24383
|
+
}
|
|
24384
|
+
}
|
|
24385
|
+
}
|
|
24386
|
+
function renderDatabaseResult(operation, result, options = {}) {
|
|
24387
|
+
return useJson(options) ? JSON.stringify(result, null, 2) : formatHuman(operation, result);
|
|
24388
|
+
}
|
|
24389
|
+
function renderDatabaseError(error, options = {}) {
|
|
24390
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
24391
|
+
return useJson(options) ? JSON.stringify({ error: message }) : `\u2717 ${message}`;
|
|
24392
|
+
}
|
|
24393
|
+
|
|
24394
|
+
// src/cli/index.ts
|
|
24395
|
+
async function withDb(fn, formatError = (error) => JSON.stringify({
|
|
24396
|
+
error: error instanceof Error ? error.message : String(error)
|
|
24397
|
+
})) {
|
|
24301
24398
|
try {
|
|
24302
24399
|
return await fn();
|
|
24303
24400
|
} catch (error) {
|
|
24304
|
-
console.error(
|
|
24401
|
+
console.error(formatError(error));
|
|
24305
24402
|
closeDb();
|
|
24306
24403
|
process.exit(1);
|
|
24307
24404
|
} finally {
|
|
@@ -24550,13 +24647,15 @@ program2.command("template").description("\u7BA1\u7406\u4EFB\u52A1\u8C03\u5EA6\u
|
|
|
24550
24647
|
}))
|
|
24551
24648
|
);
|
|
24552
24649
|
var databaseCommand = new Command("db").description("\u6570\u636E\u5E93\u68C0\u67E5\u3001\u5907\u4EFD\u3001\u6E05\u7A7A\u4E0E\u6062\u590D");
|
|
24553
|
-
databaseCommand.command("check").description("\u68C0\u67E5\u6570\u636E\u5E93\u5B8C\u6574\u6027\u3001\u5916\u952E\u548C\u4E1A\u52A1\u8868\u7EDF\u8BA1").action(async () => withDb(async () => {
|
|
24554
|
-
|
|
24555
|
-
}));
|
|
24556
|
-
|
|
24557
|
-
|
|
24558
|
-
|
|
24559
|
-
|
|
24650
|
+
databaseCommand.command("check").description("\u68C0\u67E5\u6570\u636E\u5E93\u5B8C\u6574\u6027\u3001\u5916\u952E\u548C\u4E1A\u52A1\u8868\u7EDF\u8BA1").option("--json", "\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09").action(async (options) => withDb(async () => {
|
|
24651
|
+
const result = DatabaseMaintenanceService.check();
|
|
24652
|
+
console.log(renderDatabaseResult("check", result, { forceJson: options.json }));
|
|
24653
|
+
}, (error) => renderDatabaseError(error, { forceJson: options.json })));
|
|
24654
|
+
databaseCommand.command("backup").description("\u521B\u5EFA\u7ECF\u8FC7\u5B8C\u6574\u6027\u6821\u9A8C\u7684\u4E00\u81F4\u6027\u5907\u4EFD").option("-o, --output <path>", "\u5907\u4EFD\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5199\u5165\u6570\u636E\u5E93\u76EE\u5F55\uFF09").option("--json", "\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09").action(async (options) => withDb(async () => {
|
|
24655
|
+
const result = DatabaseMaintenanceService.backup(options.output);
|
|
24656
|
+
console.log(renderDatabaseResult("backup", result, { forceJson: options.json }));
|
|
24657
|
+
}, (error) => renderDatabaseError(error, { forceJson: options.json })));
|
|
24658
|
+
databaseCommand.command("clear").description("\u5907\u4EFD\u540E\u4E8B\u52A1\u6027\u6E05\u7A7A\u4EFB\u52A1\u3001\u6267\u884C\u8BB0\u5F55\u548C\u8C03\u5EA6\u6A21\u677F").option("--confirm <word>", "\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 CLEAR").option("--keep-stopped", "\u7EF4\u62A4\u7ED3\u675F\u540E\u4E0D\u91CD\u542F\u539F\u672C\u7531 PM2 \u7BA1\u7406\u7684 Gateway").option("--json", "\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09").action(async (options) => withDb(async () => {
|
|
24560
24659
|
if (options.confirm !== "CLEAR") {
|
|
24561
24660
|
throw new Error("\u6E05\u7A7A\u6570\u636E\u5E93\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --confirm CLEAR");
|
|
24562
24661
|
}
|
|
@@ -24564,9 +24663,9 @@ databaseCommand.command("clear").description("\u5907\u4EFD\u540E\u4E8B\u52A1\u60
|
|
|
24564
24663
|
options.keepStopped ?? false,
|
|
24565
24664
|
() => DatabaseMaintenanceService.clear()
|
|
24566
24665
|
);
|
|
24567
|
-
console.log(
|
|
24568
|
-
}));
|
|
24569
|
-
databaseCommand.command("restore").description("\u81EA\u52A8\u5907\u4EFD\u5F53\u524D\u5E93\u540E\uFF0C\u4ECE\u6307\u5B9A\u5907\u4EFD\u6062\u590D\u6570\u636E\u5E93").requiredOption("--from <path>", "\u8981\u6062\u590D\u7684 SQLite \u5907\u4EFD\u6587\u4EF6").option("--confirm <word>", "\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 RESTORE").option("--keep-stopped", "\u7EF4\u62A4\u7ED3\u675F\u540E\u4E0D\u91CD\u542F\u539F\u672C\u7531 PM2 \u7BA1\u7406\u7684 Gateway").action(async (options) => withDb(async () => {
|
|
24666
|
+
console.log(renderDatabaseResult("clear", result, { forceJson: options.json }));
|
|
24667
|
+
}, (error) => renderDatabaseError(error, { forceJson: options.json })));
|
|
24668
|
+
databaseCommand.command("restore").description("\u81EA\u52A8\u5907\u4EFD\u5F53\u524D\u5E93\u540E\uFF0C\u4ECE\u6307\u5B9A\u5907\u4EFD\u6062\u590D\u6570\u636E\u5E93").requiredOption("--from <path>", "\u8981\u6062\u590D\u7684 SQLite \u5907\u4EFD\u6587\u4EF6").option("--confirm <word>", "\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 RESTORE").option("--keep-stopped", "\u7EF4\u62A4\u7ED3\u675F\u540E\u4E0D\u91CD\u542F\u539F\u672C\u7531 PM2 \u7BA1\u7406\u7684 Gateway").option("--json", "\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09").action(async (options) => withDb(async () => {
|
|
24570
24669
|
if (options.confirm !== "RESTORE") {
|
|
24571
24670
|
throw new Error("\u6062\u590D\u6570\u636E\u5E93\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --confirm RESTORE");
|
|
24572
24671
|
}
|
|
@@ -24574,8 +24673,8 @@ databaseCommand.command("restore").description("\u81EA\u52A8\u5907\u4EFD\u5F53\u
|
|
|
24574
24673
|
options.keepStopped ?? false,
|
|
24575
24674
|
() => DatabaseMaintenanceService.restore(options.from)
|
|
24576
24675
|
);
|
|
24577
|
-
console.log(
|
|
24578
|
-
}));
|
|
24676
|
+
console.log(renderDatabaseResult("restore", result, { forceJson: options.json }));
|
|
24677
|
+
}, (error) => renderDatabaseError(error, { forceJson: options.json })));
|
|
24579
24678
|
program2.addCommand(databaseCommand);
|
|
24580
24679
|
program2.command("init").description("Initialize SuperTask (create config + run migrations)").action(async () => withDb(async () => {
|
|
24581
24680
|
const { existsSync: existsSync7, mkdirSync: mkdirSync5, writeFileSync: writeFileSync4 } = await import("fs");
|