opencode-supertask 0.1.32-rc.2 → 0.1.34

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 CHANGED
@@ -12696,8 +12696,8 @@ var require_luxon = __commonJS({
12696
12696
  * Set whether Luxon will throw when it encounters invalid DateTimes, Durations, or Intervals
12697
12697
  * @type {boolean}
12698
12698
  */
12699
- static set throwOnInvalid(t2) {
12700
- throwOnInvalid = t2;
12699
+ static set throwOnInvalid(t3) {
12700
+ throwOnInvalid = t3;
12701
12701
  }
12702
12702
  /**
12703
12703
  * Reset Luxon's global caches. Should only be necessary in testing scenarios.
@@ -13590,7 +13590,7 @@ var require_luxon = __commonJS({
13590
13590
  }, tokens = _Formatter.parseFormat(fmt), realTokens = tokens.reduce((found, {
13591
13591
  literal,
13592
13592
  val
13593
- }) => literal ? found : found.concat(val), []), collapsed = dur.shiftTo(...realTokens.map(tokenToField).filter((t2) => t2)), durationInfo = {
13593
+ }) => literal ? found : found.concat(val), []), collapsed = dur.shiftTo(...realTokens.map(tokenToField).filter((t3) => t3)), durationInfo = {
13594
13594
  isNegativeDuration: collapsed < 0,
13595
13595
  // this relies on "collapsed" being based on "shiftTo", which builds up the object
13596
13596
  // in order
@@ -15500,15 +15500,15 @@ var require_luxon = __commonJS({
15500
15500
  return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
15501
15501
  }
15502
15502
  function unitForToken(token, loc) {
15503
- const one = digitRegex(loc), two = digitRegex(loc, "{2}"), three = digitRegex(loc, "{3}"), four = digitRegex(loc, "{4}"), six = digitRegex(loc, "{6}"), oneOrTwo = digitRegex(loc, "{1,2}"), oneToThree = digitRegex(loc, "{1,3}"), oneToSix = digitRegex(loc, "{1,6}"), oneToNine = digitRegex(loc, "{1,9}"), twoToFour = digitRegex(loc, "{2,4}"), fourToSix = digitRegex(loc, "{4,6}"), literal = (t2) => ({
15504
- regex: RegExp(escapeToken(t2.val)),
15503
+ const one = digitRegex(loc), two = digitRegex(loc, "{2}"), three = digitRegex(loc, "{3}"), four = digitRegex(loc, "{4}"), six = digitRegex(loc, "{6}"), oneOrTwo = digitRegex(loc, "{1,2}"), oneToThree = digitRegex(loc, "{1,3}"), oneToSix = digitRegex(loc, "{1,6}"), oneToNine = digitRegex(loc, "{1,9}"), twoToFour = digitRegex(loc, "{2,4}"), fourToSix = digitRegex(loc, "{4,6}"), literal = (t3) => ({
15504
+ regex: RegExp(escapeToken(t3.val)),
15505
15505
  deser: ([s2]) => s2,
15506
15506
  literal: true
15507
- }), unitate = (t2) => {
15507
+ }), unitate = (t3) => {
15508
15508
  if (token.literal) {
15509
- return literal(t2);
15509
+ return literal(t3);
15510
15510
  }
15511
- switch (t2.val) {
15511
+ switch (t3.val) {
15512
15512
  // era
15513
15513
  case "G":
15514
15514
  return oneOf(loc.eras("short"), 0);
@@ -15623,7 +15623,7 @@ var require_luxon = __commonJS({
15623
15623
  case " ":
15624
15624
  return simple(/[^\S\n\r]/);
15625
15625
  default:
15626
- return literal(t2);
15626
+ return literal(t3);
15627
15627
  }
15628
15628
  };
15629
15629
  const unit = unitate(token) || {
@@ -15825,15 +15825,15 @@ var require_luxon = __commonJS({
15825
15825
  return tokens;
15826
15826
  }
15827
15827
  function expandMacroTokens(tokens, locale) {
15828
- return Array.prototype.concat(...tokens.map((t2) => maybeExpandMacroToken(t2, locale)));
15828
+ return Array.prototype.concat(...tokens.map((t3) => maybeExpandMacroToken(t3, locale)));
15829
15829
  }
15830
15830
  var TokenParser = class {
15831
15831
  constructor(locale, format) {
15832
15832
  this.locale = locale;
15833
15833
  this.format = format;
15834
15834
  this.tokens = expandMacroTokens(Formatter.parseFormat(format), locale);
15835
- this.units = this.tokens.map((t2) => unitForToken(t2, locale));
15836
- this.disqualifyingUnit = this.units.find((t2) => t2.invalidReason);
15835
+ this.units = this.tokens.map((t3) => unitForToken(t3, locale));
15836
+ this.disqualifyingUnit = this.units.find((t3) => t3.invalidReason);
15837
15837
  if (!this.disqualifyingUnit) {
15838
15838
  const [regexString, handlers] = buildRegex(this.units);
15839
15839
  this.regex = RegExp(regexString, "i");
@@ -16658,7 +16658,7 @@ var require_luxon = __commonJS({
16658
16658
  */
16659
16659
  static parseFormatForOpts(formatOpts, localeOpts = {}) {
16660
16660
  const tokenList = formatOptsToTokens(formatOpts, Locale.fromObject(localeOpts));
16661
- return !tokenList ? null : tokenList.map((t2) => t2 ? t2.val : null).join("");
16661
+ return !tokenList ? null : tokenList.map((t3) => t3 ? t3.val : null).join("");
16662
16662
  }
16663
16663
  /**
16664
16664
  * Produce the the fully expanded format token for the locale
@@ -16669,7 +16669,7 @@ var require_luxon = __commonJS({
16669
16669
  */
16670
16670
  static expandFormat(fmt, localeOpts = {}) {
16671
16671
  const expanded = expandMacroTokens(Formatter.parseFormat(fmt), Locale.fromObject(localeOpts));
16672
- return expanded.map((t2) => t2.val).join("");
16672
+ return expanded.map((t3) => t3.val).join("");
16673
16673
  }
16674
16674
  static resetCache() {
16675
16675
  zoneOffsetTs = void 0;
@@ -19526,10 +19526,10 @@ var require_random = __commonJS({
19526
19526
  }
19527
19527
  function mulberry32(seed) {
19528
19528
  return () => {
19529
- let t2 = seed += 1831565813;
19530
- t2 = Math.imul(t2 ^ t2 >>> 15, t2 | 1);
19531
- t2 ^= t2 + Math.imul(t2 ^ t2 >>> 7, t2 | 61);
19532
- return ((t2 ^ t2 >>> 14) >>> 0) / 4294967296;
19529
+ let t3 = seed += 1831565813;
19530
+ t3 = Math.imul(t3 ^ t3 >>> 15, t3 | 1);
19531
+ t3 ^= t3 + Math.imul(t3 ^ t3 >>> 7, t3 | 61);
19532
+ return ((t3 ^ t3 >>> 14) >>> 0) / 4294967296;
19533
19533
  };
19534
19534
  }
19535
19535
  function seededRandom(str) {
@@ -21542,6 +21542,25 @@ function currentGatewayRuntime(gatewayEntry = resolveGatewayEntry()) {
21542
21542
  env: { ...process.env }
21543
21543
  };
21544
21544
  }
21545
+ function refreshGatewayExecutionEnvironment(runtime, gatewayEntry) {
21546
+ const env = { ...process.env };
21547
+ for (const key of /* @__PURE__ */ new Set([
21548
+ ...Object.keys(runtime.env).filter((name) => name.startsWith("SUPERTASK_")),
21549
+ ...Object.keys(env).filter((name) => name.startsWith("SUPERTASK_")),
21550
+ "HOME",
21551
+ "PATH",
21552
+ "PM2_HOME"
21553
+ ])) {
21554
+ const value = runtime.env[key];
21555
+ if (value === void 0) delete env[key];
21556
+ else env[key] = value;
21557
+ }
21558
+ return {
21559
+ ...runtime,
21560
+ gatewayEntry: resolve3(gatewayEntry),
21561
+ env
21562
+ };
21563
+ }
21545
21564
  function isGatewayRunning() {
21546
21565
  if (!isPm2Installed()) return false;
21547
21566
  const proc = pm2JsonList().find((item) => item.name === PROCESS_NAME);
@@ -21894,7 +21913,7 @@ function installUnlocked() {
21894
21913
  }
21895
21914
  const existing = pm2JsonList().find((item) => item.name === PROCESS_NAME);
21896
21915
  const oldRuntime = gatewayRuntimeFromProcess(existing);
21897
- const targetRuntime = oldRuntime ? { ...oldRuntime, gatewayEntry: resolve3(resolveGatewayEntry()) } : currentGatewayRuntime();
21916
+ const targetRuntime = oldRuntime ? refreshGatewayExecutionEnvironment(oldRuntime, resolveGatewayEntry()) : currentGatewayRuntime();
21898
21917
  const before = getRunningVersion(oldRuntime?.env ?? process.env, oldRuntime?.cwd);
21899
21918
  if (oldRuntime && !scopesMatch(currentScope(), runtimeScope(oldRuntime))) {
21900
21919
  throw new Error("[supertask] \u5F53\u524D CLI \u4E0E PM2 Gateway \u7684\u6570\u636E\u5E93/\u914D\u7F6E/OpenCode \u8FD0\u884C\u4F5C\u7528\u57DF\u4E0D\u4E00\u81F4\uFF0C\u5DF2\u62D2\u7EDD\u8986\u76D6");
@@ -22007,7 +22026,10 @@ function upgradeUnlocked(target) {
22007
22026
  const oldRuntime = gatewayRuntimeFromProcess(existing) ?? (process.env.SUPERTASK_GATEWAY_ENTRY ? currentGatewayRuntime(resolveGatewayEntry()) : null);
22008
22027
  const before = getRunningVersion(oldRuntime?.env ?? process.env, oldRuntime?.cwd);
22009
22028
  const currentVersion = target?.version ?? getPackageVersion();
22010
- const targetRuntime = oldRuntime ? { ...oldRuntime, gatewayEntry: resolve3(target?.gatewayEntry ?? oldRuntime.gatewayEntry) } : currentGatewayRuntime(target?.gatewayEntry ?? resolveGatewayEntry());
22029
+ const targetRuntime = oldRuntime ? refreshGatewayExecutionEnvironment(
22030
+ oldRuntime,
22031
+ target?.gatewayEntry ?? oldRuntime.gatewayEntry
22032
+ ) : currentGatewayRuntime(target?.gatewayEntry ?? resolveGatewayEntry());
22011
22033
  assertRuntimeCanControlPm2(oldRuntime, existing);
22012
22034
  gatewayKillTimeoutMs(targetRuntime);
22013
22035
  gatewayTerminationCommandTimeoutMs(targetRuntime);
@@ -22163,17 +22185,19 @@ var init_semver = __esm({
22163
22185
  // src/daemon/update.ts
22164
22186
  var update_exports = {};
22165
22187
  __export(update_exports, {
22188
+ getGlobalCliDiagnostic: () => getGlobalCliDiagnostic,
22166
22189
  getOpenCodePluginDiagnostic: () => getOpenCodePluginDiagnostic,
22167
22190
  installLatestPlugin: () => installLatestPlugin,
22168
22191
  installPluginVersion: () => installPluginVersion,
22169
22192
  resolveConfiguredPluginSpec: () => resolveConfiguredPluginSpec,
22170
22193
  resolveInstalledPlugin: () => resolveInstalledPlugin,
22171
- resolveInstalledPluginVersion: () => resolveInstalledPluginVersion
22194
+ resolveInstalledPluginVersion: () => resolveInstalledPluginVersion,
22195
+ updateGlobalCli: () => updateGlobalCli
22172
22196
  });
22173
22197
  import { spawnSync as spawnSync3 } from "child_process";
22174
- import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync } from "fs";
22198
+ import { existsSync as existsSync6, readFileSync as readFileSync4, readdirSync, realpathSync } from "fs";
22175
22199
  import { homedir as homedir4 } from "os";
22176
- import { join as join5 } from "path";
22200
+ import { dirname as dirname7, join as join5, resolve as resolve4 } from "path";
22177
22201
  function pluginAt(packageDir) {
22178
22202
  const packageJson = join5(packageDir, "package.json");
22179
22203
  const gatewayEntry = join5(packageDir, "dist/gateway/index.js");
@@ -22216,6 +22240,131 @@ function opencodeBin() {
22216
22240
  function npmBin() {
22217
22241
  return process.env.SUPERTASK_NPM_BIN ?? "npm";
22218
22242
  }
22243
+ function bunBin() {
22244
+ return process.env.SUPERTASK_BUN_BIN ?? "bun";
22245
+ }
22246
+ function resolveGlobalCliExecutable() {
22247
+ const override = process.env.SUPERTASK_CLI_BIN;
22248
+ if (override) return existsSync6(override) ? resolve4(override) : null;
22249
+ const result = spawnSync3(process.platform === "win32" ? "where" : "which", ["supertask"], {
22250
+ encoding: "utf8",
22251
+ env: process.env,
22252
+ timeout: 1e4
22253
+ });
22254
+ if (result.status !== 0) return null;
22255
+ const executable = `${result.stdout ?? ""}`.trim().split(/\r?\n/)[0];
22256
+ return executable && existsSync6(executable) ? resolve4(executable) : null;
22257
+ }
22258
+ function cliPackageDir(executable) {
22259
+ try {
22260
+ let directory = dirname7(realpathSync(executable));
22261
+ for (let depth = 0; depth < 6; depth += 1) {
22262
+ const packagePath = join5(directory, "package.json");
22263
+ if (existsSync6(packagePath)) {
22264
+ const pkg = JSON.parse(readFileSync4(packagePath, "utf8"));
22265
+ if (pkg.name === PACKAGE_NAME) return directory;
22266
+ }
22267
+ const parent = dirname7(directory);
22268
+ if (parent === directory) break;
22269
+ directory = parent;
22270
+ }
22271
+ } catch {
22272
+ }
22273
+ return null;
22274
+ }
22275
+ function packageVersion(packageDir) {
22276
+ try {
22277
+ const pkg = JSON.parse(readFileSync4(join5(packageDir, "package.json"), "utf8"));
22278
+ return pkg.name === PACKAGE_NAME && typeof pkg.version === "string" ? pkg.version : null;
22279
+ } catch {
22280
+ return null;
22281
+ }
22282
+ }
22283
+ function npmGlobalRoot() {
22284
+ const result = spawnSync3(npmBin(), ["root", "-g"], {
22285
+ encoding: "utf8",
22286
+ env: process.env,
22287
+ timeout: 3e4
22288
+ });
22289
+ if (result.status !== 0) return null;
22290
+ const root = `${result.stdout ?? ""}`.trim();
22291
+ if (!root) return null;
22292
+ try {
22293
+ return realpathSync(root);
22294
+ } catch {
22295
+ return resolve4(root);
22296
+ }
22297
+ }
22298
+ function globalCliPackageManager(packageDir) {
22299
+ const normalized = packageDir.replaceAll("\\", "/");
22300
+ if (normalized.includes("/install/global/node_modules/")) return "bun";
22301
+ const npmRoot = npmGlobalRoot();
22302
+ if (npmRoot && resolve4(packageDir) === join5(npmRoot, PACKAGE_NAME)) return "npm";
22303
+ return null;
22304
+ }
22305
+ function getGlobalCliDiagnostic() {
22306
+ const executable = resolveGlobalCliExecutable();
22307
+ if (!executable) {
22308
+ return {
22309
+ installed: false,
22310
+ executable: null,
22311
+ packageDir: null,
22312
+ version: null,
22313
+ packageManager: null
22314
+ };
22315
+ }
22316
+ const packageDir = cliPackageDir(executable);
22317
+ if (!packageDir) {
22318
+ return {
22319
+ installed: true,
22320
+ executable,
22321
+ packageDir: null,
22322
+ version: null,
22323
+ packageManager: null
22324
+ };
22325
+ }
22326
+ return {
22327
+ installed: true,
22328
+ executable,
22329
+ packageDir,
22330
+ version: packageVersion(packageDir),
22331
+ packageManager: globalCliPackageManager(packageDir)
22332
+ };
22333
+ }
22334
+ function updateGlobalCli(version2) {
22335
+ if (!isSemanticVersion(version2)) {
22336
+ throw new Error(`[supertask] \u5168\u5C40 CLI \u76EE\u6807\u7248\u672C\u65E0\u6548: ${version2}`);
22337
+ }
22338
+ const before = getGlobalCliDiagnostic();
22339
+ if (!before.installed) return { ...before, action: "not-installed" };
22340
+ if (before.version === version2) return { ...before, action: "already-current" };
22341
+ if (!before.packageManager) {
22342
+ throw new Error(
22343
+ `[supertask] \u65E0\u6CD5\u786E\u8BA4\u5168\u5C40 CLI \u7684\u5305\u7BA1\u7406\u5668\uFF08\u5F53\u524D ${before.version ?? "unknown"}\uFF0C\u76EE\u6807 ${version2}\uFF09\uFF1B\u8BF7\u6267\u884C npm install -g ${PACKAGE_NAME}@${version2} \u6216 bun add -g ${PACKAGE_NAME}@${version2}`
22344
+ );
22345
+ }
22346
+ const command = before.packageManager === "npm" ? npmBin() : bunBin();
22347
+ const args = before.packageManager === "npm" ? ["install", "-g", `${PACKAGE_NAME}@${version2}`] : ["add", "-g", `${PACKAGE_NAME}@${version2}`];
22348
+ const result = spawnSync3(command, args, {
22349
+ encoding: "utf8",
22350
+ env: process.env,
22351
+ timeout: 12e4
22352
+ });
22353
+ const output = `${result.stdout ?? ""}${result.stderr ?? ""}`.trim();
22354
+ if (result.error) {
22355
+ throw new Error(`[supertask] \u5168\u5C40 CLI \u66F4\u65B0\u5931\u8D25: ${result.error.message}`);
22356
+ }
22357
+ if (result.status !== 0) {
22358
+ throw new Error(`[supertask] \u5168\u5C40 CLI \u66F4\u65B0\u5931\u8D25: ${output || `\u9000\u51FA\u7801 ${result.status}`}`);
22359
+ }
22360
+ const after = getGlobalCliDiagnostic();
22361
+ if (after.version !== version2) {
22362
+ throw new Error(
22363
+ `[supertask] \u5168\u5C40 CLI \u66F4\u65B0\u540E\u7248\u672C\u4E0D\u5339\u914D\uFF1A\u671F\u671B ${version2}\uFF0C\u5B9E\u9645 ${after.version ?? "unknown"}`
22364
+ );
22365
+ }
22366
+ return { ...after, action: "updated" };
22367
+ }
22219
22368
  function latestVersion() {
22220
22369
  const result = spawnSync3(npmBin(), [
22221
22370
  "view",
@@ -22515,7 +22664,7 @@ var init_health = __esm({
22515
22664
  import { spawn } from "child_process";
22516
22665
  import { fileURLToPath as fileURLToPath5 } from "url";
22517
22666
  import { existsSync as existsSync7 } from "fs";
22518
- import { dirname as dirname7, join as join6 } from "path";
22667
+ import { dirname as dirname8, join as join6 } from "path";
22519
22668
  import { randomUUID as randomUUID2 } from "crypto";
22520
22669
  function assertWorkerProcessIsolationSupported(platform = process.platform) {
22521
22670
  if (platform === "win32") {
@@ -22704,7 +22853,7 @@ var init_worker = __esm({
22704
22853
  }
22705
22854
  launcherEntry() {
22706
22855
  const extension = import.meta.url.endsWith(".ts") ? "ts" : "js";
22707
- const moduleDir = dirname7(fileURLToPath5(import.meta.url));
22856
+ const moduleDir = dirname8(fileURLToPath5(import.meta.url));
22708
22857
  const candidates = [
22709
22858
  join6(moduleDir, `launcher.${extension}`),
22710
22859
  join6(moduleDir, `../worker/launcher.${extension}`)
@@ -22773,8 +22922,8 @@ var init_worker = __esm({
22773
22922
  }
22774
22923
  });
22775
22924
  let spawnError = null;
22776
- const spawned = new Promise((resolve4, reject) => {
22777
- child.once("spawn", resolve4);
22925
+ const spawned = new Promise((resolve5, reject) => {
22926
+ child.once("spawn", resolve5);
22778
22927
  child.once("error", (error) => {
22779
22928
  spawnError = error;
22780
22929
  reject(error);
@@ -22822,10 +22971,10 @@ var init_worker = __esm({
22822
22971
  return;
22823
22972
  }
22824
22973
  try {
22825
- await new Promise((resolve4, reject) => {
22974
+ await new Promise((resolve5, reject) => {
22826
22975
  child.stdin.end("START\n", (error) => {
22827
22976
  if (error) reject(error);
22828
- else resolve4();
22977
+ else resolve5();
22829
22978
  });
22830
22979
  });
22831
22980
  } catch (error) {
@@ -22872,7 +23021,7 @@ var init_worker = __esm({
22872
23021
  );
22873
23022
  return;
22874
23023
  }
22875
- const failure = code === 0 ? void 0 : `${spawnError ? "\u65E0\u6CD5\u542F\u52A8 opencode" : "opencode \u9000\u51FA\u7801"} ${spawnError?.message ?? code ?? "null"}${signal ? `\uFF0C\u4FE1\u53F7 ${signal}` : ""}`;
23024
+ const failure = code === 0 ? void 0 : `${spawnError ? "\u65E0\u6CD5\u542F\u52A8 opencode" : "opencode \u9000\u51FA\u7801"} ${spawnError?.message ?? code ?? "null"}${signal ? `\uFF0C\u4FE1\u53F7 ${signal}` : ""}\uFF08agent=${entry.task.agent}\uFF0Cmodel=${this.resolveModel(entry.task.model) ?? "Agent/\u9ED8\u8BA4\u914D\u7F6E"}\uFF0Ccwd=${entry.task.cwd ?? process.cwd()}\uFF09`;
22876
23025
  this.runDetached(
22877
23026
  this.settleEntry(entry, code, failure),
22878
23027
  "task settlement failed",
@@ -26857,7 +27006,7 @@ __export(web_exports, {
26857
27006
  setDashboardRuntimeConfig: () => setDashboardRuntimeConfig
26858
27007
  });
26859
27008
  import { existsSync as existsSync8, mkdirSync as mkdirSync5, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync3 } from "fs";
26860
- import { basename as basename3, dirname as dirname8 } from "path";
27009
+ import { basename as basename3, dirname as dirname9 } from "path";
26861
27010
  function setDashboardRuntimeConfig(config) {
26862
27011
  runtimeConfig = config === null ? null : structuredClone(config);
26863
27012
  }
@@ -27069,7 +27218,7 @@ function readCurrentConfig() {
27069
27218
  }
27070
27219
  function writeConfig(cfg) {
27071
27220
  const configPath = getConfigPath();
27072
- const dir = dirname8(configPath);
27221
+ const dir = dirname9(configPath);
27073
27222
  if (!existsSync8(dir)) mkdirSync5(dir, { recursive: true });
27074
27223
  const tempPath = `${configPath}.${process.pid}.tmp`;
27075
27224
  writeFileSync3(tempPath, JSON.stringify(cfg, null, 2) + "\n", { mode: 384 });
@@ -28084,6 +28233,26 @@ init_pm2();
28084
28233
  init_config();
28085
28234
  import { spawnSync as spawnSync4 } from "child_process";
28086
28235
 
28236
+ // src/cli/i18n.ts
28237
+ function requestedLanguage(argv) {
28238
+ for (let index2 = 2; index2 < argv.length; index2 += 1) {
28239
+ const argument = argv[index2];
28240
+ if (argument === "--lang") return argv[index2 + 1];
28241
+ if (argument.startsWith("--lang=")) return argument.slice("--lang=".length);
28242
+ }
28243
+ return void 0;
28244
+ }
28245
+ function resolveCliLocale(argv = process.argv, env = process.env) {
28246
+ const requested = requestedLanguage(argv) ?? env.SUPERTASK_LANG ?? "auto";
28247
+ if (requested === "zh" || requested === "zh-CN") return "zh-CN";
28248
+ if (requested === "en") return "en";
28249
+ const systemLocale = env.LC_ALL || env.LC_MESSAGES || env.LANG || "";
28250
+ return /^zh(?:[_-]|$)/i.test(systemLocale) ? "zh-CN" : "en";
28251
+ }
28252
+ function cliText(locale, zh, en) {
28253
+ return locale === "zh-CN" ? zh : en;
28254
+ }
28255
+
28087
28256
  // src/cli/database-output.ts
28088
28257
  function useJson(options) {
28089
28258
  const isTTY = options.isTTY ?? process.stdout.isTTY === true;
@@ -28100,23 +28269,52 @@ function formatBytes(bytes) {
28100
28269
  const rendered = Number.isInteger(value) ? String(value) : value.toFixed(1);
28101
28270
  return `${rendered} ${units[unit]}`;
28102
28271
  }
28103
- function formatCounts(counts) {
28104
- return `\u4EFB\u52A1 ${counts.tasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${counts.taskRuns} \xB7 \u8C03\u5EA6\u6A21\u677F ${counts.taskTemplates}`;
28105
- }
28106
- function formatGateway(gateway) {
28107
- if (gateway.restarted) return "\u5DF2\u81EA\u52A8\u505C\u6B62\u3001\u91CD\u542F\u5E76\u6062\u590D\u5C31\u7EEA";
28108
- if (gateway.keptStopped) return "\u5DF2\u81EA\u52A8\u505C\u6B62\uFF0C\u6309\u8981\u6C42\u4FDD\u6301\u505C\u6B62";
28109
- 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";
28110
- return "\u539F Gateway \u672A\u6062\u590D\u8FD0\u884C";
28272
+ function formatCounts(counts, locale) {
28273
+ return cliText(
28274
+ locale,
28275
+ `\u4EFB\u52A1 ${counts.tasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${counts.taskRuns} \xB7 \u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F ${counts.taskTemplates}`,
28276
+ `tasks ${counts.tasks} \xB7 runs ${counts.taskRuns} \xB7 scheduled templates ${counts.taskTemplates}`
28277
+ );
28111
28278
  }
28112
- function formatCheck(result) {
28279
+ function formatGateway(gateway, locale) {
28280
+ if (gateway.restarted) return cliText(locale, "\u5DF2\u81EA\u52A8\u505C\u6B62\u3001\u91CD\u542F\u5E76\u6062\u590D\u5C31\u7EEA", "stopped, restarted, and ready");
28281
+ if (gateway.keptStopped) return cliText(locale, "\u5DF2\u81EA\u52A8\u505C\u6B62\uFF0C\u6309\u8981\u6C42\u4FDD\u6301\u505C\u6B62", "stopped and left stopped as requested");
28282
+ if (!gateway.wasRunning) {
28283
+ return cliText(
28284
+ locale,
28285
+ "\u65E0\u9700\u81EA\u52A8\u505C\u542F\uFF08\u672A\u53D1\u73B0\u5339\u914D\u5F53\u524D\u6570\u636E\u5E93\u7684 PM2 Gateway\uFF09",
28286
+ "no matching PM2 Gateway was running"
28287
+ );
28288
+ }
28289
+ return cliText(locale, "\u539F Gateway \u672A\u6062\u590D\u8FD0\u884C", "the previous Gateway was not restored");
28290
+ }
28291
+ function formatCheck(result, locale) {
28292
+ if (locale === "en") {
28293
+ const lines2 = [
28294
+ result.ok ? "\u2713 Database check passed" : "\u2717 Database check failed",
28295
+ "",
28296
+ `Database: ${result.path}`,
28297
+ `Size: ${formatBytes(result.sizeBytes)}`,
28298
+ `Journal mode: ${result.journalMode}`,
28299
+ `Counts: ${formatCounts(result.counts, locale)}`,
28300
+ `Running: tasks ${result.runningTasks} \xB7 runs ${result.runningRuns}`
28301
+ ];
28302
+ if (!result.ok) {
28303
+ lines2.push(
28304
+ `Integrity: ${result.integrityMessages.join("; ") || "no result"}`,
28305
+ `Foreign-key violations: ${result.foreignKeyViolations}`,
28306
+ `Missing tables: ${result.missingTables.join(", ") || "none"}`
28307
+ );
28308
+ }
28309
+ return lines2.join("\n");
28310
+ }
28113
28311
  const lines = [
28114
28312
  result.ok ? "\u2713 \u6570\u636E\u5E93\u68C0\u67E5\u901A\u8FC7" : "\u2717 \u6570\u636E\u5E93\u68C0\u67E5\u672A\u901A\u8FC7",
28115
28313
  "",
28116
28314
  `\u6570\u636E\u5E93\uFF1A${result.path}`,
28117
28315
  `\u5927\u5C0F\uFF1A${formatBytes(result.sizeBytes)}`,
28118
28316
  `\u65E5\u5FD7\u6A21\u5F0F\uFF1A${result.journalMode}`,
28119
- `\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(result.counts)}`,
28317
+ `\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(result.counts, locale)}`,
28120
28318
  `\u8FD0\u884C\u4E2D\uFF1A\u4EFB\u52A1 ${result.runningTasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${result.runningRuns}`
28121
28319
  ];
28122
28320
  if (!result.ok) {
@@ -28128,49 +28326,81 @@ function formatCheck(result) {
28128
28326
  }
28129
28327
  return lines.join("\n");
28130
28328
  }
28131
- function formatHuman(operation, result) {
28329
+ function formatHuman(operation, result, locale) {
28132
28330
  switch (operation) {
28133
28331
  case "check":
28134
- return formatCheck(result);
28332
+ return formatCheck(result, locale);
28135
28333
  case "backup": {
28136
28334
  const backup = result;
28335
+ if (locale === "en") {
28336
+ return [
28337
+ "\u2713 Database backup completed",
28338
+ "",
28339
+ `Backup: ${backup.path}`,
28340
+ `Size: ${formatBytes(backup.sizeBytes)}`,
28341
+ `Counts: ${formatCounts(backup.check.counts, locale)}`,
28342
+ `Integrity: ${backup.check.ok ? "passed" : "failed"}`
28343
+ ].join("\n");
28344
+ }
28137
28345
  return [
28138
28346
  "\u2713 \u6570\u636E\u5E93\u5907\u4EFD\u5B8C\u6210",
28139
28347
  "",
28140
28348
  `\u5907\u4EFD\u6587\u4EF6\uFF1A${backup.path}`,
28141
28349
  `\u5927\u5C0F\uFF1A${formatBytes(backup.sizeBytes)}`,
28142
- `\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(backup.check.counts)}`,
28350
+ `\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(backup.check.counts, locale)}`,
28143
28351
  `\u6570\u636E\u5E93\u5B8C\u6574\u6027\uFF1A${backup.check.ok ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7"}`
28144
28352
  ].join("\n");
28145
28353
  }
28146
28354
  case "clear": {
28147
28355
  const cleared = result;
28356
+ if (locale === "en") {
28357
+ return [
28358
+ "\u2713 Database safely cleared",
28359
+ "",
28360
+ `Deleted: ${formatCounts(cleared.deleted, locale)}`,
28361
+ `Safety backup: ${cleared.backupPath}`,
28362
+ `Gateway: ${formatGateway(cleared.gateway, locale)}`,
28363
+ `Integrity: ${cleared.check.ok ? "passed" : "failed"}`
28364
+ ].join("\n");
28365
+ }
28148
28366
  return [
28149
28367
  "\u2713 \u6570\u636E\u5E93\u5DF2\u5B89\u5168\u6E05\u7A7A",
28150
28368
  "",
28151
- `\u5DF2\u5220\u9664\uFF1A${formatCounts(cleared.deleted)}`,
28369
+ `\u5DF2\u5220\u9664\uFF1A${formatCounts(cleared.deleted, locale)}`,
28152
28370
  `\u5B89\u5168\u5907\u4EFD\uFF1A${cleared.backupPath}`,
28153
- `Gateway\uFF1A${formatGateway(cleared.gateway)}`,
28371
+ `Gateway\uFF1A${formatGateway(cleared.gateway, locale)}`,
28154
28372
  `\u6570\u636E\u5E93\u5B8C\u6574\u6027\uFF1A${cleared.check.ok ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7"}`
28155
28373
  ].join("\n");
28156
28374
  }
28157
28375
  case "restore": {
28158
28376
  const restored = result;
28377
+ if (locale === "en") {
28378
+ return [
28379
+ "\u2713 Database restore completed",
28380
+ "",
28381
+ `Source: ${restored.sourcePath}`,
28382
+ `Pre-restore safety backup: ${restored.safetyBackupPath}`,
28383
+ `Recovered runtime state: tasks ${restored.recoveredRunningTasks} \xB7 runs ${restored.closedRunningRuns}`,
28384
+ `Counts: ${formatCounts(restored.check.counts, locale)}`,
28385
+ `Gateway: ${formatGateway(restored.gateway, locale)}`,
28386
+ `Integrity: ${restored.check.ok ? "passed" : "failed"}`
28387
+ ].join("\n");
28388
+ }
28159
28389
  return [
28160
28390
  "\u2713 \u6570\u636E\u5E93\u6062\u590D\u5B8C\u6210",
28161
28391
  "",
28162
28392
  `\u6062\u590D\u6765\u6E90\uFF1A${restored.sourcePath}`,
28163
28393
  `\u6062\u590D\u524D\u5B89\u5168\u5907\u4EFD\uFF1A${restored.safetyBackupPath}`,
28164
28394
  `\u8FD0\u884C\u6001\u6536\u655B\uFF1A\u4EFB\u52A1 ${restored.recoveredRunningTasks} \xB7 \u6267\u884C\u8BB0\u5F55 ${restored.closedRunningRuns}`,
28165
- `\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(restored.check.counts)}`,
28166
- `Gateway\uFF1A${formatGateway(restored.gateway)}`,
28395
+ `\u6570\u636E\u7EDF\u8BA1\uFF1A${formatCounts(restored.check.counts, locale)}`,
28396
+ `Gateway\uFF1A${formatGateway(restored.gateway, locale)}`,
28167
28397
  `\u6570\u636E\u5E93\u5B8C\u6574\u6027\uFF1A${restored.check.ok ? "\u901A\u8FC7" : "\u672A\u901A\u8FC7"}`
28168
28398
  ].join("\n");
28169
28399
  }
28170
28400
  }
28171
28401
  }
28172
28402
  function renderDatabaseResult(operation, result, options = {}) {
28173
- return useJson(options) ? JSON.stringify(result, null, 2) : formatHuman(operation, result);
28403
+ return useJson(options) ? JSON.stringify(result, null, 2) : formatHuman(operation, result, options.locale ?? "zh-CN");
28174
28404
  }
28175
28405
  function renderDatabaseError(error, options = {}) {
28176
28406
  const message = error instanceof Error ? error.message : String(error);
@@ -28214,6 +28444,8 @@ function parseTaskStatus(value) {
28214
28444
 
28215
28445
  // src/cli/index.ts
28216
28446
  init_update2();
28447
+ var cliLocale = resolveCliLocale();
28448
+ var t2 = (zh, en) => cliText(cliLocale, zh, en);
28217
28449
  async function withDb(fn, formatError = (error) => JSON.stringify({
28218
28450
  error: error instanceof Error ? error.message : String(error)
28219
28451
  })) {
@@ -28239,8 +28471,13 @@ function runDestructiveDatabaseMaintenance(keepStopped, operation) {
28239
28471
  };
28240
28472
  }
28241
28473
  var program2 = new Command();
28242
- program2.name("supertask").description("\u901A\u7528\u4EFB\u52A1\u7BA1\u7406\u7CFB\u7EDF - AI Agent \u4EFB\u52A1\u8C03\u5EA6\u5668").version(getPackageVersion());
28243
- program2.command("add").description("\u521B\u5EFA\u65B0\u4EFB\u52A1").requiredOption("-n, --name <name>", "\u4EFB\u52A1\u540D\u79F0").requiredOption("-a, --agent <agent>", "\u4E3B Agent \u540D\u79F0").requiredOption("-p, --prompt <prompt>", "\u63D0\u793A\u8BCD").option("-m, --model <model>", "\u6A21\u578B").option("-c, --category <category>", "\u5206\u7C7B", "general").option("-i, --importance <number>", "\u91CD\u8981\u7A0B\u5EA6 (1-5)", "3").option("-u, --urgency <number>", "\u7D27\u6025\u7A0B\u5EA6 (1-5)", "3").option("-b, --batch <batchId>", "\u6279\u6B21 ID").option("-d, --depends <taskId>", "\u4F9D\u8D56\u7684\u4EFB\u52A1 ID").option("--max-retries <number>", "\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "3").option("--retry-backoff <duration>", "\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "30s").option("--timeout <duration>", "\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h").option("-w, --cwd <path>", "(\u5DF2\u5E9F\u5F03) \u5DE5\u4F5C\u76EE\u5F55\u3002\u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8BB0\u5F55\u63D0\u4EA4\u4EFB\u52A1\u65F6\u7684\u5F53\u524D\u76EE\u5F55").action(async (options) => withDb(async () => {
28474
+ program2.name("supertask").description(t2("\u9762\u5411 OpenCode Agent \u7684\u6301\u4E45\u5316\u4EFB\u52A1\u961F\u5217\u4E0E\u5B9A\u65F6\u4EFB\u52A1\u7CFB\u7EDF", "Durable task queue and scheduler for OpenCode agents")).addOption(new Option("--lang <language>", t2("CLI \u8BED\u8A00\uFF1Aauto / zh-CN / en", "CLI language: auto / zh-CN / en")).choices(["auto", "zh-CN", "en"]).default("auto")).helpOption("-h, --help", t2("\u663E\u793A\u5E2E\u52A9", "display help for command")).addHelpCommand("help [command]", t2("\u663E\u793A\u547D\u4EE4\u5E2E\u52A9", "display help for command")).version(getPackageVersion(), "-V, --version", t2("\u663E\u793A\u7248\u672C\u53F7", "output the version number"));
28475
+ if (cliLocale === "zh-CN") {
28476
+ program2.configureOutput({
28477
+ writeOut: (value) => process.stdout.write(value.replace(/^Usage:/gm, "\u7528\u6CD5\uFF1A").replace(/^Options:/gm, "\u9009\u9879\uFF1A").replace(/^Commands:/gm, "\u547D\u4EE4\uFF1A").replace(/^Arguments:/gm, "\u53C2\u6570\uFF1A"))
28478
+ });
28479
+ }
28480
+ program2.command("add").description(t2("\u521B\u5EFA\u65B0\u4EFB\u52A1", "create a queued task")).requiredOption("-n, --name <name>", t2("\u4EFB\u52A1\u540D\u79F0", "task name")).requiredOption("-a, --agent <agent>", t2("\u4E3B Agent \u540D\u79F0", "primary agent name")).requiredOption("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("-c, --category <category>", t2("\u5206\u7C7B", "category"), "general").option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 (1-5)", "importance (1-5)"), "3").option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 (1-5)", "urgency (1-5)"), "3").option("-b, --batch <batchId>", t2("\u6279\u6B21 ID", "batch ID")).option("-d, --depends <taskId>", t2("\u4F9D\u8D56\u7684\u4EFB\u52A1 ID", "dependency task ID")).option("--max-retries <number>", t2("\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "retries allowed after the first attempt"), "3").option("--retry-backoff <duration>", t2("\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min"), "30s").option("--timeout <duration>", t2("\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout, e.g. 30min / 2h")).option("-w, --cwd <path>", t2("(\u5DF2\u5E9F\u5F03) \u7CFB\u7EDF\u4F1A\u81EA\u52A8\u8BB0\u5F55\u63D0\u4EA4\u65F6\u7684\u5F53\u524D\u76EE\u5F55", "(deprecated) the submission directory is recorded automatically")).action(async (options) => withDb(async () => {
28244
28481
  const submitCwd = process.cwd();
28245
28482
  const retryBackoffMs = parseDuration(options.retryBackoff);
28246
28483
  const timeoutMs = options.timeout ? parseDuration(options.timeout) : null;
@@ -28264,7 +28501,7 @@ program2.command("add").description("\u521B\u5EFA\u65B0\u4EFB\u52A1").requiredOp
28264
28501
  });
28265
28502
  console.log(JSON.stringify({ id: task.id, status: "created" }, null, 2));
28266
28503
  }));
28267
- program2.command("edit").description("\u4FEE\u6539\u5F53\u524D\u9879\u76EE\u4E2D\u5C1A\u672A\u5B8C\u6210\u7684\u4EFB\u52A1").requiredOption("--id <id>", "\u4EFB\u52A1 ID").option("-n, --name <name>", "\u4EFB\u52A1\u540D\u79F0").option("-a, --agent <agent>", "Agent \u540D\u79F0").option("-m, --model <model>", "\u6A21\u578B").option("-p, --prompt <prompt>", "\u63D0\u793A\u8BCD").option("-c, --category <category>", "\u5206\u7C7B").option("-i, --importance <number>", "\u91CD\u8981\u7A0B\u5EA6 (1-5)").option("-u, --urgency <number>", "\u7D27\u6025\u7A0B\u5EA6 (1-5)").option("-b, --batch <batchId>", "\u6279\u6B21 ID").option("--clear-batch", "\u6E05\u7A7A\u6279\u6B21 ID").option("--max-retries <number>", "\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570").option("--retry-backoff <duration>", "\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min").option("--timeout <duration>", "\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h").option("--clear-timeout", "\u6E05\u7A7A\u4EFB\u52A1\u7EA7\u8D85\u65F6\uFF0C\u6539\u7528 Gateway \u9ED8\u8BA4\u503C").action(async (options) => withDb(async () => {
28504
+ program2.command("edit").description(t2("\u4FEE\u6539\u5F53\u524D\u9879\u76EE\u4E2D\u5C1A\u672A\u5B8C\u6210\u7684\u4EFB\u52A1", "edit an unfinished task in the current project")).requiredOption("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).option("-n, --name <name>", t2("\u4EFB\u52A1\u540D\u79F0", "task name")).option("-a, --agent <agent>", t2("Agent \u540D\u79F0", "agent name")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).option("-c, --category <category>", t2("\u5206\u7C7B", "category")).option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 (1-5)", "importance (1-5)")).option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 (1-5)", "urgency (1-5)")).option("-b, --batch <batchId>", t2("\u6279\u6B21 ID", "batch ID")).option("--clear-batch", t2("\u6E05\u7A7A\u6279\u6B21 ID", "clear the batch ID")).option("--max-retries <number>", t2("\u9996\u6B21\u6267\u884C\u4E4B\u5916\u5141\u8BB8\u7684\u91CD\u8BD5\u6B21\u6570", "retries allowed after the first attempt")).option("--retry-backoff <duration>", t2("\u91CD\u8BD5\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min")).option("--timeout <duration>", t2("\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout, e.g. 30min / 2h")).option("--clear-timeout", t2("\u6E05\u7A7A\u4EFB\u52A1\u7EA7\u8D85\u65F6\uFF0C\u6539\u7528 Gateway \u9ED8\u8BA4\u503C", "clear the task timeout and use the Gateway default")).action(async (options) => withDb(async () => {
28268
28505
  if (options.batch !== void 0 && options.clearBatch) {
28269
28506
  throw new Error("batch \u548C clear-batch \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
28270
28507
  }
@@ -28302,7 +28539,7 @@ program2.command("edit").description("\u4FEE\u6539\u5F53\u524D\u9879\u76EE\u4E2D
28302
28539
  if (!task) throw new Error(`\u4EFB\u52A1 #${id} \u4E0D\u5B58\u5728\u4E8E\u5F53\u524D\u9879\u76EE\uFF0C\u6216\u5176\u72B6\u6001\u4E0D\u5141\u8BB8\u7F16\u8F91`);
28303
28540
  console.log(JSON.stringify({ id: task.id, status: task.status, updated: true }, null, 2));
28304
28541
  }));
28305
- program2.command("next").description("\u83B7\u53D6\u4E0B\u4E00\u4E2A\u5F85\u6267\u884C\u7684\u4EFB\u52A1").action(async () => withDb(async () => {
28542
+ program2.command("next").description(t2("\u83B7\u53D6\u4E0B\u4E00\u4E2A\u5F85\u6267\u884C\u7684\u4EFB\u52A1", "show the next runnable task")).action(async () => withDb(async () => {
28306
28543
  const task = await TaskService.next({ cwd: process.cwd() });
28307
28544
  if (task) {
28308
28545
  console.log(JSON.stringify({
@@ -28320,7 +28557,7 @@ program2.command("next").description("\u83B7\u53D6\u4E0B\u4E00\u4E2A\u5F85\u6267
28320
28557
  console.log(JSON.stringify({ id: null, message: "No executable tasks" }));
28321
28558
  }
28322
28559
  }));
28323
- program2.command("cancel").description("\u53D6\u6D88\u4EFB\u52A1").requiredOption("--id <id>", "\u4EFB\u52A1 ID").action(async (options) => withDb(async () => {
28560
+ program2.command("cancel").description(t2("\u53D6\u6D88\u4EFB\u52A1", "cancel a task")).requiredOption("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).action(async (options) => withDb(async () => {
28324
28561
  const task = await TaskService.cancel(parsePositiveInteger(options.id, "id"), { cwd: process.cwd() });
28325
28562
  if (task) {
28326
28563
  console.log(JSON.stringify({ id: task.id, status: task.status }));
@@ -28329,8 +28566,8 @@ program2.command("cancel").description("\u53D6\u6D88\u4EFB\u52A1").requiredOptio
28329
28566
  process.exit(1);
28330
28567
  }
28331
28568
  }));
28332
- var runCommand = new Command("run").description("\u7BA1\u7406\u9694\u79BB\u7684\u6267\u884C\u8BB0\u5F55");
28333
- runCommand.command("abandon").description("\u4EBA\u5DE5\u5173\u95ED\u5DF2\u786E\u8BA4\u4E0D\u5B58\u5728\u9057\u7559\u8FDB\u7A0B\u7684\u65E7\u7248\u65E0 PID \u9694\u79BB\u8BB0\u5F55").requiredOption("--id <id>", "\u6267\u884C\u8BB0\u5F55 run ID").option("--confirm <word>", "\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 ABANDON").action(async (options) => withDb(async () => {
28569
+ var runCommand = new Command("run").description(t2("\u7BA1\u7406\u9694\u79BB\u7684\u6267\u884C\u8BB0\u5F55", "manage quarantined task runs"));
28570
+ runCommand.command("abandon").description(t2("\u4EBA\u5DE5\u5173\u95ED\u5DF2\u786E\u8BA4\u4E0D\u5B58\u5728\u9057\u7559\u8FDB\u7A0B\u7684\u65E7\u7248\u65E0 PID \u9694\u79BB\u8BB0\u5F55", "close a legacy no-PID quarantine after confirming no process remains")).requiredOption("--id <id>", t2("\u6267\u884C\u8BB0\u5F55 run ID", "run ID")).option("--confirm <word>", t2("\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 ABANDON", "confirmation word; must be ABANDON")).action(async (options) => withDb(async () => {
28334
28571
  if (options.confirm !== "ABANDON") {
28335
28572
  throw new Error("\u5173\u95ED\u65E7\u7248\u9694\u79BB run \u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --confirm ABANDON");
28336
28573
  }
@@ -28340,7 +28577,7 @@ runCommand.command("abandon").description("\u4EBA\u5DE5\u5173\u95ED\u5DF2\u786E\
28340
28577
  console.log(JSON.stringify(result, null, 2));
28341
28578
  }));
28342
28579
  program2.addCommand(runCommand);
28343
- program2.command("retry").description("\u91CD\u8BD5\u5931\u8D25\u7684\u4EFB\u52A1").option("--id <id>", "\u4EFB\u52A1 ID").option("-b, --batch <batchId>", "\u6279\u6B21 ID\uFF08\u6279\u91CF\u91CD\u8BD5\uFF09").action(async (options) => withDb(async () => {
28580
+ program2.command("retry").description(t2("\u91CD\u8BD5\u5931\u8D25\u7684\u4EFB\u52A1", "retry failed tasks")).option("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).option("-b, --batch <batchId>", t2("\u6279\u6B21 ID\uFF08\u6279\u91CF\u91CD\u8BD5\uFF09", "batch ID for bulk retry")).action(async (options) => withDb(async () => {
28344
28581
  if (options.id) {
28345
28582
  const task = await TaskService.retry(parsePositiveInteger(options.id, "id"), { cwd: process.cwd() });
28346
28583
  if (task) {
@@ -28357,11 +28594,11 @@ program2.command("retry").description("\u91CD\u8BD5\u5931\u8D25\u7684\u4EFB\u52A
28357
28594
  process.exit(1);
28358
28595
  }
28359
28596
  }));
28360
- program2.command("status").description("\u67E5\u770B\u4EFB\u52A1\u7EDF\u8BA1").option("-b, --batch <batchId>", "\u6309\u6279\u6B21\u7EDF\u8BA1").action(async (options) => withDb(async () => {
28597
+ program2.command("status").description(t2("\u67E5\u770B\u4EFB\u52A1\u7EDF\u8BA1", "show task counts")).option("-b, --batch <batchId>", t2("\u6309\u6279\u6B21\u7EDF\u8BA1", "filter counts by batch")).action(async (options) => withDb(async () => {
28361
28598
  const stats = await TaskService.stats({ batchId: options.batch, cwd: process.cwd() });
28362
28599
  console.log(JSON.stringify(stats, null, 2));
28363
28600
  }));
28364
- program2.command("list").description("\u5217\u51FA\u4EFB\u52A1").option("-s, --status <status>", "\u6309\u72B6\u6001\u7B5B\u9009").option("-b, --batch <batchId>", "\u6309\u6279\u6B21\u7B5B\u9009").option("-c, --category <category>", "\u6309\u5206\u7C7B\u7B5B\u9009").option("-l, --limit <number>", "\u9650\u5236\u6570\u91CF", "20").action(async (options) => withDb(async () => {
28601
+ program2.command("list").description(t2("\u5217\u51FA\u4EFB\u52A1", "list tasks")).option("-s, --status <status>", t2("\u6309\u72B6\u6001\u7B5B\u9009", "filter by status")).option("-b, --batch <batchId>", t2("\u6309\u6279\u6B21\u7B5B\u9009", "filter by batch")).option("-c, --category <category>", t2("\u6309\u5206\u7C7B\u7B5B\u9009", "filter by category")).option("-l, --limit <number>", t2("\u9650\u5236\u6570\u91CF", "maximum rows"), "20").action(async (options) => withDb(async () => {
28365
28602
  const tasks4 = await TaskService.list({
28366
28603
  status: parseTaskStatus(options.status),
28367
28604
  batchId: options.batch,
@@ -28371,7 +28608,7 @@ program2.command("list").description("\u5217\u51FA\u4EFB\u52A1").option("-s, --s
28371
28608
  });
28372
28609
  console.log(JSON.stringify(tasks4, null, 2));
28373
28610
  }));
28374
- program2.command("get").description("\u83B7\u53D6\u5355\u4E2A\u4EFB\u52A1\u8BE6\u60C5").requiredOption("--id <id>", "\u4EFB\u52A1 ID").action(async (options) => withDb(async () => {
28611
+ program2.command("get").description(t2("\u83B7\u53D6\u5355\u4E2A\u4EFB\u52A1\u8BE6\u60C5", "show one task")).requiredOption("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).action(async (options) => withDb(async () => {
28375
28612
  const task = await TaskService.getById(parsePositiveInteger(options.id, "id"), { cwd: process.cwd() });
28376
28613
  if (task) {
28377
28614
  console.log(JSON.stringify(task, null, 2));
@@ -28380,13 +28617,13 @@ program2.command("get").description("\u83B7\u53D6\u5355\u4E2A\u4EFB\u52A1\u8BE6\
28380
28617
  process.exit(1);
28381
28618
  }
28382
28619
  }));
28383
- program2.command("delete").description("\u5220\u9664\u4EFB\u52A1").requiredOption("--id <id>", "\u4EFB\u52A1 ID").action(async (options) => withDb(async () => {
28620
+ program2.command("delete").description(t2("\u5220\u9664\u4EFB\u52A1", "delete a task")).requiredOption("--id <id>", t2("\u4EFB\u52A1 ID", "task ID")).action(async (options) => withDb(async () => {
28384
28621
  const id = parsePositiveInteger(options.id, "id");
28385
28622
  const deleted = await TaskService.delete(id, { cwd: process.cwd() });
28386
28623
  console.log(JSON.stringify({ deleted, id }));
28387
28624
  }));
28388
- program2.command("template").description("\u7BA1\u7406\u4EFB\u52A1\u8C03\u5EA6\u6A21\u677F").addCommand(
28389
- new Command("add").description("\u521B\u5EFA\u8C03\u5EA6\u6A21\u677F").requiredOption("-n, --name <name>", "\u6A21\u677F\u540D\u79F0").requiredOption("-a, --agent <agent>", "Agent \u540D\u79F0").requiredOption("-p, --prompt <prompt>", "\u63D0\u793A\u8BCD").requiredOption("-t, --type <type>", "\u8C03\u5EA6\u7C7B\u578B\uFF1Acron/delayed/recurring").option("--cron <expr>", "cron \u8868\u8FBE\u5F0F\uFF08cron \u7C7B\u578B\u5FC5\u586B\uFF09").option("--delay <duration>", "\u5EF6\u8FDF\u65F6\u95F4\uFF08delayed \u7C7B\u578B\u5FC5\u586B\uFF09\uFF0C\u5982 30s / 5min / 1h / 2d").option("--interval <duration>", "\u5FAA\u73AF\u95F4\u9694\uFF08recurring \u7C7B\u578B\u5FC5\u586B\uFF09\uFF0C\u5982 1h / 30min / 5s").option("-m, --model <model>", "\u6A21\u578B").option("-c, --category <category>", "\u5206\u7C7B", "general").option("-i, --importance <number>", "\u91CD\u8981\u7A0B\u5EA6 1-5", "3").option("-u, --urgency <number>", "\u7D27\u6025\u7A0B\u5EA6 1-5", "3").option("-b, --batch <batchId>", "\u6A21\u677F\u751F\u6210\u4EFB\u52A1\u7684\u6279\u6B21 ID").option("--max-instances <number>", "\u81EA\u52A8\u8C03\u5EA6\u6D3B\u8DC3\u5B9E\u4F8B\u4E0A\u9650\uFF08\u624B\u52A8\u89E6\u53D1\u4E0D\u53D7\u9650\uFF09", "1").option("--max-retries <number>", "\u6700\u5927\u91CD\u8BD5\u6B21\u6570", "3").option("--retry-backoff <duration>", "\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "30s").option("--timeout <duration>", "\u6BCF\u6B21\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h").action(async (options) => withDb(async () => {
28625
+ program2.command("template").description(t2("\u7BA1\u7406\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "manage scheduled task templates")).addCommand(
28626
+ new Command("add").description(t2("\u521B\u5EFA\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "create a scheduled task template")).requiredOption("-n, --name <name>", t2("\u6A21\u677F\u540D\u79F0", "template name")).requiredOption("-a, --agent <agent>", t2("Agent \u540D\u79F0", "agent name")).requiredOption("-p, --prompt <prompt>", t2("\u63D0\u793A\u8BCD", "prompt")).requiredOption("-t, --type <type>", t2("\u5B9A\u65F6\u7C7B\u578B\uFF1Acron/delayed/recurring", "schedule type: cron/delayed/recurring")).option("--cron <expr>", t2("cron \u8868\u8FBE\u5F0F\uFF08cron \u7C7B\u578B\u5FC5\u586B\uFF09", "cron expression (required for cron)")).option("--delay <duration>", t2("\u5EF6\u8FDF\u65F6\u95F4\uFF08delayed \u5FC5\u586B\uFF09\uFF0C\u5982 30s / 5min / 1h / 2d", "delay (required for delayed), e.g. 30s / 5min / 1h / 2d")).option("--interval <duration>", t2("\u5FAA\u73AF\u95F4\u9694\uFF08recurring \u5FC5\u586B\uFF09\uFF0C\u5982 1h / 30min / 5s", "interval (required for recurring), e.g. 1h / 30min / 5s")).option("-m, --model <model>", t2("\u6A21\u578B", "model")).option("-c, --category <category>", t2("\u5206\u7C7B", "category"), "general").option("-i, --importance <number>", t2("\u91CD\u8981\u7A0B\u5EA6 1-5", "importance 1-5"), "3").option("-u, --urgency <number>", t2("\u7D27\u6025\u7A0B\u5EA6 1-5", "urgency 1-5"), "3").option("-b, --batch <batchId>", t2("\u6A21\u677F\u751F\u6210\u4EFB\u52A1\u7684\u6279\u6B21 ID", "batch ID for generated tasks")).option("--max-instances <number>", t2("\u81EA\u52A8\u5B9A\u65F6\u4EFB\u52A1\u7684\u6D3B\u8DC3\u5B9E\u4F8B\u4E0A\u9650\uFF08\u7ACB\u5373\u89E6\u53D1\u4E0D\u53D7\u9650\uFF09", "active instance limit for automatic scheduling (Run now is unrestricted)"), "1").option("--max-retries <number>", t2("\u6700\u5927\u91CD\u8BD5\u6B21\u6570", "maximum retries"), "3").option("--retry-backoff <duration>", t2("\u9000\u907F\u57FA\u7840\u95F4\u9694\uFF0C\u5982 30s / 5min", "retry backoff base, e.g. 30s / 5min"), "30s").option("--timeout <duration>", t2("\u6BCF\u6B21\u4EFB\u52A1\u786C\u8D85\u65F6\uFF0C\u5982 30min / 2h", "hard timeout per task, e.g. 30min / 2h")).action(async (options) => withDb(async () => {
28390
28627
  let intervalMs = null;
28391
28628
  let runAt = null;
28392
28629
  const retryBackoffMs = parseDuration(options.retryBackoff);
@@ -28431,12 +28668,12 @@ program2.command("template").description("\u7BA1\u7406\u4EFB\u52A1\u8C03\u5EA6\u
28431
28668
  console.log(JSON.stringify({ id: tmpl.id, status: "created", nextRunAt: tmpl.nextRunAt }, null, 2));
28432
28669
  }))
28433
28670
  ).addCommand(
28434
- new Command("list").description("\u5217\u51FA\u8C03\u5EA6\u6A21\u677F").action(async () => withDb(async () => {
28671
+ new Command("list").description(t2("\u5217\u51FA\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "list scheduled task templates")).action(async () => withDb(async () => {
28435
28672
  const templates = await TaskTemplateService.list();
28436
28673
  console.log(JSON.stringify(templates, null, 2));
28437
28674
  }))
28438
28675
  ).addCommand(
28439
- new Command("enable").description("\u542F\u7528\u6A21\u677F").requiredOption("--id <id>", "\u6A21\u677F ID").action(async (options) => withDb(async () => {
28676
+ new Command("enable").description(t2("\u542F\u7528\u6A21\u677F", "enable a template")).requiredOption("--id <id>", t2("\u6A21\u677F ID", "template ID")).action(async (options) => withDb(async () => {
28440
28677
  const tmpl = await TaskTemplateService.enable(parsePositiveInteger(options.id, "id"));
28441
28678
  if (tmpl) {
28442
28679
  console.log(JSON.stringify({ id: tmpl.id, enabled: true }));
@@ -28446,7 +28683,7 @@ program2.command("template").description("\u7BA1\u7406\u4EFB\u52A1\u8C03\u5EA6\u
28446
28683
  }
28447
28684
  }))
28448
28685
  ).addCommand(
28449
- new Command("disable").description("\u7981\u7528\u6A21\u677F").requiredOption("--id <id>", "\u6A21\u677F ID").action(async (options) => withDb(async () => {
28686
+ new Command("disable").description(t2("\u7981\u7528\u6A21\u677F", "disable a template")).requiredOption("--id <id>", t2("\u6A21\u677F ID", "template ID")).action(async (options) => withDb(async () => {
28450
28687
  const tmpl = await TaskTemplateService.disable(parsePositiveInteger(options.id, "id"));
28451
28688
  if (tmpl) {
28452
28689
  console.log(JSON.stringify({ id: tmpl.id, enabled: false }));
@@ -28456,23 +28693,23 @@ program2.command("template").description("\u7BA1\u7406\u4EFB\u52A1\u8C03\u5EA6\u
28456
28693
  }
28457
28694
  }))
28458
28695
  ).addCommand(
28459
- new Command("delete").description("\u5220\u9664\u6A21\u677F").requiredOption("--id <id>", "\u6A21\u677F ID").action(async (options) => withDb(async () => {
28696
+ new Command("delete").description(t2("\u5220\u9664\u6A21\u677F", "delete a template")).requiredOption("--id <id>", t2("\u6A21\u677F ID", "template ID")).action(async (options) => withDb(async () => {
28460
28697
  const id = parsePositiveInteger(options.id, "id");
28461
28698
  const deleted = await TaskTemplateService.delete(id);
28462
28699
  console.log(JSON.stringify({ deleted, id }));
28463
28700
  }))
28464
28701
  );
28465
- var databaseCommand = new Command("db").description("\u6570\u636E\u5E93\u68C0\u67E5\u3001\u5907\u4EFD\u3001\u6E05\u7A7A\u4E0E\u6062\u590D");
28466
- 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 () => {
28702
+ var databaseCommand = new Command("db").description(t2("\u6570\u636E\u5E93\u68C0\u67E5\u3001\u5907\u4EFD\u3001\u6E05\u7A7A\u4E0E\u6062\u590D", "check, back up, clear, and restore the database"));
28703
+ databaseCommand.command("check").description(t2("\u68C0\u67E5\u6570\u636E\u5E93\u5B8C\u6574\u6027\u3001\u5916\u952E\u548C\u4E1A\u52A1\u8868\u7EDF\u8BA1", "check integrity, foreign keys, and table counts")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09", "force JSON output (already the default when non-interactive)")).action(async (options) => withDb(async () => {
28467
28704
  const result = DatabaseMaintenanceService.check();
28468
- console.log(renderDatabaseResult("check", result, { forceJson: options.json }));
28705
+ console.log(renderDatabaseResult("check", result, { forceJson: options.json, locale: cliLocale }));
28469
28706
  if (!result.ok) process.exitCode = 1;
28470
28707
  }, (error) => renderDatabaseError(error, { forceJson: options.json })));
28471
- 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 () => {
28708
+ databaseCommand.command("backup").description(t2("\u521B\u5EFA\u7ECF\u8FC7\u5B8C\u6574\u6027\u6821\u9A8C\u7684\u4E00\u81F4\u6027\u5907\u4EFD", "create a consistent, integrity-checked backup")).option("-o, --output <path>", t2("\u5907\u4EFD\u6587\u4EF6\u8DEF\u5F84\uFF08\u9ED8\u8BA4\u5199\u5165\u6570\u636E\u5E93\u76EE\u5F55\uFF09", "backup path (defaults to the database directory)")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09", "force JSON output (already the default when non-interactive)")).action(async (options) => withDb(async () => {
28472
28709
  const result = DatabaseMaintenanceService.backup(options.output);
28473
- console.log(renderDatabaseResult("backup", result, { forceJson: options.json }));
28710
+ console.log(renderDatabaseResult("backup", result, { forceJson: options.json, locale: cliLocale }));
28474
28711
  }, (error) => renderDatabaseError(error, { forceJson: options.json })));
28475
- 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 () => {
28712
+ databaseCommand.command("clear").description(t2("\u5907\u4EFD\u540E\u4E8B\u52A1\u6027\u6E05\u7A7A\u4EFB\u52A1\u3001\u6267\u884C\u8BB0\u5F55\u548C\u5B9A\u65F6\u4EFB\u52A1\u6A21\u677F", "back up, then transactionally clear tasks, runs, and scheduled templates")).option("--confirm <word>", t2("\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 CLEAR", "confirmation word; must be CLEAR")).option("--keep-stopped", t2("\u7EF4\u62A4\u7ED3\u675F\u540E\u4E0D\u91CD\u542F\u539F\u672C\u7531 PM2 \u7BA1\u7406\u7684 Gateway", "leave a previously managed Gateway stopped")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09", "force JSON output (already the default when non-interactive)")).action(async (options) => withDb(async () => {
28476
28713
  if (options.confirm !== "CLEAR") {
28477
28714
  throw new Error("\u6E05\u7A7A\u6570\u636E\u5E93\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --confirm CLEAR");
28478
28715
  }
@@ -28480,9 +28717,9 @@ databaseCommand.command("clear").description("\u5907\u4EFD\u540E\u4E8B\u52A1\u60
28480
28717
  options.keepStopped ?? false,
28481
28718
  () => DatabaseMaintenanceService.clear()
28482
28719
  );
28483
- console.log(renderDatabaseResult("clear", result, { forceJson: options.json }));
28720
+ console.log(renderDatabaseResult("clear", result, { forceJson: options.json, locale: cliLocale }));
28484
28721
  }, (error) => renderDatabaseError(error, { forceJson: options.json })));
28485
- 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 () => {
28722
+ databaseCommand.command("restore").description(t2("\u81EA\u52A8\u5907\u4EFD\u5F53\u524D\u5E93\u540E\uFF0C\u4ECE\u6307\u5B9A\u5907\u4EFD\u6062\u590D\u6570\u636E\u5E93", "back up the live database, then restore from a backup")).requiredOption("--from <path>", t2("\u8981\u6062\u590D\u7684 SQLite \u5907\u4EFD\u6587\u4EF6", "SQLite backup to restore")).option("--confirm <word>", t2("\u5371\u9669\u64CD\u4F5C\u786E\u8BA4\uFF0C\u5FC5\u987B\u586B\u5199 RESTORE", "confirmation word; must be RESTORE")).option("--keep-stopped", t2("\u7EF4\u62A4\u7ED3\u675F\u540E\u4E0D\u91CD\u542F\u539F\u672C\u7531 PM2 \u7BA1\u7406\u7684 Gateway", "leave a previously managed Gateway stopped")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON\uFF08\u975E\u4EA4\u4E92\u8C03\u7528\u9ED8\u8BA4\u5DF2\u8F93\u51FA JSON\uFF09", "force JSON output (already the default when non-interactive)")).action(async (options) => withDb(async () => {
28486
28723
  if (options.confirm !== "RESTORE") {
28487
28724
  throw new Error("\u6062\u590D\u6570\u636E\u5E93\u5FC5\u987B\u663E\u5F0F\u4F20\u5165 --confirm RESTORE");
28488
28725
  }
@@ -28490,16 +28727,16 @@ databaseCommand.command("restore").description("\u81EA\u52A8\u5907\u4EFD\u5F53\u
28490
28727
  options.keepStopped ?? false,
28491
28728
  () => DatabaseMaintenanceService.restore(options.from)
28492
28729
  );
28493
- console.log(renderDatabaseResult("restore", result, { forceJson: options.json }));
28730
+ console.log(renderDatabaseResult("restore", result, { forceJson: options.json, locale: cliLocale }));
28494
28731
  }, (error) => renderDatabaseError(error, { forceJson: options.json })));
28495
28732
  program2.addCommand(databaseCommand);
28496
- program2.command("init").description("Initialize SuperTask (create config + run migrations)").action(async () => withDb(async () => {
28733
+ program2.command("init").description(t2("\u521D\u59CB\u5316 SuperTask\uFF08\u521B\u5EFA\u914D\u7F6E\u5E76\u6267\u884C\u8FC1\u79FB\uFF09", "initialize SuperTask (create config and run migrations)")).action(async () => withDb(async () => {
28497
28734
  const { existsSync: existsSync9, mkdirSync: mkdirSync6, writeFileSync: writeFileSync4 } = await import("fs");
28498
- const { dirname: dirname9 } = await import("path");
28735
+ const { dirname: dirname10 } = await import("path");
28499
28736
  const { getConfigPath: getConfigPath2 } = await Promise.resolve().then(() => (init_config(), config_exports));
28500
28737
  const configPath = getConfigPath2();
28501
28738
  if (!existsSync9(configPath)) {
28502
- const dir = dirname9(configPath);
28739
+ const dir = dirname10(configPath);
28503
28740
  if (!existsSync9(dir)) mkdirSync6(dir, { recursive: true });
28504
28741
  writeFileSync4(configPath, JSON.stringify({
28505
28742
  configVersion: 2,
@@ -28514,16 +28751,16 @@ program2.command("init").description("Initialize SuperTask (create config + run
28514
28751
  getDb2();
28515
28752
  console.log(JSON.stringify({ migrated: true }));
28516
28753
  }));
28517
- program2.command("migrate").description("Run database migrations").action(async () => withDb(async () => {
28754
+ program2.command("migrate").description(t2("\u6267\u884C\u6570\u636E\u5E93\u8FC1\u79FB", "run database migrations")).action(async () => withDb(async () => {
28518
28755
  const { getDb: getDb2 } = await Promise.resolve().then(() => (init_db2(), db_exports));
28519
28756
  getDb2();
28520
28757
  console.log(JSON.stringify({ migrated: true }));
28521
28758
  }));
28522
- program2.command("gateway").description("Start the Gateway process (foreground)").action(async () => {
28759
+ program2.command("gateway").description(t2("\u5728\u524D\u53F0\u542F\u52A8 Gateway", "start the Gateway in the foreground")).action(async () => {
28523
28760
  const { main: main2 } = await Promise.resolve().then(() => (init_gateway(), gateway_exports));
28524
28761
  await main2();
28525
28762
  });
28526
- program2.command("ui").description("Open Web Dashboard (embedded in Gateway)").action(async () => {
28763
+ program2.command("ui").description(t2("\u6253\u5F00 Gateway \u5185\u7F6E\u7684 Web \u7BA1\u7406\u754C\u9762", "open the Web Dashboard embedded in the Gateway")).action(async () => {
28527
28764
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
28528
28765
  const cfg = loadConfig2();
28529
28766
  const url = `http://localhost:${cfg.dashboard.port}`;
@@ -28535,19 +28772,19 @@ program2.command("ui").description("Open Web Dashboard (embedded in Gateway)").a
28535
28772
  } catch {
28536
28773
  }
28537
28774
  });
28538
- program2.command("config").description("Show current configuration").action(async () => {
28775
+ program2.command("config").description(t2("\u663E\u793A\u5F53\u524D\u914D\u7F6E", "show the current configuration")).action(async () => {
28539
28776
  const { loadConfig: loadConfig2 } = await Promise.resolve().then(() => (init_config(), config_exports));
28540
28777
  const cfg = loadConfig2();
28541
28778
  console.log(JSON.stringify(cfg, null, 2));
28542
28779
  });
28543
- program2.command("doctor").description("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\u5E93\u3001Gateway\u3001Dashboard \u548C\u65E5\u5FD7\u8F6E\u8F6C").option("--json", "\u5F3A\u5236\u8F93\u51FA JSON").action(async (options) => withDb(async () => {
28780
+ program2.command("doctor").description(t2("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\u5E93\u3001Gateway\u3001Web \u754C\u9762\u548C\u65E5\u5FD7\u8F6E\u8F6C", "diagnose OpenCode, database, Gateway, Dashboard, and log rotation")).option("--json", t2("\u5F3A\u5236\u8F93\u51FA JSON", "force JSON output")).action(async (options) => withDb(async () => {
28544
28781
  const config = loadConfig();
28545
28782
  const database = DatabaseMaintenanceService.check();
28546
28783
  const legacyQuarantinedRuns = await TaskRunService.listLegacyQuarantinedRuns(
28547
28784
  config.watchdog.heartbeatTimeoutMs
28548
28785
  );
28549
28786
  const gateway = getGatewayDiagnostic();
28550
- const packageVersion = getPackageVersion();
28787
+ const packageVersion2 = getPackageVersion();
28551
28788
  const opencodeBin2 = process.env.SUPERTASK_OPENCODE_BIN ?? "opencode";
28552
28789
  const opencodeResult = spawnSync4(opencodeBin2, ["--version"], {
28553
28790
  encoding: "utf8",
@@ -28557,7 +28794,7 @@ program2.command("doctor").description("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\
28557
28794
  ok: opencodeResult.status === 0,
28558
28795
  executable: opencodeBin2,
28559
28796
  version: opencodeResult.status === 0 ? opencodeResult.stdout.trim() : null,
28560
- error: opencodeResult.status === 0 ? null : opencodeResult.error?.message || opencodeResult.stderr.trim() || `\u9000\u51FA\u7801 ${opencodeResult.status}`
28797
+ error: opencodeResult.status === 0 ? null : opencodeResult.error?.message || opencodeResult.stderr.trim() || t2(`\u9000\u51FA\u7801 ${opencodeResult.status}`, `exit code ${opencodeResult.status}`)
28561
28798
  };
28562
28799
  const plugin = getOpenCodePluginDiagnostic();
28563
28800
  let dashboard = {
@@ -28582,44 +28819,68 @@ program2.command("doctor").description("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\
28582
28819
  const gatewayEntryPinned = gateway.gatewayEntry === null || !/[\\/]opencode-supertask@(latest|next)[\\/]/.test(gateway.gatewayEntry);
28583
28820
  const gatewayVersionMatchesPackage = gateway.gatewayPackageVersion !== null && gateway.runningVersion === gateway.gatewayPackageVersion;
28584
28821
  const configuredVersionsMatch = plugin.ok && plugin.version === gateway.gatewayPackageVersion;
28822
+ const cliVersionMatchesPlugin = plugin.ok && plugin.version === packageVersion2;
28585
28823
  if (!plugin.ok && plugin.error) {
28586
28824
  warnings.push(plugin.error);
28587
28825
  }
28588
- if (plugin.version !== null && plugin.version !== packageVersion) {
28589
- warnings.push(`\u5F53\u524D CLI v${packageVersion} \u4E0E OpenCode \u63D2\u4EF6 v${plugin.version} \u4E0D\u4E00\u81F4\uFF1B\u8BF7\u7528\u539F\u5305\u7BA1\u7406\u5668\u5168\u5C40\u5B89\u88C5 opencode-supertask@${plugin.version}\uFF08npm install -g \u6216 bun add -g\uFF09`);
28826
+ if (plugin.version !== null && plugin.version !== packageVersion2) {
28827
+ warnings.push(t2(
28828
+ `\u5F53\u524D CLI v${packageVersion2} \u4E0E OpenCode \u63D2\u4EF6 v${plugin.version} \u4E0D\u4E00\u81F4\uFF1B\u6267\u884C supertask upgrade \u8BA9 CLI\u3001\u63D2\u4EF6\u548C Gateway \u6536\u655B\u5230\u540C\u4E00\u7CBE\u786E\u7248\u672C`,
28829
+ `CLI v${packageVersion2} does not match OpenCode plugin v${plugin.version}; run supertask upgrade to converge the CLI, plugin, and Gateway on one exact version`
28830
+ ));
28590
28831
  }
28591
28832
  if (!gatewayEntryPinned) {
28592
- warnings.push(`PM2 Gateway \u4ECD\u4ECE\u6D6E\u52A8\u7F13\u5B58\u8DEF\u5F84\u542F\u52A8\uFF1A${gateway.gatewayEntry}`);
28833
+ warnings.push(t2(
28834
+ `PM2 Gateway \u4ECD\u4ECE\u6D6E\u52A8\u7F13\u5B58\u8DEF\u5F84\u542F\u52A8\uFF1A${gateway.gatewayEntry}`,
28835
+ `The PM2 Gateway still starts from a floating cache path: ${gateway.gatewayEntry}`
28836
+ ));
28593
28837
  }
28594
28838
  if (gateway.processFound && gateway.gatewayPackageVersion === null) {
28595
- warnings.push(`\u65E0\u6CD5\u4ECE PM2 Gateway \u5165\u53E3\u786E\u8BA4 opencode-supertask \u5305\u7248\u672C\uFF1A${gateway.gatewayEntry ?? "unknown"}`);
28839
+ warnings.push(t2(
28840
+ `\u65E0\u6CD5\u4ECE PM2 Gateway \u5165\u53E3\u786E\u8BA4 opencode-supertask \u5305\u7248\u672C\uFF1A${gateway.gatewayEntry ?? "unknown"}`,
28841
+ `Could not determine the opencode-supertask package version from the PM2 Gateway entry: ${gateway.gatewayEntry ?? "unknown"}`
28842
+ ));
28596
28843
  } else if (gateway.processFound && !gatewayVersionMatchesPackage) {
28597
- warnings.push(`Gateway ready \u9501\u7248\u672C ${gateway.runningVersion ?? "unknown"} \u4E0E\u5165\u53E3\u5305\u7248\u672C ${gateway.gatewayPackageVersion ?? "unknown"} \u4E0D\u4E00\u81F4`);
28844
+ warnings.push(t2(
28845
+ `Gateway ready \u9501\u7248\u672C ${gateway.runningVersion ?? "unknown"} \u4E0E\u5165\u53E3\u5305\u7248\u672C ${gateway.gatewayPackageVersion ?? "unknown"} \u4E0D\u4E00\u81F4`,
28846
+ `Gateway ready-lock version ${gateway.runningVersion ?? "unknown"} does not match entry package version ${gateway.gatewayPackageVersion ?? "unknown"}`
28847
+ ));
28598
28848
  }
28599
28849
  if (plugin.version !== null && gateway.gatewayPackageVersion !== null && plugin.version !== gateway.gatewayPackageVersion) {
28600
- warnings.push(`OpenCode \u63D2\u4EF6 v${plugin.version} \u4E0E PM2 Gateway v${gateway.gatewayPackageVersion} \u4E0D\u4E00\u81F4\uFF1B\u6267\u884C supertask upgrade`);
28850
+ warnings.push(t2(
28851
+ `OpenCode \u63D2\u4EF6 v${plugin.version} \u4E0E PM2 Gateway v${gateway.gatewayPackageVersion} \u4E0D\u4E00\u81F4\uFF1B\u6267\u884C supertask upgrade`,
28852
+ `OpenCode plugin v${plugin.version} does not match PM2 Gateway v${gateway.gatewayPackageVersion}; run supertask upgrade`
28853
+ ));
28601
28854
  }
28602
28855
  if (gateway.pm2Installed && !gateway.logRotationInstalled) {
28603
- warnings.push("\u672A\u68C0\u6D4B\u5230 pm2-logrotate\uFF1B\u957F\u671F\u8FD0\u884C\u524D\u5EFA\u8BAE\u5B89\u88C5\u5E76\u9650\u5236\u65E5\u5FD7\u4FDD\u7559\u91CF");
28856
+ warnings.push(t2(
28857
+ "\u672A\u68C0\u6D4B\u5230 pm2-logrotate\uFF1B\u957F\u671F\u8FD0\u884C\u524D\u5EFA\u8BAE\u5B89\u88C5\u5E76\u9650\u5236\u65E5\u5FD7\u4FDD\u7559\u91CF",
28858
+ "pm2-logrotate was not detected; install it and limit log retention before long-running use"
28859
+ ));
28604
28860
  }
28605
28861
  if (gateway.startupConfigured === false) {
28606
- warnings.push(process.platform === "linux" ? "\u672A\u68C0\u6D4B\u5230\u5DF2\u542F\u7528\u4E14\u5305\u542B\u53EF\u6062\u590D PM2 dump \u7684 systemd \u81EA\u542F\u670D\u52A1" : "\u672A\u68C0\u6D4B\u5230\u6B63\u5728\u8FD0\u884C\u4E14\u5305\u542B\u53EF\u6062\u590D PM2 dump \u7684 macOS LaunchAgent");
28862
+ warnings.push(process.platform === "linux" ? t2("\u672A\u68C0\u6D4B\u5230\u5DF2\u542F\u7528\u4E14\u5305\u542B\u53EF\u6062\u590D PM2 dump \u7684 systemd \u81EA\u542F\u670D\u52A1", "No enabled systemd startup service with a recoverable PM2 dump was detected") : t2("\u672A\u68C0\u6D4B\u5230\u6B63\u5728\u8FD0\u884C\u4E14\u5305\u542B\u53EF\u6062\u590D PM2 dump \u7684 macOS LaunchAgent", "No running macOS LaunchAgent with a recoverable PM2 dump was detected"));
28607
28863
  }
28608
28864
  if (gateway.processFound && !gateway.scopeMatches) {
28609
- warnings.push("\u5F53\u524D CLI/OpenCode \u4E0E PM2 Gateway \u7684\u6570\u636E\u5E93\u3001\u914D\u7F6E\u6216 OpenCode \u53EF\u6267\u884C\u6587\u4EF6\u4F5C\u7528\u57DF\u4E0D\u4E00\u81F4");
28865
+ warnings.push(t2(
28866
+ "\u5F53\u524D CLI/OpenCode \u4E0E PM2 Gateway \u7684\u6570\u636E\u5E93\u3001\u914D\u7F6E\u6216 OpenCode \u53EF\u6267\u884C\u6587\u4EF6\u4F5C\u7528\u57DF\u4E0D\u4E00\u81F4",
28867
+ "The current CLI/OpenCode database, config, or OpenCode executable scope does not match the PM2 Gateway"
28868
+ ));
28610
28869
  }
28611
28870
  for (const run of legacyQuarantinedRuns) {
28612
- const cwdHint = run.taskCwd == null ? "\uFF08\u65E7\u4EFB\u52A1\u6CA1\u6709 cwd\uFF0C\u8BF7\u5148\u5728 Dashboard \u53D6\u6D88\uFF09" : `\uFF08\u5728 ${run.taskCwd} \u6267\u884C\uFF09`;
28613
- const cancel = run.taskStatus === "cancelled" ? "" : `\u5148${cwdHint} supertask cancel --id ${run.taskId}\uFF1B`;
28614
- const owner = run.ownerAlive ? `owner PID ${run.workerPid} \u4ECD\u5B58\u6D3B\uFF0C\u5148\u786E\u8BA4\u5E76\u505C\u6B62\u5BF9\u5E94\u8FDB\u7A0B\uFF1B` : "";
28615
- warnings.push(
28616
- `\u65E7\u7248\u9694\u79BB run #${run.runId}\uFF1A${owner}${cancel}\u786E\u8BA4\u6CA1\u6709\u9057\u7559 OpenCode \u8FDB\u7A0B\u540E\u6267\u884C supertask run abandon --id ${run.runId} --confirm ABANDON`
28617
- );
28618
- }
28619
- const ok = opencode.ok && plugin.ok && database.ok && legacyQuarantinedRuns.length === 0 && gateway.pm2Installed && gateway.status === "online" && gateway.ready && gatewayEntryPinned && gatewayVersionMatchesPackage && configuredVersionsMatch && gateway.scopeMatches && gateway.logRotationInstalled && gateway.startupConfigured !== false && dashboard.ok;
28871
+ const cwdHint = run.taskCwd == null ? t2("\uFF08\u65E7\u4EFB\u52A1\u6CA1\u6709 cwd\uFF0C\u8BF7\u5148\u5728 Dashboard \u53D6\u6D88\uFF09", " (the legacy task has no cwd; cancel it in the Dashboard first)") : t2(`\uFF08\u5728 ${run.taskCwd} \u6267\u884C\uFF09`, ` (run in ${run.taskCwd})`);
28872
+ const cancel = run.taskStatus === "cancelled" ? "" : t2(`\u5148${cwdHint} supertask cancel --id ${run.taskId}\uFF1B`, `first${cwdHint}: supertask cancel --id ${run.taskId}; `);
28873
+ const owner = run.ownerAlive ? t2(`owner PID ${run.workerPid} \u4ECD\u5B58\u6D3B\uFF0C\u5148\u786E\u8BA4\u5E76\u505C\u6B62\u5BF9\u5E94\u8FDB\u7A0B\uFF1B`, `owner PID ${run.workerPid} is still alive; confirm and stop it first; `) : "";
28874
+ warnings.push(t2(
28875
+ `\u65E7\u7248\u9694\u79BB run #${run.runId}\uFF1A${owner}${cancel}\u786E\u8BA4\u6CA1\u6709\u9057\u7559 OpenCode \u8FDB\u7A0B\u540E\u6267\u884C supertask run abandon --id ${run.runId} --confirm ABANDON`,
28876
+ `Legacy quarantined run #${run.runId}: ${owner}${cancel}after confirming no OpenCode process remains, run supertask run abandon --id ${run.runId} --confirm ABANDON`
28877
+ ));
28878
+ }
28879
+ const ok = opencode.ok && plugin.ok && database.ok && legacyQuarantinedRuns.length === 0 && gateway.pm2Installed && gateway.status === "online" && gateway.ready && gatewayEntryPinned && gatewayVersionMatchesPackage && configuredVersionsMatch && cliVersionMatchesPlugin && gateway.scopeMatches && gateway.logRotationInstalled && gateway.startupConfigured !== false && dashboard.ok;
28620
28880
  const report = {
28621
28881
  ok,
28622
- packageVersion,
28882
+ packageVersion: packageVersion2,
28883
+ cliVersionMatchesPlugin,
28623
28884
  configPath: getConfigPath(),
28624
28885
  opencode,
28625
28886
  plugin,
@@ -28634,17 +28895,17 @@ program2.command("doctor").description("\u68C0\u67E5 OpenCode\u3001\u6570\u636E\
28634
28895
  console.log(JSON.stringify(report, null, 2));
28635
28896
  } else {
28636
28897
  const mark = (value) => value ? "\u2713" : "\u2717";
28637
- console.log(`SuperTask doctor: ${ok ? "\u6B63\u5E38" : "\u5F02\u5E38"}`);
28638
- console.log(`${mark(opencode.ok)} OpenCode ${opencode.version ?? opencode.error ?? "\u4E0D\u53EF\u7528"}`);
28639
- console.log(`${mark(plugin.ok)} OpenCode \u63D2\u4EF6 ${plugin.spec || plugin.error || "\u672A\u914D\u7F6E"}${plugin.cachedVersion ? `\uFF08\u7F13\u5B58 v${plugin.cachedVersion}\uFF09` : ""}`);
28640
- console.log(`${mark(database.ok)} \u6570\u636E\u5E93 ${database.path}\uFF08\u4EFB\u52A1 ${database.counts.tasks}\uFF0C\u8FD0\u884C\u4E2D ${database.runningTasks}\uFF09`);
28898
+ console.log(`SuperTask doctor: ${ok ? t2("\u6B63\u5E38", "healthy") : t2("\u5F02\u5E38", "unhealthy")}`);
28899
+ console.log(`${mark(opencode.ok)} OpenCode ${opencode.version ?? opencode.error ?? t2("\u4E0D\u53EF\u7528", "unavailable")}`);
28900
+ console.log(`${mark(plugin.ok)} ${t2("OpenCode \u63D2\u4EF6", "OpenCode plugin")} ${plugin.spec || plugin.error || t2("\u672A\u914D\u7F6E", "not configured")}${plugin.cachedVersion ? t2(`\uFF08\u7F13\u5B58 v${plugin.cachedVersion}\uFF09`, ` (cached v${plugin.cachedVersion})`) : ""}`);
28901
+ console.log(`${mark(database.ok)} ${t2("\u6570\u636E\u5E93", "Database")} ${database.path}${t2(`\uFF08\u4EFB\u52A1 ${database.counts.tasks}\uFF0C\u8FD0\u884C\u4E2D ${database.runningTasks}\uFF09`, ` (tasks ${database.counts.tasks}, running ${database.runningTasks})`)}`);
28641
28902
  console.log(`${mark(gateway.status === "online" && gateway.ready && gatewayEntryPinned && gatewayVersionMatchesPackage)} Gateway ${gateway.status ?? "missing"}${gateway.pid ? `\uFF0CPID ${gateway.pid}` : ""}${gateway.runningVersion ? `\uFF0Cv${gateway.runningVersion}` : ""}${gateway.gatewayEntry ? `\uFF0C${gateway.gatewayEntry}` : ""}`);
28642
- console.log(`${mark(dashboard.ok)} Dashboard ${dashboard.enabled ? dashboard.url : "\u5DF2\u7981\u7528"}`);
28903
+ console.log(`${mark(dashboard.ok)} Dashboard ${dashboard.enabled ? dashboard.url : t2("\u5DF2\u7981\u7528", "disabled")}`);
28643
28904
  for (const warning of warnings) console.log(`! ${warning}`);
28644
28905
  }
28645
28906
  if (!ok) process.exitCode = 1;
28646
28907
  }));
28647
- program2.command("install").description("Install Gateway as pm2 service (auto-start, crash recovery, log rotation)").action(async () => {
28908
+ program2.command("install").description(t2("\u7528 PM2 \u5B89\u88C5 Gateway\uFF08\u5F00\u673A\u542F\u52A8\u3001\u5D29\u6E83\u6062\u590D\u3001\u65E5\u5FD7\u8F6E\u8F6C\uFF09", "install the Gateway with PM2 (startup, crash recovery, log rotation)")).action(async () => {
28648
28909
  try {
28649
28910
  const { install: pm2Install } = await Promise.resolve().then(() => (init_pm2(), pm2_exports));
28650
28911
  pm2Install();
@@ -28653,7 +28914,7 @@ program2.command("install").description("Install Gateway as pm2 service (auto-st
28653
28914
  process.exit(1);
28654
28915
  }
28655
28916
  });
28656
- program2.command("uninstall").description("Stop and remove Gateway pm2 service").action(async () => {
28917
+ program2.command("uninstall").description(t2("\u505C\u6B62\u5E76\u79FB\u9664 PM2 Gateway", "stop and remove the PM2 Gateway")).action(async () => {
28657
28918
  try {
28658
28919
  const { uninstall: pm2Uninstall } = await Promise.resolve().then(() => (init_pm2(), pm2_exports));
28659
28920
  pm2Uninstall();
@@ -28662,15 +28923,15 @@ program2.command("uninstall").description("Stop and remove Gateway pm2 service")
28662
28923
  process.exit(1);
28663
28924
  }
28664
28925
  });
28665
- program2.command("upgrade").description("Update OpenCode plugin cache and restart Gateway").action(async () => {
28666
- console.log("Updating opencode-supertask...");
28926
+ program2.command("upgrade").description(t2("\u66F4\u65B0 OpenCode \u63D2\u4EF6\u7F13\u5B58\u5E76\u91CD\u542F Gateway", "update the OpenCode plugin cache and restart the Gateway")).action(async () => {
28927
+ console.log(t2("\u6B63\u5728\u66F4\u65B0 opencode-supertask...", "Updating opencode-supertask..."));
28667
28928
  let installed;
28668
28929
  let previousVersion;
28669
28930
  try {
28670
28931
  const { resolveInstalledPlugin: resolveInstalledPlugin2 } = await Promise.resolve().then(() => (init_update2(), update_exports));
28671
28932
  previousVersion = resolveInstalledPlugin2().version;
28672
28933
  } catch (error) {
28673
- console.error(`\u65E0\u6CD5\u786E\u8BA4\u5F53\u524D OpenCode \u63D2\u4EF6\u7248\u672C\uFF0C\u5DF2\u53D6\u6D88\u5347\u7EA7: ${error instanceof Error ? error.message : String(error)}`);
28934
+ console.error(t2("\u65E0\u6CD5\u786E\u8BA4\u5F53\u524D OpenCode \u63D2\u4EF6\u7248\u672C\uFF0C\u5DF2\u53D6\u6D88\u5347\u7EA7\uFF1A", "Could not determine the current OpenCode plugin version; upgrade cancelled: ") + (error instanceof Error ? error.message : String(error)));
28674
28935
  process.exit(1);
28675
28936
  }
28676
28937
  try {
@@ -28685,17 +28946,40 @@ program2.command("upgrade").description("Update OpenCode plugin cache and restar
28685
28946
  detail += `; OpenCode \u63D2\u4EF6\u56DE\u6EDA\u5931\u8D25: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`;
28686
28947
  }
28687
28948
  console.error(detail);
28688
- console.error("Try manually: query npm dist-tags.latest, then install that exact version with opencode plugin.");
28949
+ console.error(t2(
28950
+ "\u53EF\u4EBA\u5DE5\u67E5\u8BE2 npm dist-tags.latest\uFF0C\u518D\u7528 opencode plugin \u5B89\u88C5\u8BE5\u7CBE\u786E\u7248\u672C\u3002",
28951
+ "Try manually: query npm dist-tags.latest, then install that exact version with opencode plugin."
28952
+ ));
28689
28953
  process.exit(1);
28690
28954
  }
28691
28955
  try {
28692
28956
  const { upgrade: pm2Upgrade } = await Promise.resolve().then(() => (init_pm2(), pm2_exports));
28693
28957
  const result = pm2Upgrade(installed);
28694
- console.log(`
28695
- SuperTask upgraded: ${result.before ?? "unknown"} \u2192 ${result.after}`);
28696
- console.log("Gateway restarted. Please restart opencode to load the new plugin.");
28697
- if (getPackageVersion() !== installed.version) {
28698
- console.log(`Global CLI remains v${getPackageVersion()}. Update it with your original package manager to opencode-supertask@${installed.version} (npm install -g or bun add -g).`);
28958
+ console.log(t2(
28959
+ `
28960
+ SuperTask \u5DF2\u5347\u7EA7\uFF1A${result.before ?? "unknown"} \u2192 ${result.after}`,
28961
+ `
28962
+ SuperTask upgraded: ${result.before ?? "unknown"} \u2192 ${result.after}`
28963
+ ));
28964
+ console.log(t2("Gateway \u5DF2\u91CD\u542F\u3002\u8BF7\u91CD\u542F OpenCode \u52A0\u8F7D\u65B0\u63D2\u4EF6\u3002", "Gateway restarted. Restart OpenCode to load the new plugin."));
28965
+ try {
28966
+ const { updateGlobalCli: updateGlobalCli2 } = await Promise.resolve().then(() => (init_update2(), update_exports));
28967
+ const cli = updateGlobalCli2(installed.version);
28968
+ if (cli.action === "updated") {
28969
+ console.log(t2(
28970
+ `\u5DF2\u4F7F\u7528 ${cli.packageManager} \u5C06\u5168\u5C40 CLI \u66F4\u65B0\u5230 v${installed.version}\u3002`,
28971
+ `Global CLI updated to v${installed.version} with ${cli.packageManager}.`
28972
+ ));
28973
+ } else if (cli.action === "not-installed") {
28974
+ console.log(t2("\u672A\u627E\u5230\u5168\u5C40 CLI\uFF1B\u63D2\u4EF6\u548C Gateway \u5347\u7EA7\u5DF2\u5B8C\u6210\u3002", "No global CLI installation was found; plugin and Gateway upgrade is complete."));
28975
+ }
28976
+ } catch (cliError) {
28977
+ console.error(t2("\u63D2\u4EF6\u548C Gateway \u5DF2\u5347\u7EA7\uFF0C\u4F46\u5168\u5C40 CLI \u672A\u66F4\u65B0\uFF1A", "Plugin and Gateway were upgraded, but the global CLI was not: ") + (cliError instanceof Error ? cliError.message : String(cliError)));
28978
+ console.error(t2(
28979
+ `\u6267\u884C npm install -g opencode-supertask@${installed.version} \u6216 bun add -g opencode-supertask@${installed.version}\uFF0C\u518D\u8FD0\u884C supertask doctor\u3002`,
28980
+ `Run npm install -g opencode-supertask@${installed.version} or bun add -g opencode-supertask@${installed.version}, then run supertask doctor.`
28981
+ ));
28982
+ process.exit(1);
28699
28983
  }
28700
28984
  } catch (err) {
28701
28985
  let detail = err instanceof Error ? err.message : String(err);
@@ -28707,7 +28991,7 @@ SuperTask upgraded: ${result.before ?? "unknown"} \u2192 ${result.after}`);
28707
28991
  } catch (rollbackError) {
28708
28992
  detail += `; Gateway \u5DF2\u56DE\u6EDA\uFF0C\u4F46 OpenCode \u63D2\u4EF6\u56DE\u6EDA\u5931\u8D25: ${rollbackError instanceof Error ? rollbackError.message : String(rollbackError)}`;
28709
28993
  }
28710
- console.error("Gateway restart failed:", detail);
28994
+ console.error(t2("Gateway \u91CD\u542F\u5931\u8D25\uFF1A", "Gateway restart failed:"), detail);
28711
28995
  process.exit(1);
28712
28996
  }
28713
28997
  });