opencode-supertask 0.1.35 → 0.1.36
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/CHANGELOG.md +15 -0
- package/README.md +7 -4
- package/dist/cli/index.js +410 -51
- package/dist/cli/index.js.map +1 -1
- package/dist/gateway/index.js +238 -28
- package/dist/gateway/index.js.map +1 -1
- package/dist/plugin/supertask.js +30 -0
- package/dist/plugin/supertask.js.map +1 -1
- package/dist/web/index.d.ts +7 -0
- package/dist/web/index.js +238 -28
- package/dist/web/index.js.map +1 -1
- package/package.json +1 -1
package/dist/web/index.d.ts
CHANGED
|
@@ -26,6 +26,13 @@ interface GatewayDiagnostic {
|
|
|
26
26
|
currentScope: RuntimeScope;
|
|
27
27
|
gatewayScope: RuntimeScope | null;
|
|
28
28
|
scopeMatches: boolean;
|
|
29
|
+
gatewayOpenCode: OpenCodeRuntimeDiagnostic | null;
|
|
30
|
+
}
|
|
31
|
+
interface OpenCodeRuntimeDiagnostic {
|
|
32
|
+
ok: boolean;
|
|
33
|
+
executable: string;
|
|
34
|
+
version: string | null;
|
|
35
|
+
error: string | null;
|
|
29
36
|
}
|
|
30
37
|
|
|
31
38
|
declare function setDashboardRuntimeConfig(config: GatewayConfig | null): void;
|
package/dist/web/index.js
CHANGED
|
@@ -18800,7 +18800,27 @@ function scopesMatch(left, right) {
|
|
|
18800
18800
|
function currentScope() {
|
|
18801
18801
|
return runtimeScope({ cwd: process.cwd(), env: process.env });
|
|
18802
18802
|
}
|
|
18803
|
-
function
|
|
18803
|
+
function diagnoseOpenCodeRuntime(runtime = {
|
|
18804
|
+
cwd: process.cwd(),
|
|
18805
|
+
env: process.env
|
|
18806
|
+
}) {
|
|
18807
|
+
const executable = runtimeScope(runtime).opencodePath;
|
|
18808
|
+
const result = spawnSync(executable, ["--version"], {
|
|
18809
|
+
cwd: runtime.cwd,
|
|
18810
|
+
env: runtime.env,
|
|
18811
|
+
encoding: "utf8",
|
|
18812
|
+
timeout: 1e4,
|
|
18813
|
+
killSignal: "SIGKILL"
|
|
18814
|
+
});
|
|
18815
|
+
const ok = result.status === 0 && result.error === void 0;
|
|
18816
|
+
return {
|
|
18817
|
+
ok,
|
|
18818
|
+
executable,
|
|
18819
|
+
version: ok ? result.stdout.trim() || result.stderr.trim() || null : null,
|
|
18820
|
+
error: ok ? null : result.error?.message || result.stderr.trim() || result.stdout.trim() || `exit code ${result.status}`
|
|
18821
|
+
};
|
|
18822
|
+
}
|
|
18823
|
+
function getGatewayDiagnostic(options = {}) {
|
|
18804
18824
|
const producerScope = currentScope();
|
|
18805
18825
|
if (!isPm2Installed()) {
|
|
18806
18826
|
return {
|
|
@@ -18816,7 +18836,8 @@ function getGatewayDiagnostic() {
|
|
|
18816
18836
|
startupConfigured: process.platform === "darwin" || process.platform === "linux" ? false : null,
|
|
18817
18837
|
currentScope: producerScope,
|
|
18818
18838
|
gatewayScope: null,
|
|
18819
|
-
scopeMatches: false
|
|
18839
|
+
scopeMatches: false,
|
|
18840
|
+
gatewayOpenCode: null
|
|
18820
18841
|
};
|
|
18821
18842
|
}
|
|
18822
18843
|
const processes = pm2JsonList();
|
|
@@ -18844,7 +18865,8 @@ function getGatewayDiagnostic() {
|
|
|
18844
18865
|
) : process.platform === "linux" ? isLinuxStartupConfigured(gatewayEnv, runtime?.cwd, runtime ?? void 0) : null,
|
|
18845
18866
|
currentScope: producerScope,
|
|
18846
18867
|
gatewayScope: managedScope,
|
|
18847
|
-
scopeMatches: managedScope != null && scopesMatch(producerScope, managedScope)
|
|
18868
|
+
scopeMatches: managedScope != null && scopesMatch(producerScope, managedScope),
|
|
18869
|
+
gatewayOpenCode: runtime === null || !options.probeOpenCode ? null : diagnoseOpenCodeRuntime(runtime)
|
|
18848
18870
|
};
|
|
18849
18871
|
}
|
|
18850
18872
|
function pm2Bin(env = process.env) {
|
|
@@ -19163,7 +19185,7 @@ var ZH = {
|
|
|
19163
19185
|
"action.hideLogs": "\u6536\u8D77\u65E5\u5FD7",
|
|
19164
19186
|
"action.save": "\u4FDD\u5B58\u8BBE\u7F6E",
|
|
19165
19187
|
"action.saveAndRestart": "\u4FDD\u5B58\u5E76\u91CD\u542F",
|
|
19166
|
-
"action.copy": "\u590D\u5236
|
|
19188
|
+
"action.copy": "\u590D\u5236\u539F\u59CB\u6570\u636E",
|
|
19167
19189
|
"action.close": "\u5173\u95ED",
|
|
19168
19190
|
"action.confirm": "\u786E\u8BA4",
|
|
19169
19191
|
"action.clearDatabase": "\u6E05\u7A7A\u6570\u636E\u5E93",
|
|
@@ -19355,9 +19377,46 @@ var ZH = {
|
|
|
19355
19377
|
"theme.light": "\u6D45\u8272",
|
|
19356
19378
|
"theme.dark": "\u6DF1\u8272",
|
|
19357
19379
|
"language.label": "\u8BED\u8A00",
|
|
19358
|
-
"details.title": "\
|
|
19359
|
-
"details.subtitle": "\u539F\u59CB\
|
|
19360
|
-
"details.
|
|
19380
|
+
"details.title": "\u8BE6\u60C5",
|
|
19381
|
+
"details.subtitle": "\u91CD\u70B9\u4FE1\u606F\u5DF2\u6574\u7406\uFF1B\u539F\u59CB\u6570\u636E\u4EC5\u7528\u4E8E\u6392\u969C\u3002",
|
|
19382
|
+
"details.taskTitle": "\u4EFB\u52A1\u8BE6\u60C5",
|
|
19383
|
+
"details.runTitle": "\u6267\u884C\u8BE6\u60C5",
|
|
19384
|
+
"details.templateTitle": "\u5B9A\u65F6\u4EFB\u52A1\u8BE6\u60C5",
|
|
19385
|
+
"details.raw": "\u67E5\u770B\u539F\u59CB\u6570\u636E\uFF08JSON\uFF09",
|
|
19386
|
+
"details.copySuccess": "\u539F\u59CB\u6570\u636E\u5DF2\u590D\u5236",
|
|
19387
|
+
"details.id": "\u7F16\u53F7",
|
|
19388
|
+
"details.project": "\u9879\u76EE\u76EE\u5F55",
|
|
19389
|
+
"details.prompt": "\u63D0\u793A\u8BCD",
|
|
19390
|
+
"details.result": "\u6267\u884C\u7ED3\u679C / \u5931\u8D25\u539F\u56E0",
|
|
19391
|
+
"details.category": "\u5206\u7C7B",
|
|
19392
|
+
"details.batch": "\u6279\u6B21",
|
|
19393
|
+
"details.dependency": "\u4F9D\u8D56\u4EFB\u52A1",
|
|
19394
|
+
"details.importance": "\u91CD\u8981\u7A0B\u5EA6",
|
|
19395
|
+
"details.urgency": "\u7D27\u6025\u7A0B\u5EA6",
|
|
19396
|
+
"details.retryCount": "\u5DF2\u91CD\u8BD5 / \u6700\u591A\u91CD\u8BD5",
|
|
19397
|
+
"details.retryBackoff": "\u91CD\u8BD5\u7B49\u5F85",
|
|
19398
|
+
"details.timeout": "\u6267\u884C\u8D85\u65F6",
|
|
19399
|
+
"details.createdAt": "\u521B\u5EFA\u65F6\u95F4",
|
|
19400
|
+
"details.updatedAt": "\u66F4\u65B0\u65F6\u95F4",
|
|
19401
|
+
"details.startedAt": "\u5F00\u59CB\u65F6\u95F4",
|
|
19402
|
+
"details.finishedAt": "\u7ED3\u675F\u65F6\u95F4",
|
|
19403
|
+
"details.scheduledAt": "\u8BA1\u5212\u65F6\u95F4",
|
|
19404
|
+
"details.enabled": "\u81EA\u52A8\u8FD0\u884C",
|
|
19405
|
+
"details.scheduleRule": "\u8FD0\u884C\u89C4\u5219",
|
|
19406
|
+
"details.maxInstances": "\u81EA\u52A8\u8C03\u5EA6\u4E0A\u9650",
|
|
19407
|
+
"details.maxRetries": "\u5931\u8D25\u91CD\u8BD5\u6B21\u6570",
|
|
19408
|
+
"details.lastRun": "\u4E0A\u6B21\u8FD0\u884C",
|
|
19409
|
+
"details.nextRun": "\u4E0B\u6B21\u8FD0\u884C",
|
|
19410
|
+
"details.taskId": "\u6240\u5C5E\u4EFB\u52A1",
|
|
19411
|
+
"details.session": "OpenCode \u4F1A\u8BDD",
|
|
19412
|
+
"details.heartbeat": "\u6700\u8FD1\u5FC3\u8DF3",
|
|
19413
|
+
"details.process": "\u8FDB\u7A0B",
|
|
19414
|
+
"details.history": "\u6267\u884C\u5386\u53F2",
|
|
19415
|
+
"details.noHistory": "\u8FD8\u6CA1\u6709\u6267\u884C\u8BB0\u5F55",
|
|
19416
|
+
"details.none": "\u65E0",
|
|
19417
|
+
"details.default": "\u8DDF\u968F\u7CFB\u7EDF\u9ED8\u8BA4",
|
|
19418
|
+
"details.enabledYes": "\u5DF2\u542F\u7528",
|
|
19419
|
+
"details.enabledNo": "\u5DF2\u505C\u7528",
|
|
19361
19420
|
"dialog.cancelTask": "\u53D6\u6D88\u4EFB\u52A1 #{id}\uFF1F",
|
|
19362
19421
|
"dialog.cancelTaskBody": "\u8FD0\u884C\u4E2D\u7684\u4EFB\u52A1\u4F1A\u5728\u4E0B\u4E00\u4E2A\u8F6E\u8BE2\u5468\u671F\u7EC8\u6B62\u5BF9\u5E94\u8FDB\u7A0B\u6811\u3002",
|
|
19363
19422
|
"dialog.retryTask": "\u91CD\u8BD5\u4EFB\u52A1 #{id}\uFF1F",
|
|
@@ -19427,7 +19486,7 @@ var EN = {
|
|
|
19427
19486
|
"action.hideLogs": "Hide log",
|
|
19428
19487
|
"action.save": "Save settings",
|
|
19429
19488
|
"action.saveAndRestart": "Save and restart",
|
|
19430
|
-
"action.copy": "Copy
|
|
19489
|
+
"action.copy": "Copy raw data",
|
|
19431
19490
|
"action.close": "Close",
|
|
19432
19491
|
"action.confirm": "Confirm",
|
|
19433
19492
|
"action.clearDatabase": "Clear database",
|
|
@@ -19619,9 +19678,46 @@ var EN = {
|
|
|
19619
19678
|
"theme.light": "Light",
|
|
19620
19679
|
"theme.dark": "Dark",
|
|
19621
19680
|
"language.label": "Language",
|
|
19622
|
-
"details.title": "
|
|
19623
|
-
"details.subtitle": "
|
|
19624
|
-
"details.
|
|
19681
|
+
"details.title": "Details",
|
|
19682
|
+
"details.subtitle": "Key information is organized below; raw data is only for troubleshooting.",
|
|
19683
|
+
"details.taskTitle": "Task details",
|
|
19684
|
+
"details.runTitle": "Run details",
|
|
19685
|
+
"details.templateTitle": "Scheduled task details",
|
|
19686
|
+
"details.raw": "View raw data (JSON)",
|
|
19687
|
+
"details.copySuccess": "Raw data copied",
|
|
19688
|
+
"details.id": "ID",
|
|
19689
|
+
"details.project": "Project directory",
|
|
19690
|
+
"details.prompt": "Prompt",
|
|
19691
|
+
"details.result": "Result / failure reason",
|
|
19692
|
+
"details.category": "Category",
|
|
19693
|
+
"details.batch": "Batch",
|
|
19694
|
+
"details.dependency": "Dependency",
|
|
19695
|
+
"details.importance": "Importance",
|
|
19696
|
+
"details.urgency": "Urgency",
|
|
19697
|
+
"details.retryCount": "Retries used / allowed",
|
|
19698
|
+
"details.retryBackoff": "Retry delay",
|
|
19699
|
+
"details.timeout": "Run timeout",
|
|
19700
|
+
"details.createdAt": "Created",
|
|
19701
|
+
"details.updatedAt": "Updated",
|
|
19702
|
+
"details.startedAt": "Started",
|
|
19703
|
+
"details.finishedAt": "Finished",
|
|
19704
|
+
"details.scheduledAt": "Scheduled for",
|
|
19705
|
+
"details.enabled": "Automatic runs",
|
|
19706
|
+
"details.scheduleRule": "Schedule rule",
|
|
19707
|
+
"details.maxInstances": "Automatic scheduling limit",
|
|
19708
|
+
"details.maxRetries": "Failure retries",
|
|
19709
|
+
"details.lastRun": "Last run",
|
|
19710
|
+
"details.nextRun": "Next run",
|
|
19711
|
+
"details.taskId": "Task",
|
|
19712
|
+
"details.session": "OpenCode session",
|
|
19713
|
+
"details.heartbeat": "Latest heartbeat",
|
|
19714
|
+
"details.process": "Processes",
|
|
19715
|
+
"details.history": "Run history",
|
|
19716
|
+
"details.noHistory": "No runs yet",
|
|
19717
|
+
"details.none": "None",
|
|
19718
|
+
"details.default": "Use system default",
|
|
19719
|
+
"details.enabledYes": "Enabled",
|
|
19720
|
+
"details.enabledNo": "Disabled",
|
|
19625
19721
|
"dialog.cancelTask": "Cancel task #{id}?",
|
|
19626
19722
|
"dialog.cancelTaskBody": "A running task will terminate its process tree on the next worker poll.",
|
|
19627
19723
|
"dialog.retryTask": "Retry task #{id}?",
|
|
@@ -19929,6 +20025,8 @@ var STYLES = `
|
|
|
19929
20025
|
.danger-card h2 .icon { width:17px; height:17px; }
|
|
19930
20026
|
.danger-card p { max-width:800px; margin:0 0 14px; color:var(--text-2); font-size:12px; }
|
|
19931
20027
|
.log-panel { margin:12px 0; animation:reveal .18s ease both; }
|
|
20028
|
+
.run-log-row td { padding:0 16px 16px; background:color-mix(in srgb,var(--surface-2) 64%,var(--surface)); }
|
|
20029
|
+
.run-log-row .log-panel { margin:0; box-shadow:none; }
|
|
19932
20030
|
.log-content { display:grid; gap:14px; padding:16px; }
|
|
19933
20031
|
.log-section-head { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:7px; }
|
|
19934
20032
|
.run-command,.run-output,.run-error,.run-tools { min-width:0; }
|
|
@@ -19986,8 +20084,21 @@ var STYLES = `
|
|
|
19986
20084
|
.directory-item:active { transform:scale(.99); }
|
|
19987
20085
|
.directory-item .icon { width:17px; height:17px; color:var(--primary); flex:0 0 auto; }
|
|
19988
20086
|
.directory-empty { min-height:220px; display:grid; place-items:center; color:var(--text-3); }
|
|
19989
|
-
.
|
|
19990
|
-
|
|
20087
|
+
.detail-view { display:grid; gap:16px; }
|
|
20088
|
+
.detail-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
|
|
20089
|
+
.detail-item { min-width:0; padding:12px 13px; border:1px solid var(--border); border-radius:10px; background:var(--surface-2); }
|
|
20090
|
+
.detail-item.wide { grid-column:1 / -1; }
|
|
20091
|
+
.detail-label { margin-bottom:5px; color:var(--text-3); font-size:10px; font-weight:750; letter-spacing:.045em; text-transform:uppercase; }
|
|
20092
|
+
.detail-value { color:var(--text); font-size:13px; line-height:1.55; overflow-wrap:anywhere; }
|
|
20093
|
+
.detail-value.mono { font-family:"SFMono-Regular",Consolas,monospace; font-size:11px; }
|
|
20094
|
+
.detail-value.long { max-height:240px; margin:0; overflow:auto; white-space:pre-wrap; }
|
|
20095
|
+
.detail-history h3 { margin:0 0 8px; font-size:13px; }
|
|
20096
|
+
.detail-history-list { display:grid; gap:7px; }
|
|
20097
|
+
.detail-history-item { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:9px 11px; border:1px solid var(--border); border-radius:9px; background:var(--surface-2); font-size:11px; }
|
|
20098
|
+
.detail-raw { padding-top:12px; border-top:1px solid var(--border); }
|
|
20099
|
+
.detail-raw summary { color:var(--text-2); cursor:pointer; font-size:12px; font-weight:650; }
|
|
20100
|
+
.json-view { max-height:320px; margin:10px 0 0; padding:15px; overflow:auto; border:1px solid var(--border); border-radius:10px; color:var(--text-2);
|
|
20101
|
+
background:var(--surface-2); font-family:"SFMono-Regular",Consolas,monospace; font-size:11px; white-space:pre-wrap; overflow-wrap:anywhere; }
|
|
19991
20102
|
.confirm-copy { color:var(--text-2); margin:0; }
|
|
19992
20103
|
.confirm-copy strong { display:block; margin-bottom:5px; color:var(--text); font-size:15px; }
|
|
19993
20104
|
.danger-input { width:100%; height:40px; margin-top:14px; padding:0 12px; border:1px solid var(--border); border-radius:9px; outline:none;
|
|
@@ -20051,8 +20162,13 @@ var STYLES = `
|
|
|
20051
20162
|
.responsive-table td[data-primary]::before { display:none; }
|
|
20052
20163
|
.responsive-table .task-prompt { max-width:100%; }
|
|
20053
20164
|
.responsive-table .actions { justify-content:flex-start; }
|
|
20165
|
+
.responsive-table .run-log-row { padding:0; overflow:hidden; }
|
|
20166
|
+
.responsive-table .run-log-cell { display:block; padding:0; }
|
|
20167
|
+
.responsive-table .run-log-cell::before { display:none; }
|
|
20054
20168
|
.project-grid { grid-template-columns:1fr; }
|
|
20055
20169
|
.template-form-grid { grid-template-columns:1fr; }
|
|
20170
|
+
.detail-grid { grid-template-columns:1fr; }
|
|
20171
|
+
.detail-item.wide { grid-column:auto; }
|
|
20056
20172
|
.form-field-wide { grid-column:auto; }
|
|
20057
20173
|
.field-action { align-items:stretch; flex-direction:column; }
|
|
20058
20174
|
.field-action .btn { width:100%; }
|
|
@@ -20086,7 +20202,70 @@ function clientMessages(locale) {
|
|
|
20086
20202
|
"action.refresh",
|
|
20087
20203
|
"action.logs",
|
|
20088
20204
|
"action.hideLogs",
|
|
20205
|
+
"details.title",
|
|
20206
|
+
"details.subtitle",
|
|
20207
|
+
"details.taskTitle",
|
|
20208
|
+
"details.runTitle",
|
|
20209
|
+
"details.templateTitle",
|
|
20210
|
+
"details.raw",
|
|
20089
20211
|
"details.copySuccess",
|
|
20212
|
+
"details.id",
|
|
20213
|
+
"details.project",
|
|
20214
|
+
"details.prompt",
|
|
20215
|
+
"details.result",
|
|
20216
|
+
"details.category",
|
|
20217
|
+
"details.batch",
|
|
20218
|
+
"details.dependency",
|
|
20219
|
+
"details.importance",
|
|
20220
|
+
"details.urgency",
|
|
20221
|
+
"details.retryCount",
|
|
20222
|
+
"details.retryBackoff",
|
|
20223
|
+
"details.timeout",
|
|
20224
|
+
"details.createdAt",
|
|
20225
|
+
"details.updatedAt",
|
|
20226
|
+
"details.startedAt",
|
|
20227
|
+
"details.finishedAt",
|
|
20228
|
+
"details.scheduledAt",
|
|
20229
|
+
"details.enabled",
|
|
20230
|
+
"details.scheduleRule",
|
|
20231
|
+
"details.maxInstances",
|
|
20232
|
+
"details.maxRetries",
|
|
20233
|
+
"details.lastRun",
|
|
20234
|
+
"details.nextRun",
|
|
20235
|
+
"details.taskId",
|
|
20236
|
+
"details.session",
|
|
20237
|
+
"details.heartbeat",
|
|
20238
|
+
"details.process",
|
|
20239
|
+
"details.history",
|
|
20240
|
+
"details.noHistory",
|
|
20241
|
+
"details.none",
|
|
20242
|
+
"details.default",
|
|
20243
|
+
"details.enabledYes",
|
|
20244
|
+
"details.enabledNo",
|
|
20245
|
+
"table.name",
|
|
20246
|
+
"table.agent",
|
|
20247
|
+
"table.model",
|
|
20248
|
+
"table.status",
|
|
20249
|
+
"table.duration",
|
|
20250
|
+
"template.scheduleType",
|
|
20251
|
+
"status.pending",
|
|
20252
|
+
"status.running",
|
|
20253
|
+
"status.done",
|
|
20254
|
+
"status.failed",
|
|
20255
|
+
"status.dead_letter",
|
|
20256
|
+
"status.cancelled",
|
|
20257
|
+
"status.unknown",
|
|
20258
|
+
"runStatus.running",
|
|
20259
|
+
"runStatus.done",
|
|
20260
|
+
"runStatus.failed",
|
|
20261
|
+
"schedule.cron",
|
|
20262
|
+
"schedule.recurring",
|
|
20263
|
+
"schedule.delayed",
|
|
20264
|
+
"schedule.unknown",
|
|
20265
|
+
"duration.seconds",
|
|
20266
|
+
"duration.minutes",
|
|
20267
|
+
"duration.hours",
|
|
20268
|
+
"duration.days",
|
|
20090
20269
|
"feedback.copyFailed",
|
|
20091
20270
|
"dialog.cancelTask",
|
|
20092
20271
|
"dialog.cancelTaskBody",
|
|
@@ -20215,8 +20394,8 @@ function renderLayout(options) {
|
|
|
20215
20394
|
<div class="dialog-actions"><button type="button" class="btn" onclick="document.getElementById('directory-dialog').close()">${t(locale, "action.cancel")}</button><button id="directory-choose" type="button" class="btn btn-primary">${icon("folder")}${t(locale, "action.chooseThisFolder")}</button></div>
|
|
20216
20395
|
</dialog>
|
|
20217
20396
|
<dialog id="detail-dialog">
|
|
20218
|
-
<div class="dialog-head"><div><h2>${t(locale, "details.title")}</h2><p>${t(locale, "details.subtitle")}</p></div><button class="icon-button" onclick="document.getElementById('detail-dialog').close()" aria-label="${t(locale, "action.close")}">${icon("close")}</button></div>
|
|
20219
|
-
<div class="dialog-body"><
|
|
20397
|
+
<div class="dialog-head"><div><h2 id="detail-title">${t(locale, "details.title")}</h2><p>${t(locale, "details.subtitle")}</p></div><button class="icon-button" onclick="document.getElementById('detail-dialog').close()" aria-label="${t(locale, "action.close")}">${icon("close")}</button></div>
|
|
20398
|
+
<div class="dialog-body"><div id="detail-content" class="detail-view"></div><details class="detail-raw"><summary>${t(locale, "details.raw")}</summary><pre id="detail-raw" class="json-view"></pre></details></div>
|
|
20220
20399
|
<div class="dialog-actions"><button class="btn" onclick="copyDetails()">${icon("copy")}${t(locale, "action.copy")}</button><button class="btn btn-primary" onclick="document.getElementById('detail-dialog').close()">${t(locale, "action.close")}</button></div>
|
|
20221
20400
|
</dialog>
|
|
20222
20401
|
<dialog id="confirm-dialog">
|
|
@@ -20248,9 +20427,39 @@ function renderLayout(options) {
|
|
|
20248
20427
|
async function retryTask(id){if(!await ask(text('dialog.retryTask',{id}),text('dialog.retryTaskBody')))return;try{await readJson(await fetch('/api/tasks/'+id+'/retry',{method:'POST'}));location.reload()}catch(error){showToast(text('feedback.retryFailed')+': '+error.message,'error')}}
|
|
20249
20428
|
async function cancelTask(id){if(!await ask(text('dialog.cancelTask',{id}),text('dialog.cancelTaskBody'),true))return;try{await readJson(await fetch('/api/tasks/'+id+'/cancel',{method:'POST'}));location.reload()}catch(error){showToast(text('feedback.cancelFailed')+': '+error.message,'error')}}
|
|
20250
20429
|
async function deleteTask(id){if(!await ask(text('dialog.deleteTask',{id}),text('dialog.deleteTaskBody'),true))return;try{await readJson(await fetch('/api/tasks/'+id,{method:'DELETE'}));location.reload()}catch(error){showToast(text('feedback.deleteFailed')+': '+error.message,'error')}}
|
|
20251
|
-
|
|
20252
|
-
const
|
|
20253
|
-
|
|
20430
|
+
function detailDate(value){if(value===null||value===undefined||value==='')return text('details.none');const epoch=typeof value==='number'&&value<100000000000?value*1000:value;const date=new Date(epoch);return Number.isNaN(date.getTime())?String(value):date.toLocaleString(document.documentElement.lang)}
|
|
20431
|
+
function detailDuration(value){if(value===null||value===undefined)return text('details.default');const milliseconds=Number(value);if(!Number.isFinite(milliseconds))return String(value);if(milliseconds===0)return '0 ms';const units=[[86400000,text('duration.days')],[3600000,text('duration.hours')],[60000,text('duration.minutes')],[1000,text('duration.seconds')]];for(const [size,label] of units){if(milliseconds>=size&&milliseconds%size===0)return String(milliseconds/size)+' '+label}return String(milliseconds)+' ms'}
|
|
20432
|
+
function detailStatus(type,value){const prefix=type==='run'?'runStatus.':'status.';const key=prefix+String(value||'unknown');return Object.prototype.hasOwnProperty.call(UI,key)?text(key):text('status.unknown')}
|
|
20433
|
+
function detailScheduleType(value){const key='schedule.'+String(value||'unknown');return Object.prototype.hasOwnProperty.call(UI,key)?text(key):text('schedule.unknown')}
|
|
20434
|
+
function detailModel(value){return !value||value==='default'?text('details.default'):String(value)}
|
|
20435
|
+
function detailSession(value){if(!value)return text('details.none');const session=String(value);return session.length<=10?session:session.slice(0,6)+'***'+session.slice(-4)}
|
|
20436
|
+
function detailTaskResult(data){const presentation=data._resultPresentation;if(!presentation)return text('details.none');const parts=[];if(Array.isArray(presentation.errors)&&presentation.errors.length)parts.push(presentation.errors.join('\\n'));if(presentation.text)parts.push(presentation.text);return parts.join('\\n\\n')||text('details.none')}
|
|
20437
|
+
function detailField(label,value,options={}){const item=document.createElement('div');item.className='detail-item'+(options.wide?' wide':'');const name=document.createElement('div');name.className='detail-label';name.textContent=label;const content=options.long?document.createElement('pre'):document.createElement('div');content.className='detail-value'+(options.mono?' mono':'')+(options.long?' long':'');content.textContent=value===null||value===undefined||value===''?text('details.none'):String(value);item.append(name,content);return item}
|
|
20438
|
+
function renderDetailHistory(runs){const section=document.createElement('section');section.className='detail-history';const title=document.createElement('h3');title.textContent=text('details.history');section.appendChild(title);if(!Array.isArray(runs)||runs.length===0){const empty=document.createElement('div');empty.className='muted small';empty.textContent=text('details.noHistory');section.appendChild(empty);return section}const list=document.createElement('div');list.className='detail-history-list';for(const run of runs){const item=document.createElement('div');item.className='detail-history-item';const primary=document.createElement('strong');primary.textContent='Run #'+run.id+' \xB7 '+detailStatus('run',run.status);const secondary=document.createElement('span');secondary.className='muted';secondary.textContent=detailDate(run.startedAt)+(run.model?' \xB7 '+detailModel(run.model):'');item.append(primary,secondary);list.appendChild(item)}section.appendChild(list);return section}
|
|
20439
|
+
function detailFields(type,data){if(type==='task')return [
|
|
20440
|
+
[text('details.id'),'#'+data.id],[text('table.name'),data.name],[text('table.status'),detailStatus('task',data.status)],[text('details.project'),data.cwd,{wide:true,mono:true}],
|
|
20441
|
+
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
20442
|
+
[text('details.category'),data.category],[text('details.batch'),data.batchId],[text('details.dependency'),data.dependsOn?'#'+data.dependsOn:text('details.none')],
|
|
20443
|
+
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.retryCount'),String(data.retryCount??0)+' / '+String(data.maxRetries??0)],
|
|
20444
|
+
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.scheduledAt'),detailDate(data.scheduledAt)],
|
|
20445
|
+
[text('details.createdAt'),detailDate(data.createdAt)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
20446
|
+
[text('details.result'),detailTaskResult(data),{wide:true,long:true}]
|
|
20447
|
+
];if(type==='run'){const started=data.startedAt?new Date(data.startedAt).getTime():null;const finished=data.finishedAt?new Date(data.finishedAt).getTime():null;return [
|
|
20448
|
+
[text('details.id'),'Run #'+data.id],[text('details.taskId'),'#'+data.taskId],[text('table.status'),detailStatus('run',data.status)],[text('table.model'),detailModel(data.model)],
|
|
20449
|
+
[text('details.session'),detailSession(data.sessionId)],[text('details.startedAt'),detailDate(data.startedAt)],[text('details.finishedAt'),detailDate(data.finishedAt)],
|
|
20450
|
+
[text('table.duration'),started!==null?detailDuration((finished??Date.now())-started):text('details.none')],[text('details.heartbeat'),detailDate(data.heartbeatAt)],
|
|
20451
|
+
[text('details.process'),'Worker PID '+String(data.workerPid??'\u2014')+' \xB7 OpenCode PID '+String(data.childPid??'\u2014'),{wide:true,mono:true}]
|
|
20452
|
+
];}const scheduleRule=data.scheduleType==='cron'?data.cronExpr:data.scheduleType==='recurring'?detailDuration(data.intervalMs):detailDate(data.runAt);return [
|
|
20453
|
+
[text('details.id'),'#'+data.id],[text('table.name'),data.name],[text('details.enabled'),data.enabled?text('details.enabledYes'):text('details.enabledNo')],[text('details.project'),data.cwd,{wide:true,mono:true}],
|
|
20454
|
+
[text('table.agent'),data.agent],[text('table.model'),detailModel(data.model)],[text('details.prompt'),data.prompt,{wide:true,long:true}],
|
|
20455
|
+
[text('template.scheduleType'),detailScheduleType(data.scheduleType)],[text('details.scheduleRule'),scheduleRule],[text('details.category'),data.category],[text('details.batch'),data.batchId],
|
|
20456
|
+
[text('details.importance'),data.importance],[text('details.urgency'),data.urgency],[text('details.maxInstances'),data.maxInstances],[text('details.maxRetries'),data.maxRetries??0],
|
|
20457
|
+
[text('details.retryBackoff'),detailDuration(data.retryBackoffMs)],[text('details.timeout'),detailDuration(data.timeoutMs)],[text('details.lastRun'),detailDate(data.lastRunAt)],[text('details.nextRun'),detailDate(data.nextRunAt)],
|
|
20458
|
+
[text('details.createdAt'),detailDate(data.createdAt)],[text('details.updatedAt'),detailDate(data.updatedAt)]
|
|
20459
|
+
]}
|
|
20460
|
+
async function showRecord(url,type){try{const data=await readJson(await fetch(url));const content=document.getElementById('detail-content');content.replaceChildren();const grid=document.createElement('div');grid.className='detail-grid';for(const [label,value,options] of detailFields(type,data))grid.appendChild(detailField(label,value,options));content.appendChild(grid);if(type==='task')content.appendChild(renderDetailHistory(data._runs));document.getElementById('detail-title').textContent=text(type==='task'?'details.taskTitle':type==='run'?'details.runTitle':'details.templateTitle');document.getElementById('detail-raw').textContent=JSON.stringify(data,null,2);document.querySelector('#detail-dialog .detail-raw').open=false;document.getElementById('detail-dialog').showModal()}catch(error){showToast(error.message,'error')}}
|
|
20461
|
+
const showDetail=id=>showRecord('/api/tasks/'+id,'task');const showRunDetail=id=>showRecord('/api/runs/'+id,'run');const showTemplateDetail=id=>showRecord('/api/templates/'+id,'template');
|
|
20462
|
+
async function copyDetails(){try{await navigator.clipboard.writeText(document.getElementById('detail-raw').textContent);showToast(text('details.copySuccess'))}catch{showToast(text('feedback.copyFailed'),'error')}}
|
|
20254
20463
|
async function copySessionCommand(id){try{const data=await readJson(await fetch('/api/runs/'+id+'/session-command'));await navigator.clipboard.writeText(data.command);showToast(text('feedback.sessionCommandCopied'))}catch(error){showToast(error.message||text('feedback.copyFailed'),'error')}}
|
|
20255
20464
|
async function copyRunCommand(id){try{await navigator.clipboard.writeText(document.getElementById('command-'+id).textContent);showToast(text('feedback.commandCopied'))}catch{showToast(text('feedback.copyFailed'),'error')}}
|
|
20256
20465
|
function taskField(name){return document.getElementById('task-'+name)}
|
|
@@ -20288,7 +20497,7 @@ function renderLayout(options) {
|
|
|
20288
20497
|
async function disableTmpl(id){if(!await ask(text('dialog.disableTemplate'),text('dialog.disableTemplateBody')))return;try{await readJson(await fetch('/api/templates/'+id+'/disable',{method:'POST'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
20289
20498
|
async function deleteTmpl(id){if(!await ask(text('dialog.deleteTemplate'),text('dialog.deleteTemplateBody'),true))return;try{await readJson(await fetch('/api/templates/'+id,{method:'DELETE'}));location.reload()}catch(error){showToast(error.message,'error')}}
|
|
20290
20499
|
async function triggerTmpl(id){if(!await ask(text('dialog.triggerTemplate'),text('dialog.triggerTemplateBody')))return;try{const data=await readJson(await fetch('/api/templates/'+id+'/trigger',{method:'POST'}));showToast(text('feedback.triggered',{id:data.taskId}));setTimeout(()=>location.reload(),550)}catch(error){showToast(error.message,'error')}}
|
|
20291
|
-
function toggleLog(id,button){const panel=document.getElementById('log-'+id);const hidden=!panel.hidden;panel.hidden=hidden;button.setAttribute('aria-expanded',String(!hidden));button.textContent=text(hidden?'action.logs':'action.hideLogs');}
|
|
20500
|
+
function toggleLog(id,button){const panel=document.getElementById('log-'+id);const hidden=!panel.hidden;panel.hidden=hidden;button.setAttribute('aria-expanded',String(!hidden));button.textContent=text(hidden?'action.logs':'action.hideLogs');if(!hidden)requestAnimationFrame(()=>panel.scrollIntoView({block:'nearest',behavior:'smooth'}));}
|
|
20292
20501
|
function filterTasks(value){const query=value.trim().toLocaleLowerCase();let visible=0;document.querySelectorAll('[data-task-row]').forEach(row=>{const match=!query||row.dataset.search.toLocaleLowerCase().includes(query);row.hidden=!match;if(match)visible++});const empty=document.getElementById('search-empty');if(empty)empty.hidden=visible!==0;}
|
|
20293
20502
|
async function clearDatabase(){if(!await askDanger())return;try{const data=await readJson(await fetch('/api/database/clear',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({confirmation:'CLEAR'})}));showToast(text('feedback.databaseCleared',{path:data.backupPath}));setTimeout(()=>location.reload(),1000)}catch(error){showToast(error.message,'error')}}
|
|
20294
20503
|
async function confirmGatewayRestart(runningCount=0){const body=runningCount>0?text('dialog.restartGatewayRunningBody',{count:runningCount}):text('dialog.restartGatewayBody');return await ask(text('dialog.restartGateway'),body)}
|
|
@@ -20642,7 +20851,7 @@ function renderRunLog(runId, taskName, log, locale) {
|
|
|
20642
20851
|
const errors = presentation.errors.length > 0 ? `<div class="run-error"><strong>${t(locale, "logs.error")}</strong><pre>${esc(presentation.errors.join("\n"))}</pre></div>` : "";
|
|
20643
20852
|
const tools = presentation.tools.length > 0 ? `<div class="run-tools"><strong>${t(locale, "logs.tools")}</strong><div class="actions">${presentation.tools.map((tool) => `<span class="tag">${esc(tool)}</span>`).join("")}</div></div>` : "";
|
|
20644
20853
|
const output = `<div class="run-output"><strong>${t(locale, "logs.output")}</strong><pre>${esc(presentation.text || t(locale, "logs.noText"))}</pre></div>`;
|
|
20645
|
-
return `<section
|
|
20854
|
+
return `<section class="panel log-panel"><div class="panel-head"><h3>Run #${runId} \xB7 ${esc(taskName)}</h3></div><div class="log-content">${command}${errors}${output}${tools}<details class="raw-log"><summary>${t(locale, "logs.raw")}</summary><div class="log-box">${esc(log)}</div></details></div></section>`;
|
|
20646
20855
|
}
|
|
20647
20856
|
function esc(value) {
|
|
20648
20857
|
if (!value) return "";
|
|
@@ -20992,14 +21201,11 @@ app.get("/runs", async (c) => {
|
|
|
20992
21201
|
const total = Number(totalResult[0]?.count ?? 0);
|
|
20993
21202
|
const totalPages = Math.max(1, Math.ceil(total / limit));
|
|
20994
21203
|
if (page > totalPages) return c.redirect(`/runs?page=${totalPages}`);
|
|
20995
|
-
const logs = [];
|
|
20996
21204
|
const rows = runs.map((run) => {
|
|
20997
21205
|
const status = safeStatus(run.status);
|
|
20998
21206
|
const resumable = isValidSessionId(run.sessionId);
|
|
20999
|
-
|
|
21000
|
-
|
|
21001
|
-
}
|
|
21002
|
-
return `<tr>
|
|
21207
|
+
const log = run.log ? renderRunLog(run.id, run.taskName, run.log, locale) : "";
|
|
21208
|
+
return `<tr class="run-summary-row">
|
|
21003
21209
|
<td class="faint" data-label="${t(locale, "table.run")}">#${run.id}</td>
|
|
21004
21210
|
<td data-primary data-label="${t(locale, "table.task")}"><div class="task-name">${esc(run.taskName)} <span class="faint">#${run.taskId}</span></div>${run.model ? `<div style="margin-top:4px"><span class="tag">${esc(run.model)}</span></div>` : ""}</td>
|
|
21005
21211
|
<td data-label="${t(locale, "table.agent")}"><span class="tag">${esc(run.taskAgent)}</span></td>
|
|
@@ -21010,7 +21216,7 @@ app.get("/runs", async (c) => {
|
|
|
21010
21216
|
<td data-label="${t(locale, "table.actions")}"><div class="actions"><button type="button" class="btn" onclick="showRunDetail(${run.id})">${t(locale, "action.details")}</button>
|
|
21011
21217
|
${resumable ? `<button type="button" class="btn" onclick="copySessionCommand(${run.id})">${icon("copy")}${t(locale, "action.continueSession")}</button>` : ""}
|
|
21012
21218
|
${run.log ? `<button type="button" class="btn" aria-expanded="false" onclick="toggleLog(${run.id},this)">${t(locale, "action.logs")}</button>` : ""}</div></td>
|
|
21013
|
-
</tr
|
|
21219
|
+
</tr>${log ? `<tr id="log-${run.id}" class="run-log-row" hidden><td class="run-log-cell" colspan="8">${log}</td></tr>` : ""}`;
|
|
21014
21220
|
}).join("");
|
|
21015
21221
|
const body = `
|
|
21016
21222
|
<div class="stats-grid">
|
|
@@ -21020,7 +21226,7 @@ app.get("/runs", async (c) => {
|
|
|
21020
21226
|
${statCard(runs.filter((run) => run.status === "running").length, t(locale, "stats.pageRunning"), "tone-blue", icon("activity"), "reveal-delay-2")}
|
|
21021
21227
|
</div>
|
|
21022
21228
|
<section class="panel reveal reveal-delay-2">${runs.length === 0 ? emptyState(t(locale, "empty.runs"), "") : `<div class="table-wrap"><table class="responsive-table"><thead><tr><th>${t(locale, "table.run")}</th><th>${t(locale, "table.task")}</th><th>${t(locale, "table.agent")}</th><th>${t(locale, "table.session")}</th><th>${t(locale, "table.status")}</th><th>${t(locale, "table.duration")}</th><th>${t(locale, "table.heartbeat")}</th><th>${t(locale, "table.actions")}</th></tr></thead><tbody>${rows}</tbody></table></div>`}</section>
|
|
21023
|
-
${
|
|
21229
|
+
${pagination(locale, "/runs", page, totalPages, total)}`;
|
|
21024
21230
|
return c.html(renderLayout({ locale, activeTab: "runs", body }));
|
|
21025
21231
|
});
|
|
21026
21232
|
app.get("/system", async (c) => {
|
|
@@ -21127,7 +21333,11 @@ app.get("/api/tasks/:id", async (c) => {
|
|
|
21127
21333
|
const task = await TaskService.getById(id);
|
|
21128
21334
|
if (!task) return c.json({ error: "not found" }, 404);
|
|
21129
21335
|
const runs = await TaskRunService.listByTaskId(id);
|
|
21130
|
-
return c.json({
|
|
21336
|
+
return c.json({
|
|
21337
|
+
...task,
|
|
21338
|
+
_resultPresentation: task.resultLog ? presentRunLog(task.resultLog) : null,
|
|
21339
|
+
_runs: runs
|
|
21340
|
+
});
|
|
21131
21341
|
});
|
|
21132
21342
|
app.get("/api/runs/:id", async (c) => {
|
|
21133
21343
|
const id = parsePositiveInteger(c.req.param("id"));
|