mano-coding 0.1.31 → 0.1.33

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.
Files changed (2) hide show
  1. package/dist/bin.js +378 -208
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -3441,8 +3441,8 @@ var init_zh = __esm({
3441
3441
  "create.skipped": "- \u65E0\u9700\u5B89\u88C5\uFF1A{0}\n",
3442
3442
  // apply.ts
3443
3443
  "apply.description": "\u5411\u6307\u5B9A\u76EE\u5F55\u589E\u52A0 AI Coding \u77E5\u8BC6\u8D44\u4EA7\u6216\u672C\u5730 MCP",
3444
- "apply.argPackageSpec": "\u8981\u5E94\u7528\u7684\u6269\u5C55\u5305\u89C4\u683C\uFF08\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u5305\uFF09",
3445
- "apply.packageRequired": "apply \u547D\u4EE4\u5FC5\u987B\u663E\u5F0F\u6307\u5B9A\u81F3\u5C11\u4E00\u4E2A\u6269\u5C55\u5305",
3444
+ "apply.argPackageSpec": "\u8981\u5E94\u7528\u7684\u6A21\u677F\u89C4\u683C\uFF08\u81F3\u5C11\u9700\u8981\u4E00\u4E2A\u6A21\u677F\uFF09",
3445
+ "apply.packageRequired": "apply \u547D\u4EE4\u5FC5\u987B\u663E\u5F0F\u6307\u5B9A\u81F3\u5C11\u4E00\u4E2A\u6A21\u677F",
3446
3446
  "apply.optionOnly": "\u4EC5\u5B89\u88C5\u6307\u5B9A\u7684\u53D7\u7BA1\u77E5\u8BC6\u8D44\u4EA7\u7C7B\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF1Askills,rules,subagents,mcp,agents-md\uFF09",
3447
3447
  "apply.optionSkip": "\u8DF3\u8FC7\u6307\u5B9A\u7684\u53D7\u7BA1\u77E5\u8BC6\u8D44\u4EA7\u7C7B\u578B\uFF08\u9017\u53F7\u5206\u9694\uFF1Askills,rules,subagents,mcp,agents-md\uFF09",
3448
3448
  "apply.onlySkipExclusive": "--only \u4E0E --skip \u53C2\u6570\u4E92\u65A5\uFF0C\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528",
@@ -3450,15 +3450,15 @@ var init_zh = __esm({
3450
3450
  "apply.emptyAfterFilter": "\u8FC7\u6EE4\u540E\u65E0\u53EF\u4EA4\u4ED8\u7684\u6838\u5FC3\u53D7\u7BA1\u8D44\u4EA7\u4E14\u5305\u4E0D\u5305\u542B apply \u751F\u547D\u5468\u671F\u4EFB\u52A1",
3451
3451
  "apply.driftDetected": "\u53D7\u7BA1\u8D44\u6E90\u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD apply\uFF1B\u8BF7\u5148\u8FD0\u884C sync --drift restore \u6216 accept",
3452
3452
  "apply.packageSpecRequired": "\u9879\u76EE\u65E0 lock \u6587\u4EF6\u65F6 apply \u9700\u8981 <package-spec>\u3002\u4F7F\u7528 --dry-run \u9884\u89C8\u3002",
3453
- "apply.addonKindMismatch": "\u5305 {0} \u7684\u7C7B\u578B\u4E3A '{1}'\uFF0C\u671F\u671B 'Addon'",
3453
+ "apply.addonKindMismatch": "\u5305 {0} \u7684\u7C7B\u578B\u4E3A '{1}'\uFF0C\u671F\u671B '\u6A21\u677F'",
3454
3454
  "apply.missingInputs": "\u7F3A\u5C11\u5FC5\u586B\u8F93\u5165\uFF1A{0}\u3002\u901A\u8FC7 --set \u63D0\u4F9B\u3002",
3455
3455
  "apply.planConflict": "Plan \u5B58\u5728\u51B2\u7A81",
3456
3456
  "apply.needsConfirmation": "\u6267\u884C Plan \u9700\u8981 --yes\u3002\u4F7F\u7528 --dry-run \u9884\u89C8\u3002",
3457
3457
  "apply.userDeclined": "\u7528\u6237\u62D2\u7EDD\u4E86 Plan \u786E\u8BA4",
3458
3458
  "apply.executionFailed": "\u6267\u884C\u5931\u8D25\uFF1B\u5DF2\u5C1D\u8BD5\u56DE\u6EDA",
3459
3459
  "apply.executionFailedShort": "\u6267\u884C\u5931\u8D25",
3460
- "apply.projectExtensionFailed": "Addon {0} \u7684\u5DE5\u7A0B\u6269\u5C55 apply \u5931\u8D25\uFF1A{1}",
3461
- "apply.applied": "\u5DF2\u5C06 Addon \u5E94\u7528\u5230 {0}",
3460
+ "apply.projectExtensionFailed": "\u6A21\u677F {0} \u7684\u5DE5\u7A0B\u6269\u5C55 apply \u5931\u8D25\uFF1A{1}",
3461
+ "apply.applied": "\u5DF2\u5C06\u6A21\u677F\u5E94\u7528\u5230 {0}",
3462
3462
  "apply.lockFile": "Lock \u6587\u4EF6\uFF1A{0}",
3463
3463
  // sync.ts
3464
3464
  "sync.description": "\u4ECE lock \u6587\u4EF6\u6062\u590D\u9879\u76EE\u72B6\u6001\uFF08\u4E0D\u89E3\u6790\u7248\u672C\uFF09",
@@ -3533,6 +3533,7 @@ var init_zh = __esm({
3533
3533
  "selfUpgrade.toMustBeExact": "--to \u5FC5\u987B\u662F\u7CBE\u786E\u7684 SemVer \u7248\u672C\u3002",
3534
3534
  "selfUpgrade.offlineCacheMiss": "\u672C\u5730\u66F4\u65B0\u7F13\u5B58\u4E2D\u6CA1\u6709\u8BF7\u6C42\u7684 CLI \u7248\u672C\u3002",
3535
3535
  "selfUpgrade.fetchMetadataFailed": "\u65E0\u6CD5\u8BFB\u53D6 CLI \u7248\u672C\u5143\u6570\u636E\uFF1A{0}",
3536
+ "selfUpgrade.fetchMetadataTimeout": "\u7F51\u7EDC\u8BF7\u6C42\u8D85\u65F6\uFF08\u8D85\u8FC7 {0} \u79D2\uFF09\uFF0C\u65E0\u6CD5\u8BFB\u53D6 CLI \u7248\u672C\u5143\u6570\u636E\u3002\u5EFA\u8BAE\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\uFF0C\u6216\u901A\u8FC7\u73AF\u5883\u53D8\u91CF AICODING_NPM_REGISTRY \u914D\u7F6E\u56FD\u5185\u955C\u50CF\u6E90\uFF08\u4F8B\u5982 https://registry.npmmirror.com\uFF09",
3536
3537
  "selfUpgrade.noLatestVersion": "Registry \u5143\u6570\u636E\u6CA1\u6709\u6709\u6548\u7684\u6700\u65B0 CLI \u7248\u672C\u3002",
3537
3538
  "selfUpgrade.versionNotInMetadata": "CLI \u7248\u672C {0} \u4E0D\u5B58\u5728\u4E8E Registry \u5143\u6570\u636E\u4E2D\u3002",
3538
3539
  "selfUpgrade.confirmationRequired": "CLI \u5347\u7EA7\u9700\u8981\u786E\u8BA4\u3002\u4F7F\u7528 --yes \u6279\u51C6\u3002",
@@ -23352,9 +23353,9 @@ async function persistGitCheckout(workDir, targetDir) {
23352
23353
  return targetDir;
23353
23354
  }
23354
23355
  async function copyGitCheckout(src, dest) {
23355
- const { readdir: readdir11, mkdir: mkdir19, copyFile: copyFile2 } = await import("node:fs/promises");
23356
+ const { readdir: readdir11, mkdir: mkdir20, copyFile: copyFile2 } = await import("node:fs/promises");
23356
23357
  const { join: joinPath } = await import("node:path");
23357
- await mkdir19(dest, { recursive: true });
23358
+ await mkdir20(dest, { recursive: true });
23358
23359
  const entries = await readdir11(src, { withFileTypes: true });
23359
23360
  for (const entry of entries) {
23360
23361
  if (entry.name === ".git") continue;
@@ -26934,9 +26935,9 @@ var init_tarball_loader = __esm({
26934
26935
  return targetDir;
26935
26936
  }
26936
26937
  async copyDirRecursive(src, dest) {
26937
- const { readdir: readdir11, mkdir: mkdir19, copyFile: copyFile2 } = await import("node:fs/promises");
26938
+ const { readdir: readdir11, mkdir: mkdir20, copyFile: copyFile2 } = await import("node:fs/promises");
26938
26939
  const { join: joinPath } = await import("node:path");
26939
- await mkdir19(dest, { recursive: true });
26940
+ await mkdir20(dest, { recursive: true });
26940
26941
  const entries = await readdir11(src, { withFileTypes: true });
26941
26942
  for (const entry of entries) {
26942
26943
  const srcPath = joinPath(src, entry.name);
@@ -31386,7 +31387,20 @@ var init_execute = __esm({
31386
31387
  // packages/core/src/execute/task-runner.ts
31387
31388
  import { spawn } from "node:child_process";
31388
31389
  import { existsSync as existsSync4 } from "node:fs";
31390
+ import { writeFile as writeFile6, mkdir as mkdir13 } from "node:fs/promises";
31391
+ import { tmpdir as tmpdir5 } from "node:os";
31389
31392
  import { delimiter, isAbsolute as isAbsolute5, join as join13, relative as relative5, resolve as resolve10, sep as sep3 } from "node:path";
31393
+ function sanitizeTaskOutput(text, stagingDir, projectDir) {
31394
+ if (!stagingDir || !projectDir || !text) return text;
31395
+ let res = text;
31396
+ const stagingBack = resolve10(stagingDir);
31397
+ const projectBack = resolve10(projectDir);
31398
+ const stagingForward = stagingBack.replaceAll("\\", "/");
31399
+ const projectForward = projectBack.replaceAll("\\", "/");
31400
+ res = res.replaceAll(stagingBack, projectBack);
31401
+ res = res.replaceAll(stagingForward, projectForward);
31402
+ return res;
31403
+ }
31390
31404
  function filterTasksByHook(items, hook) {
31391
31405
  return items.filter((item) => {
31392
31406
  const task = "task" in item ? item.task : item;
@@ -31638,7 +31652,6 @@ async function executeTasks(tasks, ctx, options = {}) {
31638
31652
  if (!varValidation.valid) {
31639
31653
  throw new TaskExecutionError(varValidation.errors.join("; "), 1);
31640
31654
  }
31641
- const stdio = options.stdio ?? "inherit";
31642
31655
  const allowedRoots = [
31643
31656
  ctx.projectDir,
31644
31657
  ctx.templateDir,
@@ -31671,8 +31684,12 @@ async function executeTasks(tasks, ctx, options = {}) {
31671
31684
  }
31672
31685
  }
31673
31686
  const taskLabel = task.name ? `${task.name} (${task.id})` : task.id;
31687
+ if (options.onTaskStart) {
31688
+ options.onTaskStart(task, i, tasks.length);
31689
+ }
31674
31690
  if (options.onProgress) {
31675
- options.onProgress(`\u6B63\u5728\u6267\u884C\u4EFB\u52A1 [${i + 1}/${tasks.length}] (${taskLabel}): ${command} ${effectiveArgs.join(" ")}`);
31691
+ const sanitizedCmd = sanitizeTaskOutput(`${command} ${effectiveArgs.join(" ")}`, ctx.stagingDir, ctx.projectDir);
31692
+ options.onProgress(`\u6B63\u5728\u6267\u884C\u4EFB\u52A1 [${i + 1}/${tasks.length}] (${taskLabel}): ${sanitizedCmd}`);
31676
31693
  }
31677
31694
  const rawExecutable = resolveTaskExecutable(command, process.platform, env.PATH);
31678
31695
  const { executable, args: spawnArgs } = prepareSpawnCommand(
@@ -31681,35 +31698,96 @@ async function executeTasks(tasks, ctx, options = {}) {
31681
31698
  process.platform
31682
31699
  );
31683
31700
  await new Promise((resolvePromise, reject) => {
31701
+ const isIgnore = options.stdio === "ignore";
31702
+ const isVerbose = Boolean(options.verbose);
31703
+ let childStdio;
31704
+ if (isIgnore) {
31705
+ childStdio = "ignore";
31706
+ } else if (isVerbose) {
31707
+ childStdio = ["inherit", "pipe", "pipe"];
31708
+ } else {
31709
+ childStdio = ["ignore", "pipe", "pipe"];
31710
+ }
31684
31711
  const child = spawn(executable, spawnArgs, {
31685
31712
  cwd: resolvedCwd,
31686
31713
  env,
31687
- stdio,
31714
+ stdio: childStdio,
31688
31715
  shell: false,
31689
31716
  windowsHide: true
31690
31717
  });
31691
- child.on("error", (err) => {
31692
- reject(
31693
- new TaskExecutionError(
31694
- `\u6267\u884C\u4EFB\u52A1 '${task.id}' \u5931\u8D25 (${command}): ${err.message}`,
31695
- 1,
31696
- task.id,
31697
- command
31698
- )
31718
+ const stdoutChunks = [];
31719
+ const stderrChunks = [];
31720
+ if (!isIgnore) {
31721
+ child.stdout?.on("data", (chunk) => {
31722
+ stdoutChunks.push(chunk);
31723
+ if (isVerbose) {
31724
+ process.stdout.write(sanitizeTaskOutput(chunk.toString(), ctx.stagingDir, ctx.projectDir));
31725
+ }
31726
+ });
31727
+ child.stderr?.on("data", (chunk) => {
31728
+ stderrChunks.push(chunk);
31729
+ if (isVerbose) {
31730
+ process.stderr.write(sanitizeTaskOutput(chunk.toString(), ctx.stagingDir, ctx.projectDir));
31731
+ }
31732
+ });
31733
+ }
31734
+ const writeErrorLogAndReject = async (code, rawErrorMessage) => {
31735
+ const now = (/* @__PURE__ */ new Date()).toISOString();
31736
+ const rawStdout = Buffer.concat(stdoutChunks).toString("utf-8");
31737
+ const rawStderr = Buffer.concat(stderrChunks).toString("utf-8");
31738
+ const stdoutStr = sanitizeTaskOutput(rawStdout, ctx.stagingDir, ctx.projectDir);
31739
+ const stderrStr = sanitizeTaskOutput(rawStderr, ctx.stagingDir, ctx.projectDir);
31740
+ const logContent = [
31741
+ `=== Mano Coding \u4EFB\u52A1\u6267\u884C\u9519\u8BEF\u65E5\u5FD7 ===`,
31742
+ `\u65F6\u95F4: ${now}`,
31743
+ `\u4EFB\u52A1 ID: ${task.id}`,
31744
+ `\u4EFB\u52A1\u540D\u79F0: ${task.name ?? task.id}`,
31745
+ `\u5DE5\u4F5C\u76EE\u5F55: ${resolvedCwd}`,
31746
+ `\u547D\u4EE4: ${command} ${effectiveArgs.join(" ")}`,
31747
+ `\u9000\u51FA\u7801: ${code}`,
31748
+ `\u9519\u8BEF\u4FE1\u606F: ${rawErrorMessage}`,
31749
+ `
31750
+ --- \u6807\u51C6\u8F93\u51FA (stdout) ---`,
31751
+ stdoutStr || "(\u65E0\u8F93\u51FA)",
31752
+ `
31753
+ --- \u6807\u51C6\u9519\u8BEF (stderr) ---`,
31754
+ stderrStr || "(\u65E0\u8F93\u51FA)",
31755
+ ""
31756
+ ].join("\n");
31757
+ const logDir = options.logDir ?? join13(ctx.projectDir, ".mano-coding", "logs");
31758
+ let logFilePath;
31759
+ try {
31760
+ await mkdir13(logDir, { recursive: true });
31761
+ logFilePath = join13(logDir, `task-error-${task.id}-${Date.now()}.log`);
31762
+ await writeFile6(logFilePath, logContent, "utf-8");
31763
+ } catch {
31764
+ try {
31765
+ const fallbackDir = join13(tmpdir5(), "mano-coding-logs");
31766
+ await mkdir13(fallbackDir, { recursive: true });
31767
+ logFilePath = join13(fallbackDir, `task-error-${task.id}-${Date.now()}.log`);
31768
+ await writeFile6(logFilePath, logContent, "utf-8");
31769
+ } catch {
31770
+ }
31771
+ }
31772
+ const taskErr = new TaskExecutionError(
31773
+ `\u4EFB\u52A1 '${taskLabel}' \u6267\u884C\u5931\u8D25\uFF0C\u9000\u51FA\u7801: ${code}${logFilePath ? `\u3002\u8BE6\u7EC6\u65E5\u5FD7\u5DF2\u4FDD\u5B58\u81F3: ${logFilePath}` : ""}`,
31774
+ code,
31775
+ task.id,
31776
+ command,
31777
+ logFilePath
31699
31778
  );
31779
+ options.onTaskFail?.(task, i, tasks.length, taskErr, logFilePath);
31780
+ reject(taskErr);
31781
+ };
31782
+ child.on("error", (err) => {
31783
+ void writeErrorLogAndReject(1, err.message);
31700
31784
  });
31701
31785
  child.on("exit", (code) => {
31702
31786
  if (code === 0 || code === null) {
31787
+ options.onTaskSuccess?.(task, i, tasks.length);
31703
31788
  resolvePromise();
31704
31789
  } else {
31705
- reject(
31706
- new TaskExecutionError(
31707
- `\u521D\u59CB\u5316\u4EFB\u52A1 '${task.id}' \u6267\u884C\u5931\u8D25\uFF0C\u9000\u51FA\u7801: ${code}`,
31708
- code,
31709
- task.id,
31710
- command
31711
- )
31712
- );
31790
+ void writeErrorLogAndReject(code, `\u5B50\u8FDB\u7A0B\u9000\u51FA\u7801\u975E 0: ${code}`);
31713
31791
  }
31714
31792
  });
31715
31793
  });
@@ -31720,11 +31798,12 @@ var init_task_runner = __esm({
31720
31798
  "packages/core/src/execute/task-runner.ts"() {
31721
31799
  "use strict";
31722
31800
  TaskExecutionError = class extends Error {
31723
- constructor(message, exitCode, taskId, command) {
31801
+ constructor(message, exitCode, taskId, command, logFile) {
31724
31802
  super(message);
31725
31803
  this.exitCode = exitCode;
31726
31804
  this.taskId = taskId;
31727
31805
  this.command = command;
31806
+ this.logFile = logFile;
31728
31807
  this.name = "TaskExecutionError";
31729
31808
  }
31730
31809
  };
@@ -32507,7 +32586,7 @@ var init_plugin = __esm({
32507
32586
 
32508
32587
  // packages/core/src/journal.ts
32509
32588
  import { createHash as createHash12, randomUUID as randomUUID3 } from "node:crypto";
32510
- import { chmod as chmod2, cp as cp2, mkdir as mkdir13, open as open4, readdir as readdir7, readFile as readFile21, rename as rename5, rm as rm5, stat as stat5, writeFile as writeFile6 } from "node:fs/promises";
32589
+ import { chmod as chmod2, cp as cp2, mkdir as mkdir14, open as open4, readdir as readdir7, readFile as readFile21, rename as rename5, rm as rm5, stat as stat5, writeFile as writeFile7 } from "node:fs/promises";
32511
32590
  import { dirname as dirname12, join as join16, resolve as resolve12 } from "node:path";
32512
32591
  function projectHash(projectRoot) {
32513
32592
  return createHash12("sha256").update(resolve12(projectRoot)).digest("hex").slice(0, 32);
@@ -32637,9 +32716,9 @@ async function createJournal(userDataDir, projectRoot, options = {}) {
32637
32716
  userDataDir: resolve12(userDataDir),
32638
32717
  ...paths
32639
32718
  };
32640
- await mkdir13(dirname12(paths.transactionPath), { recursive: true });
32641
- await mkdir13(paths.transactionPath);
32642
- await mkdir13(paths.backupPath);
32719
+ await mkdir14(dirname12(paths.transactionPath), { recursive: true });
32720
+ await mkdir14(paths.transactionPath);
32721
+ await mkdir14(paths.backupPath);
32643
32722
  await atomicWrite(paths.journalPath, documentOf(journal));
32644
32723
  return journal;
32645
32724
  }
@@ -32706,7 +32785,7 @@ async function prepareRecoverySnapshots(journal, scope, root, paths) {
32706
32785
  continue;
32707
32786
  }
32708
32787
  if (!info.isFile()) throw new JournalError(`Recovery \u76EE\u6807\u4E0D\u662F\u6587\u4EF6\u6216\u76EE\u5F55: ${path2}`, "JOURNAL_INVALID");
32709
- await writeFile6(join16(journal.backupPath, backupName), await readFile21(absolutePath));
32788
+ await writeFile7(join16(journal.backupPath, backupName), await readFile21(absolutePath));
32710
32789
  snapshots.push({ scope, path: path2, existed: true, backup: backupName, mode: info.mode & 4095, kind: "file" });
32711
32790
  } catch (error) {
32712
32791
  if (error.code === "ENOENT") {
@@ -32736,8 +32815,8 @@ async function restoreRecovery(journal, projectRoot, recovery) {
32736
32815
  if (snapshot2.mode !== void 0 && process.platform !== "win32") await chmod2(absolutePath, snapshot2.mode);
32737
32816
  continue;
32738
32817
  }
32739
- await mkdir13(dirname12(absolutePath), { recursive: true });
32740
- await writeFile6(absolutePath, await readFile21(join16(journal.backupPath, snapshot2.backup)));
32818
+ await mkdir14(dirname12(absolutePath), { recursive: true });
32819
+ await writeFile7(absolutePath, await readFile21(join16(journal.backupPath, snapshot2.backup)));
32741
32820
  if (snapshot2.mode !== void 0 && process.platform !== "win32") await chmod2(absolutePath, snapshot2.mode);
32742
32821
  }
32743
32822
  }
@@ -32806,7 +32885,7 @@ var init_journal = __esm({
32806
32885
 
32807
32886
  // packages/core/src/transaction.ts
32808
32887
  import { randomUUID as randomUUID4 } from "node:crypto";
32809
- import { mkdir as mkdir14, open as open5, lstat as lstat4, readFile as readFile22, readlink, rename as rename6, symlink as symlink2, unlink as unlink8 } from "node:fs/promises";
32888
+ import { mkdir as mkdir15, open as open5, lstat as lstat4, readFile as readFile22, readlink, rename as rename6, symlink as symlink2, unlink as unlink8 } from "node:fs/promises";
32810
32889
  import { dirname as dirname13, resolve as resolve13 } from "node:path";
32811
32890
  function errorCode(error) {
32812
32891
  if (error && typeof error === "object" && "code" in error) {
@@ -32882,7 +32961,7 @@ async function removeIfPresent(path2) {
32882
32961
  }
32883
32962
  }
32884
32963
  async function atomicWrite2(path2, content, mode) {
32885
- await mkdir14(dirname13(path2), { recursive: true });
32964
+ await mkdir15(dirname13(path2), { recursive: true });
32886
32965
  const temporaryPath = `${path2}.${randomUUID4()}.tmp`;
32887
32966
  let handle;
32888
32967
  try {
@@ -32902,7 +32981,7 @@ async function restore(path2, saved) {
32902
32981
  return removeIfPresent(path2);
32903
32982
  }
32904
32983
  await removeIfPresent(path2);
32905
- await mkdir14(dirname13(path2), { recursive: true });
32984
+ await mkdir15(dirname13(path2), { recursive: true });
32906
32985
  if (saved.kind === "symlink") {
32907
32986
  await symlink2(saved.target, path2);
32908
32987
  return;
@@ -33189,7 +33268,7 @@ var init_types5 = __esm({
33189
33268
 
33190
33269
  // packages/core/src/orchestrator/staging-manager.ts
33191
33270
  import { mkdtemp as mkdtemp5, rm as rm6 } from "node:fs/promises";
33192
- import { tmpdir as tmpdir5 } from "node:os";
33271
+ import { tmpdir as tmpdir6 } from "node:os";
33193
33272
  import { join as join17 } from "node:path";
33194
33273
  var StagingManager;
33195
33274
  var init_staging_manager = __esm({
@@ -33203,7 +33282,7 @@ var init_staging_manager = __esm({
33203
33282
  const existing = this.stagingDirs.get(packageId);
33204
33283
  if (existing) return existing;
33205
33284
  if (!this.baseDir) {
33206
- this.baseDir = await mkdtemp5(join17(tmpdir5(), "mano-staging-"));
33285
+ this.baseDir = await mkdtemp5(join17(tmpdir6(), "mano-staging-"));
33207
33286
  }
33208
33287
  const pkgStaging = await mkdtemp5(join17(this.baseDir, `${sanitizedId}-`));
33209
33288
  this.stagingDirs.set(packageId, pkgStaging);
@@ -33379,7 +33458,7 @@ var init_qualification = __esm({
33379
33458
 
33380
33459
  // packages/core/src/orchestrator/lifecycle-orchestrator.ts
33381
33460
  import { randomUUID as randomUUID5 } from "node:crypto";
33382
- import { writeFile as writeFile7, mkdir as mkdir15 } from "node:fs/promises";
33461
+ import { writeFile as writeFile8, mkdir as mkdir16 } from "node:fs/promises";
33383
33462
  import { basename as basename3, dirname as dirname14, join as join19 } from "node:path";
33384
33463
  function resolveStringInputs(globalInputs, packageInputs, packageId) {
33385
33464
  const merged = {};
@@ -33536,8 +33615,8 @@ var init_lifecycle_orchestrator = __esm({
33536
33615
  for (const intent of stagingIntents) {
33537
33616
  if (intent.action === "upsert" && intent.type === "file") {
33538
33617
  const targetPath = join19(options.projectRoot, intent.path);
33539
- await mkdir15(dirname14(targetPath), { recursive: true });
33540
- await writeFile7(targetPath, intent.content);
33618
+ await mkdir16(dirname14(targetPath), { recursive: true });
33619
+ await writeFile8(targetPath, intent.content);
33541
33620
  }
33542
33621
  }
33543
33622
  }
@@ -33780,6 +33859,7 @@ __export(src_exports, {
33780
33859
  resolveTaskExecutable: () => resolveTaskExecutable,
33781
33860
  sanitizeCommand: () => sanitizeCommand,
33782
33861
  sanitizeEnvValue: () => sanitizeEnvValue,
33862
+ sanitizeTaskOutput: () => sanitizeTaskOutput,
33783
33863
  sanitizeUrl: () => sanitizeUrl,
33784
33864
  scanJournals: () => scanJournals,
33785
33865
  scanStagingDirectory: () => scanStagingDirectory,
@@ -43722,7 +43802,7 @@ var require_dist3 = __commonJS({
43722
43802
  });
43723
43803
 
43724
43804
  // packages/cli/src/commands/extension-pipeline.ts
43725
- import { readFile as readFile24, writeFile as writeFile8 } from "node:fs/promises";
43805
+ import { readFile as readFile24, writeFile as writeFile9 } from "node:fs/promises";
43726
43806
  import { existsSync as existsSync5 } from "node:fs";
43727
43807
  import { resolve as resolve14 } from "node:path";
43728
43808
  function generateGitlabCiYaml(packageId) {
@@ -43855,7 +43935,7 @@ async function executeExtensionPipeline(directory, options) {
43855
43935
  }
43856
43936
  }
43857
43937
  const ciContent = generateGitlabCiYaml(packageId);
43858
- await writeFile8(ciFilePath, ciContent, "utf-8");
43938
+ await writeFile9(ciFilePath, ciContent, "utf-8");
43859
43939
  let addedReleaseScript = false;
43860
43940
  if (existsSync5(pkgJsonPath)) {
43861
43941
  try {
@@ -43864,7 +43944,7 @@ async function executeExtensionPipeline(directory, options) {
43864
43944
  parsed.scripts = parsed.scripts || {};
43865
43945
  if (!parsed.scripts.release) {
43866
43946
  parsed.scripts.release = "npm version patch";
43867
- await writeFile8(pkgJsonPath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
43947
+ await writeFile9(pkgJsonPath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
43868
43948
  addedReleaseScript = true;
43869
43949
  }
43870
43950
  } catch {
@@ -43908,7 +43988,7 @@ var init_extension_pipeline = __esm({
43908
43988
  });
43909
43989
 
43910
43990
  // packages/cli/src/commands/extension-create.ts
43911
- import { mkdir as mkdir16, writeFile as writeFile9, readdir as readdir9 } from "node:fs/promises";
43991
+ import { mkdir as mkdir17, writeFile as writeFile10, readdir as readdir9 } from "node:fs/promises";
43912
43992
  import { basename as basename4, resolve as resolve15 } from "node:path";
43913
43993
  function createExtensionCreateCommand() {
43914
43994
  const cmd = new Command("create");
@@ -44021,7 +44101,7 @@ async function executeExtensionCreate(directory, options) {
44021
44101
  default: true
44022
44102
  });
44023
44103
  }
44024
- await mkdir16(targetDir, { recursive: true });
44104
+ await mkdir17(targetDir, { recursive: true });
44025
44105
  const scripts = {
44026
44106
  test: "vitest"
44027
44107
  };
@@ -44047,7 +44127,7 @@ async function executeExtensionCreate(directory, options) {
44047
44127
  vitest: "^3.0.5"
44048
44128
  }
44049
44129
  };
44050
- await writeFile9(resolve15(targetDir, "package.json"), JSON.stringify(pkgJson, null, 2) + "\n", "utf-8");
44130
+ await writeFile10(resolve15(targetDir, "package.json"), JSON.stringify(pkgJson, null, 2) + "\n", "utf-8");
44051
44131
  const manifestLines = [
44052
44132
  `id: "${packageId}"`,
44053
44133
  "version: 0.1.0",
@@ -44069,7 +44149,7 @@ async function executeExtensionCreate(directory, options) {
44069
44149
  manifestLines.push(" on:");
44070
44150
  manifestLines.push(" - after:create");
44071
44151
  }
44072
- await writeFile9(resolve15(targetDir, "manifest.yaml"), manifestLines.join("\n") + "\n", "utf-8");
44152
+ await writeFile10(resolve15(targetDir, "manifest.yaml"), manifestLines.join("\n") + "\n", "utf-8");
44073
44153
  const agentsMdContent = `# ${templateName} Agent \u6307\u5357
44074
44154
 
44075
44155
  \u672C\u9879\u76EE\u57FA\u4E8E ${templateName} \u6A21\u677F\u6784\u5EFA\u3002\u5728\u8FDB\u884C AI \u8F85\u52A9\u7F16\u7801\u65F6\uFF0C\u8BF7\u9075\u5FAA\u4EE5\u4E0B\u6838\u5FC3\u539F\u5219\u4E0E\u7EA6\u5B9A\uFF1A
@@ -44081,9 +44161,9 @@ async function executeExtensionCreate(directory, options) {
44081
44161
  ## 2. \u4EA4\u4E92\u4E0E\u6CE8\u91CA
44082
44162
  - \u4EE3\u7801\u6CE8\u91CA\u4E0E\u56DE\u7B54\u8BF7\u59CB\u7EC8\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587\u3002
44083
44163
  `;
44084
- await writeFile9(resolve15(targetDir, "AGENTS.md"), agentsMdContent, "utf-8");
44164
+ await writeFile10(resolve15(targetDir, "AGENTS.md"), agentsMdContent, "utf-8");
44085
44165
  const skillDir = resolve15(targetDir, "skills", "example-skill");
44086
- await mkdir16(skillDir, { recursive: true });
44166
+ await mkdir17(skillDir, { recursive: true });
44087
44167
  const skillContent = `---
44088
44168
  name: example-skill
44089
44169
  description: ${templateName} \u793A\u4F8B Agent \u6280\u80FD\uFF0C\u6307\u5BFC AI \u6309\u7167\u6700\u4F73\u5B9E\u8DF5\u5B8C\u6210\u7279\u5B9A\u4EFB\u52A1
@@ -44099,9 +44179,9 @@ description: ${templateName} \u793A\u4F8B Agent \u6280\u80FD\uFF0C\u6307\u5BFC A
44099
44179
  2. \u9075\u5FAA\u672C\u9879\u76EE\u7684\u67B6\u6784\u8BBE\u8BA1\u539F\u5219\u5B9E\u73B0\u4EE3\u7801\u3002
44100
44180
  3. \u7F16\u5199\u5BF9\u5E94\u6D4B\u8BD5\u5E76\u9A8C\u8BC1\u3002
44101
44181
  `;
44102
- await writeFile9(resolve15(skillDir, "SKILL.md"), skillContent, "utf-8");
44182
+ await writeFile10(resolve15(skillDir, "SKILL.md"), skillContent, "utf-8");
44103
44183
  const cursorRulesDir = resolve15(targetDir, "rules", "cursor");
44104
- await mkdir16(cursorRulesDir, { recursive: true });
44184
+ await mkdir17(cursorRulesDir, { recursive: true });
44105
44185
  const cursorRuleContent = `---
44106
44186
  description: ${templateName} Cursor \u7F16\u7801\u89C4\u5219
44107
44187
  globs: *
@@ -44113,17 +44193,17 @@ alwaysApply: false
44113
44193
  - \u4F18\u5148\u4F7F\u7528\u73B0\u6709\u7684\u8BBE\u8BA1\u7CFB\u7EDF\u548C\u516C\u5171\u7EC4\u4EF6\u3002
44114
44194
  - \u4FDD\u6301\u51FD\u6570\u4E0E\u6A21\u5757\u7B80\u6D01\uFF0C\u5355\u4E00\u804C\u8D23\u3002
44115
44195
  `;
44116
- await writeFile9(resolve15(cursorRulesDir, "example-rule.mdc"), cursorRuleContent, "utf-8");
44196
+ await writeFile10(resolve15(cursorRulesDir, "example-rule.mdc"), cursorRuleContent, "utf-8");
44117
44197
  const codebuddyRulesDir = resolve15(targetDir, "rules", "codebuddy");
44118
- await mkdir16(codebuddyRulesDir, { recursive: true });
44198
+ await mkdir17(codebuddyRulesDir, { recursive: true });
44119
44199
  const codebuddyRuleContent = `# ${templateName} \u7F16\u7801\u89C4\u5219 (CodeBuddy)
44120
44200
 
44121
44201
  - \u9075\u5FAA\u4EE3\u7801\u8BBE\u8BA1\u539F\u5219\u3002
44122
44202
  - \u5355\u5143\u6D4B\u8BD5\u8986\u76D6\u6838\u5FC3\u903B\u8F91\u5206\u652F\u3002
44123
44203
  `;
44124
- await writeFile9(resolve15(codebuddyRulesDir, "example-rule.md"), codebuddyRuleContent, "utf-8");
44204
+ await writeFile10(resolve15(codebuddyRulesDir, "example-rule.md"), codebuddyRuleContent, "utf-8");
44125
44205
  const mcpDir = resolve15(targetDir, "mcp");
44126
- await mkdir16(mcpDir, { recursive: true });
44206
+ await mkdir17(mcpDir, { recursive: true });
44127
44207
  const mcpJsonContent = {
44128
44208
  mcpServers: {
44129
44209
  "example-server": {
@@ -44132,9 +44212,9 @@ alwaysApply: false
44132
44212
  }
44133
44213
  }
44134
44214
  };
44135
- await writeFile9(resolve15(mcpDir, "mcp.json"), JSON.stringify(mcpJsonContent, null, 2) + "\n", "utf-8");
44215
+ await writeFile10(resolve15(mcpDir, "mcp.json"), JSON.stringify(mcpJsonContent, null, 2) + "\n", "utf-8");
44136
44216
  const testDir = resolve15(targetDir, "test");
44137
- await mkdir16(testDir, { recursive: true });
44217
+ await mkdir17(testDir, { recursive: true });
44138
44218
  const testContent = `import { describe, expect, it } from 'vitest';
44139
44219
  import { readFile } from 'node:fs/promises';
44140
44220
  import { resolve } from 'node:path';
@@ -44147,7 +44227,7 @@ describe('${packageId} template manifest', () => {
44147
44227
  });
44148
44228
  });
44149
44229
  `;
44150
- await writeFile9(resolve15(testDir, "manifest.test.ts"), testContent, "utf-8");
44230
+ await writeFile10(resolve15(testDir, "manifest.test.ts"), testContent, "utf-8");
44151
44231
  const createdFiles = [
44152
44232
  "manifest.yaml",
44153
44233
  "AGENTS.md",
@@ -44160,7 +44240,7 @@ describe('${packageId} template manifest', () => {
44160
44240
  "test/manifest.test.ts"
44161
44241
  ];
44162
44242
  if (withPipeline) {
44163
- await writeFile9(
44243
+ await writeFile10(
44164
44244
  resolve15(targetDir, ".gitlab-ci.yml"),
44165
44245
  generateGitlabCiYaml(packageId),
44166
44246
  "utf-8"
@@ -44174,7 +44254,7 @@ describe('${packageId} template manifest', () => {
44174
44254
  withTasks: Boolean(withTasks),
44175
44255
  withPipeline: Boolean(withPipeline)
44176
44256
  });
44177
- await writeFile9(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44257
+ await writeFile10(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44178
44258
  if (output.json) {
44179
44259
  emitSuccessJson("extension create", {
44180
44260
  directory: targetDir,
@@ -44480,7 +44560,7 @@ var init_shared_options = __esm({
44480
44560
 
44481
44561
  // packages/cli/src/commands/extension-dev.ts
44482
44562
  import { mkdtemp as mkdtemp6, readFile as readFile25 } from "node:fs/promises";
44483
- import { tmpdir as tmpdir6 } from "node:os";
44563
+ import { tmpdir as tmpdir7 } from "node:os";
44484
44564
  import { join as join20, resolve as resolvePath9, relative as relative8, isAbsolute as isAbsolute6, sep as sep4 } from "node:path";
44485
44565
  function createExtensionDevCommand() {
44486
44566
  const cmd = new Command("dev");
@@ -44535,7 +44615,7 @@ async function executeExtensionDev(packageDirectory, options) {
44535
44615
  return ExitCode.SchemaInvalid;
44536
44616
  }
44537
44617
  const effectiveDryRun = options.dryRun || options.watch;
44538
- const isolatedUserData = await mkdtemp6(join20(tmpdir6(), "aicoding-dev-userdata-"));
44618
+ const isolatedUserData = await mkdtemp6(join20(tmpdir7(), "aicoding-dev-userdata-"));
44539
44619
  const prevUserData = process.env["AICODING_USER_DATA"];
44540
44620
  process.env["AICODING_USER_DATA"] = isolatedUserData;
44541
44621
  try {
@@ -44775,7 +44855,7 @@ var init_extension_test = __esm({
44775
44855
  });
44776
44856
 
44777
44857
  // packages/cli/src/commands/extension-pack.ts
44778
- import { readFile as readFile27, mkdir as mkdir17 } from "node:fs/promises";
44858
+ import { readFile as readFile27, mkdir as mkdir18 } from "node:fs/promises";
44779
44859
  import { resolve as resolve17, join as join21, dirname as dirname15 } from "node:path";
44780
44860
  import { execFile as execFile4 } from "node:child_process";
44781
44861
  import { promisify as promisify5 } from "node:util";
@@ -44925,7 +45005,7 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
44925
45005
  }
44926
45006
  }
44927
45007
  const outputDir = options.output ? resolve17(options.output) : resolve17(pkgDir, "dist-package");
44928
- await mkdir17(outputDir, { recursive: true });
45008
+ await mkdir18(outputDir, { recursive: true });
44929
45009
  let tarballName;
44930
45010
  let tarballPath;
44931
45011
  tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
@@ -45169,7 +45249,7 @@ var init_extension_submit = __esm({
45169
45249
  });
45170
45250
 
45171
45251
  // packages/cli/src/commands/extension-adapter.ts
45172
- import { readFile as readFile29, mkdir as mkdir18 } from "node:fs/promises";
45252
+ import { readFile as readFile29, mkdir as mkdir19 } from "node:fs/promises";
45173
45253
  import { dirname as dirname16, resolve as resolve19 } from "node:path";
45174
45254
  import { execFile as execFile5 } from "node:child_process";
45175
45255
  import { promisify as promisify6 } from "node:util";
@@ -45513,7 +45593,7 @@ async function executeAdapterPack(packageDirectory, options) {
45513
45593
  return ExitCode.SchemaInvalid;
45514
45594
  }
45515
45595
  const outputDir = options.output ? resolve19(options.output) : resolve19(pkgDir, "dist-package");
45516
- await mkdir18(outputDir, { recursive: true });
45596
+ await mkdir19(outputDir, { recursive: true });
45517
45597
  const tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
45518
45598
  const tarballPath = resolve19(outputDir, tarballName);
45519
45599
  try {
@@ -46101,7 +46181,7 @@ function summarizePlan(plan) {
46101
46181
  function printPlanSummary(s3) {
46102
46182
  writeHumanOutput(`\u6267\u884C\u6458\u8981\uFF1A
46103
46183
  \u64CD\u4F5C\uFF1A${s3.operation}
46104
- \u6269\u5C55\u5305\uFF1A${s3.packageCount}
46184
+ \u6A21\u677F\uFF1A${s3.packageCount}
46105
46185
  \u6587\u4EF6\uFF1A${s3.fileCount}
46106
46186
  \u914D\u7F6E\u9879\uFF1A${s3.configEntryCount}
46107
46187
  \u63D2\u4EF6\uFF1A${s3.pluginCount}
@@ -46206,11 +46286,27 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46206
46286
  });
46207
46287
  }
46208
46288
  const resources = /* @__PURE__ */ new Map();
46289
+ if (existingLock?.resources) {
46290
+ for (const res of existingLock.resources) {
46291
+ const key = `${res.target}:${res.path}:${res.selector ?? ""}`;
46292
+ resources.set(key, { ...res, owners: [...res.owners] });
46293
+ }
46294
+ }
46209
46295
  for (const intent of intents) {
46210
- if (intent.action === "remove") continue;
46211
46296
  if (!intent.target) continue;
46212
46297
  const targetId = typeof intent.target === "string" ? intent.target : intent.target.id;
46213
46298
  const selector = (intent.type === "config-entry" ? intent.selector : intent.type === "managed-section" ? intent.sectionId : null) ?? null;
46299
+ const key = `${targetId}:${intent.path}:${selector ?? ""}`;
46300
+ if (intent.action === "remove") {
46301
+ const existing2 = resources.get(key);
46302
+ if (existing2) {
46303
+ existing2.owners = existing2.owners.filter((o) => o.packageId !== intent.packageId);
46304
+ if (existing2.owners.length === 0) {
46305
+ resources.delete(key);
46306
+ }
46307
+ }
46308
+ continue;
46309
+ }
46214
46310
  let digest = intent.digest ?? "";
46215
46311
  if (!digest) {
46216
46312
  if (intent.type === "file") {
@@ -46221,7 +46317,6 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46221
46317
  digest = computeStringDigest(intent.content ?? "");
46222
46318
  }
46223
46319
  }
46224
- const key = `${targetId}:${intent.path}:${selector ?? ""}`;
46225
46320
  const owner = {
46226
46321
  packageId: intent.packageId ?? templateResolution?.packageId ?? addonResolutions[0]?.packageId ?? "unknown",
46227
46322
  assetType: intent.assetType ?? (intent.type === "file" ? "rule" : "config"),
@@ -46233,6 +46328,11 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46233
46328
  if (!existing.owners.some((o) => o.packageId === owner.packageId && o.assetType === owner.assetType && o.assetId === owner.assetId)) {
46234
46329
  existing.owners.push(owner);
46235
46330
  }
46331
+ } else {
46332
+ existing.hash = digest;
46333
+ if (!existing.owners.some((o) => o.packageId === owner.packageId && o.assetType === owner.assetType && o.assetId === owner.assetId)) {
46334
+ existing.owners.push(owner);
46335
+ }
46236
46336
  }
46237
46337
  continue;
46238
46338
  }
@@ -46500,6 +46600,85 @@ var init_spinner = __esm({
46500
46600
  }
46501
46601
  });
46502
46602
 
46603
+ // packages/cli/src/commands/task-helper.ts
46604
+ async function runTasksWithDynamicUI(tasks, ctx, options = {}) {
46605
+ if (tasks.length === 0) return;
46606
+ const isInteractive = !options.json && !options.verbose && Boolean(process.stdout.isTTY) && process.env.NODE_ENV !== "test";
46607
+ if (!options.json && options.title) {
46608
+ writeHumanOutput(`
46609
+ ${options.title}
46610
+ `);
46611
+ }
46612
+ if (isInteractive) {
46613
+ let currentSpinner = null;
46614
+ try {
46615
+ await executeTasks(tasks, ctx, {
46616
+ verbose: false,
46617
+ onTaskStart: (task, index, total) => {
46618
+ const taskLabel = task.name ? `${task.name} (${task.id})` : task.id;
46619
+ currentSpinner = new Spinner(`[${index + 1}/${total}] \u6B63\u5728\u6267\u884C\u4EFB\u52A1: ${taskLabel}...`);
46620
+ currentSpinner.start();
46621
+ },
46622
+ onTaskSuccess: (task, index, total) => {
46623
+ const taskLabel = task.name ? `${task.name}` : task.id;
46624
+ if (currentSpinner) {
46625
+ currentSpinner.succeed(`[${index + 1}/${total}] \u4EFB\u52A1\u5B8C\u6210: ${taskLabel}`);
46626
+ }
46627
+ },
46628
+ onTaskFail: (task, index, total, _error, logFile) => {
46629
+ const taskLabel = task.name ? `${task.name}` : task.id;
46630
+ if (currentSpinner) {
46631
+ currentSpinner.fail(`[${index + 1}/${total}] \u4EFB\u52A1\u6267\u884C\u5931\u8D25: ${taskLabel}`);
46632
+ }
46633
+ if (logFile) {
46634
+ writeHumanOutput(` \u8BE6\u7EC6\u65E5\u5FD7\u5DF2\u4FDD\u5B58\u81F3: ${logFile}
46635
+ `);
46636
+ }
46637
+ }
46638
+ });
46639
+ } catch (err) {
46640
+ currentSpinner?.stop();
46641
+ throw err;
46642
+ }
46643
+ } else {
46644
+ await executeTasks(tasks, ctx, {
46645
+ verbose: Boolean(options.verbose),
46646
+ stdio: options.json ? "ignore" : void 0,
46647
+ onTaskStart: (task, index, total) => {
46648
+ if (!options.json && options.verbose) {
46649
+ writeHumanOutput(`
46650
+ > [${index + 1}/${total}] \u5F00\u59CB\u6267\u884C\u4EFB\u52A1: ${task.name ?? task.id}
46651
+ `);
46652
+ }
46653
+ },
46654
+ onTaskSuccess: (task, index, total) => {
46655
+ if (!options.json && !options.verbose) {
46656
+ writeHumanOutput(`\u2714 [${index + 1}/${total}] \u4EFB\u52A1\u5B8C\u6210: ${task.name ?? task.id}
46657
+ `);
46658
+ }
46659
+ },
46660
+ onTaskFail: (task, index, total, _err, logFile) => {
46661
+ if (!options.json) {
46662
+ writeHumanOutput(`\u2716 [${index + 1}/${total}] \u4EFB\u52A1\u6267\u884C\u5931\u8D25: ${task.name ?? task.id}
46663
+ `);
46664
+ if (logFile) {
46665
+ writeHumanOutput(` \u8BE6\u7EC6\u65E5\u5FD7\u5DF2\u4FDD\u5B58\u81F3: ${logFile}
46666
+ `);
46667
+ }
46668
+ }
46669
+ }
46670
+ });
46671
+ }
46672
+ }
46673
+ var init_task_helper = __esm({
46674
+ "packages/cli/src/commands/task-helper.ts"() {
46675
+ "use strict";
46676
+ init_spinner();
46677
+ init_src2();
46678
+ init_cli_output();
46679
+ }
46680
+ });
46681
+
46503
46682
  // packages/cli/src/commands/tty-confirm.ts
46504
46683
  var tty_confirm_exports = {};
46505
46684
  __export(tty_confirm_exports, {
@@ -46756,7 +46935,7 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46756
46935
  ),
46757
46936
  {
46758
46937
  enabled: spinnerEnabled,
46759
- successText: (res) => `\u2714 \u6269\u5C55\u5305\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? spec} (v${res.manifest.version ?? "0.0.0"})`,
46938
+ successText: (res) => `\u2714 \u6A21\u677F\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? spec} (v${res.manifest.version ?? "0.0.0"})`,
46760
46939
  failText: `\u2716 \u6269\u5C55\u5305\u89E3\u6790\u5931\u8D25: ${spec}`
46761
46940
  }
46762
46941
  ), { packageId: spec });
@@ -46802,7 +46981,7 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46802
46981
  }
46803
46982
  }
46804
46983
  }
46805
- const { parseInputFlags: parseInputFlags3, validateTaskInputs: validateTaskInputs2, executeTasks: executeTasks2, filterTasksByHook: filterTasksByHook2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
46984
+ const { parseInputFlags: parseInputFlags3, validateTaskInputs: validateTaskInputs2, filterTasksByHook: filterTasksByHook2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
46806
46985
  const rawInputs = [...options.input ?? [], ...options.set ?? []];
46807
46986
  const { values: inputValues, packageValues, warnings: inputWarnings } = parseInputFlags3(rawInputs);
46808
46987
  writeWarnings(inputWarnings, output);
@@ -46993,18 +47172,12 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
46993
47172
  operation: "create",
46994
47173
  version: resolution.manifest.version
46995
47174
  };
46996
- if (!output.json) {
46997
- writeHumanOutput(`
46998
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
46999
- `);
47000
- }
47175
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47001
47176
  try {
47002
- await executeTasks2(pkgTasks, taskContext, {
47003
- onProgress: (msg) => {
47004
- if (!output.json) writeHumanOutput(`> ${msg}
47005
- `);
47006
- },
47007
- stdio: output.json ? "ignore" : "inherit"
47177
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
47178
+ title,
47179
+ verbose: options.verbose,
47180
+ json: options.json
47008
47181
  });
47009
47182
  } catch (err) {
47010
47183
  if (err instanceof Error) {
@@ -47123,18 +47296,12 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47123
47296
  operation: "create",
47124
47297
  version: resolution.manifest.version
47125
47298
  };
47126
- if (!output.json) {
47127
- writeHumanOutput(`
47128
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u521D\u59CB\u5316\u4EFB\u52A1 (after:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
47129
- `);
47130
- }
47299
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u521D\u59CB\u5316\u4EFB\u52A1 (after:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47131
47300
  try {
47132
- await executeTasks2(pkgTasks, taskContext, {
47133
- onProgress: (msg) => {
47134
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
47135
- `);
47136
- },
47137
- stdio: output.json ? "ignore" : "inherit"
47301
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
47302
+ title,
47303
+ verbose: options.verbose,
47304
+ json: options.json
47138
47305
  });
47139
47306
  } catch (err) {
47140
47307
  if (err instanceof Error) {
@@ -47214,6 +47381,7 @@ var init_create = __esm({
47214
47381
  init_plan_execution();
47215
47382
  init_searchable_select();
47216
47383
  init_spinner();
47384
+ init_task_helper();
47217
47385
  init_i18n();
47218
47386
  }
47219
47387
  });
@@ -47223,7 +47391,7 @@ import { unlink as unlink10 } from "node:fs/promises";
47223
47391
  import { randomUUID as randomUUID7 } from "node:crypto";
47224
47392
  function createApplyCommand(cliVersion) {
47225
47393
  const cmd = new Command("apply");
47226
- cmd.description("Apply an Addon package to an existing project").argument("[package-spec]", "Addon package spec (required if no project lock)").action(async (packageSpec, opts) => {
47394
+ cmd.description("Apply a template to an existing project").argument("[package-spec]", "Template spec (required if no project lock)").action(async (packageSpec, opts) => {
47227
47395
  const options = extractMutationOptions(opts);
47228
47396
  const output = {
47229
47397
  json: options.json,
@@ -47328,7 +47496,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47328
47496
  addonResolutions = existing.addons;
47329
47497
  }
47330
47498
  const newAddonResolution = await withSpinner(
47331
- `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6269\u5C55 (${packageSpec})...`,
47499
+ `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6A21\u677F (${packageSpec})...`,
47332
47500
  () => resolvePackageWith2(
47333
47501
  service,
47334
47502
  packageSpec,
@@ -47337,8 +47505,8 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47337
47505
  ),
47338
47506
  {
47339
47507
  enabled: spinnerEnabled,
47340
- successText: (res) => `\u2714 \u6269\u5C55\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? packageSpec} (v${res.manifest.version ?? "0.0.0"})`,
47341
- failText: `\u2716 \u6269\u5C55\u89E3\u6790\u5931\u8D25: ${packageSpec}`
47508
+ successText: (res) => `\u2714 \u6A21\u677F\u89E3\u6790\u5B8C\u6210: ${res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? packageSpec} (v${res.manifest.version ?? "0.0.0"})`,
47509
+ failText: `\u2716 \u6A21\u677F\u89E3\u6790\u5931\u8D25: ${packageSpec}`
47342
47510
  }
47343
47511
  );
47344
47512
  addonResolutions = [...addonResolutions.filter((resolution) => resolution.packageId !== newAddonResolution.packageId), newAddonResolution];
@@ -47396,10 +47564,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47396
47564
  );
47397
47565
  const planStartedAt = Date.now();
47398
47566
  const planBuilder = service.getPlanBuilder();
47567
+ const packagesToApply = [newAddonResolution];
47399
47568
  let planResult = planBuilder.build(
47400
47569
  "apply",
47401
47570
  service.projectRoot,
47402
- allResolutions,
47571
+ packagesToApply,
47403
47572
  projectTargets
47404
47573
  );
47405
47574
  const userInstallationKeys = /* @__PURE__ */ new Set();
@@ -47407,7 +47576,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47407
47576
  "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
47408
47577
  () => buildIntentsFromPlan(
47409
47578
  planResult.plan,
47410
- allResolutions,
47579
+ packagesToApply,
47411
47580
  service,
47412
47581
  projectTargets,
47413
47582
  userInstallationKeys,
@@ -47426,6 +47595,28 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47426
47595
  failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
47427
47596
  }
47428
47597
  );
47598
+ if (existingLock?.resources) {
47599
+ for (const intent of intents) {
47600
+ if (intent.action === "remove" || !intent.target) continue;
47601
+ const targetId = typeof intent.target === "string" ? intent.target : intent.target.id;
47602
+ const selector = (intent.type === "config-entry" ? intent.selector : intent.type === "managed-section" ? intent.sectionId : null) ?? null;
47603
+ const matched = existingLock.resources.find((r) => r.target === targetId && r.path === intent.path && (r.selector ?? null) === selector);
47604
+ if (matched && matched.owners.every((o) => o.packageId !== newAddonResolution.packageId)) {
47605
+ let newDigest = intent.digest ?? "";
47606
+ if (!newDigest && intent.type === "file" && intent.content) {
47607
+ const { computeStringDigest: computeStringDigest2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
47608
+ newDigest = computeStringDigest2(intent.content);
47609
+ }
47610
+ if (newDigest && matched.hash && newDigest !== matched.hash) {
47611
+ throw new CliError(
47612
+ `\u8D44\u6E90 '${intent.path}' \u4E0E\u5DF2\u6709\u6A21\u677F\u8D44\u6E90\u5B58\u5728\u51B2\u7A81`,
47613
+ ExitCode.ConflictOrDrift,
47614
+ "PLAN_CONFLICT"
47615
+ );
47616
+ }
47617
+ }
47618
+ }
47619
+ }
47429
47620
  const { filterTasksByHook: filterTasksByHook2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
47430
47621
  const skippedCreateTasks = [
47431
47622
  ...filterTasksByHook2(newAddonResolution.manifest.tasks ?? [], "before:create"),
@@ -47545,14 +47736,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47545
47736
  }
47546
47737
  return ExitCode.Success;
47547
47738
  }
47548
- const allTasksWithContext = allResolutions.flatMap((resolution) => {
47549
- const tTasks = resolution.manifest.tasks ?? [];
47550
- return tTasks.map((task) => ({
47551
- task,
47552
- templateDir: service.getPackageRoot(resolution) ?? service.projectRoot
47553
- }));
47554
- });
47555
- const beforeApplyTasks = allTasksWithContext.filter(({ task }) => {
47739
+ const newTasksWithContext = (newAddonResolution.manifest.tasks ?? []).map((task) => ({
47740
+ task,
47741
+ templateDir: service.getPackageRoot(newAddonResolution) ?? service.projectRoot
47742
+ }));
47743
+ const beforeApplyTasks = newTasksWithContext.filter(({ task }) => {
47556
47744
  return filterTasksByHook2([task], "before:apply").length > 0;
47557
47745
  });
47558
47746
  if (beforeApplyTasks.length > 0) {
@@ -47568,16 +47756,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47568
47756
  target: projectTargets[0]?.id,
47569
47757
  targets: projectTargets.map((t2) => t2.id)
47570
47758
  };
47571
- if (!output.json && i === 0) {
47572
- writeHumanOutput("\n\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5E94\u7528\u4EFB\u52A1 (before:apply):\n");
47573
- }
47574
47759
  try {
47575
- await executeTasks([task], taskContext, {
47576
- onProgress: (msg) => {
47577
- if (!output.json) writeHumanOutput(`> ${msg}
47578
- `);
47579
- },
47580
- stdio: output.json ? "ignore" : "inherit"
47760
+ await runTasksWithDynamicUI([task], taskContext, {
47761
+ title: i === 0 ? "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5E94\u7528\u4EFB\u52A1 (before:apply):" : void 0,
47762
+ verbose: options.verbose,
47763
+ json: options.json
47581
47764
  });
47582
47765
  } catch (err) {
47583
47766
  if (err instanceof Error) {
@@ -47623,7 +47806,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47623
47806
  addRollback(userLifecycle.rollback);
47624
47807
  const activeAssetTypes = onlyTypes ?? (skipTypes ? ["skills", "rules", "subagents", "mcp", "agents-md"].filter((t2) => !skipTypes.includes(t2)) : void 0);
47625
47808
  const packageAssetTypes = activeAssetTypes ? { [newAddonResolution.packageId]: activeAssetTypes } : void 0;
47626
- const lock = await buildLock("apply", templateResolution, addonResolutions, projectTargets, planResult.plan, service.cliVersion, inputValues, service, intents, userInstallationKeys, packageAssetTypes);
47809
+ const lock = await buildLock("apply", templateResolution, addonResolutions, projectTargets, planResult.plan, service.cliVersion, inputValues, service, intents, userInstallationKeys, packageAssetTypes, existingLock);
47627
47810
  for (const desired of [lock.desired.template, ...lock.desired.addons ?? []]) {
47628
47811
  if (!desired) continue;
47629
47812
  const previous = [existingLock?.desired.template, ...existingLock?.desired.addons ?? []].find((item) => item?.id === desired.id);
@@ -47635,7 +47818,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47635
47818
  await finishJournal(journal);
47636
47819
  });
47637
47820
  events.report("record", "success", Date.now() - recordStartedAt, { planDigest: planResult.plan.planDigest });
47638
- const afterApplyTasks = allTasksWithContext.filter(({ task }) => {
47821
+ const afterApplyTasks = newTasksWithContext.filter(({ task }) => {
47639
47822
  return filterTasksByHook2([task], "after:apply").length > 0;
47640
47823
  });
47641
47824
  if (afterApplyTasks.length > 0) {
@@ -47651,16 +47834,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47651
47834
  target: projectTargets[0]?.id,
47652
47835
  targets: projectTargets.map((t2) => t2.id)
47653
47836
  };
47654
- if (!output.json && i === 0) {
47655
- writeHumanOutput("\n\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5E94\u7528\u4EFB\u52A1 (after:apply):\n");
47656
- }
47657
47837
  try {
47658
- await executeTasks([task], taskContext, {
47659
- onProgress: (msg) => {
47660
- if (!output.json) writeHumanOutput(`> ${msg}
47661
- `);
47662
- },
47663
- stdio: output.json ? "ignore" : "inherit"
47838
+ await runTasksWithDynamicUI([task], taskContext, {
47839
+ title: i === 0 ? "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5E94\u7528\u4EFB\u52A1 (after:apply):" : void 0,
47840
+ verbose: options.verbose,
47841
+ json: options.json
47664
47842
  });
47665
47843
  } catch (err) {
47666
47844
  if (err instanceof Error) {
@@ -47720,6 +47898,7 @@ var init_apply = __esm({
47720
47898
  init_cli_output();
47721
47899
  init_service_locator();
47722
47900
  init_spinner();
47901
+ init_task_helper();
47723
47902
  init_i18n();
47724
47903
  init_plan_execution();
47725
47904
  init_searchable_select();
@@ -47968,18 +48147,12 @@ async function executeSync(options, cliVersion, silent = false, events = new Lif
47968
48147
  operation: "sync",
47969
48148
  version: resolution.manifest.version
47970
48149
  };
47971
- if (!output.json) {
47972
- writeHumanOutput(`
47973
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u540C\u6B65\u4EFB\u52A1 (before:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
47974
- `);
47975
- }
48150
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u540C\u6B65\u4EFB\u52A1 (before:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47976
48151
  try {
47977
- await executeTasks(pkgTasks, taskContext, {
47978
- onProgress: (msg) => {
47979
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
47980
- `);
47981
- },
47982
- stdio: output.json ? "ignore" : "inherit"
48152
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48153
+ title,
48154
+ verbose: options.verbose,
48155
+ json: options.json
47983
48156
  });
47984
48157
  } catch (err) {
47985
48158
  if (err instanceof Error) {
@@ -48036,18 +48209,12 @@ async function executeSync(options, cliVersion, silent = false, events = new Lif
48036
48209
  operation: "sync",
48037
48210
  version: resolution.manifest.version
48038
48211
  };
48039
- if (!output.json) {
48040
- writeHumanOutput(`
48041
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u540C\u6B65\u4EFB\u52A1 (after:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
48042
- `);
48043
- }
48212
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u540C\u6B65\u4EFB\u52A1 (after:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
48044
48213
  try {
48045
- await executeTasks(pkgTasks, taskContext, {
48046
- onProgress: (msg) => {
48047
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
48048
- `);
48049
- },
48050
- stdio: output.json ? "ignore" : "inherit"
48214
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48215
+ title,
48216
+ verbose: options.verbose,
48217
+ json: options.json
48051
48218
  });
48052
48219
  } catch (err) {
48053
48220
  if (err instanceof Error) {
@@ -48082,6 +48249,7 @@ var init_sync = __esm({
48082
48249
  init_cli_output();
48083
48250
  init_service_locator();
48084
48251
  init_plan_execution();
48252
+ init_task_helper();
48085
48253
  init_i18n();
48086
48254
  }
48087
48255
  });
@@ -48345,18 +48513,12 @@ async function executeRemove(packageId, options, cliVersion, events) {
48345
48513
  operation: "remove",
48346
48514
  version: item.manifest.version
48347
48515
  };
48348
- if (!output.json) {
48349
- writeHumanOutput(`
48350
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u79FB\u9664\u4EFB\u52A1 (before:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):
48351
- `);
48352
- }
48516
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u79FB\u9664\u4EFB\u52A1 (before:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):`;
48353
48517
  try {
48354
- await executeTasks(pkgTasks, taskContext, {
48355
- onProgress: (msg) => {
48356
- if (!output.json) writeHumanOutput(`> [${item.packageId}] ${msg}
48357
- `);
48358
- },
48359
- stdio: output.json ? "ignore" : "inherit"
48518
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48519
+ title,
48520
+ verbose: options.verbose,
48521
+ json: options.json
48360
48522
  });
48361
48523
  } catch (err) {
48362
48524
  if (err instanceof Error) {
@@ -48425,18 +48587,12 @@ async function executeRemove(packageId, options, cliVersion, events) {
48425
48587
  operation: "remove",
48426
48588
  version: item.manifest.version
48427
48589
  };
48428
- if (!output.json) {
48429
- writeHumanOutput(`
48430
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u79FB\u9664\u4EFB\u52A1 (after:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):
48431
- `);
48432
- }
48590
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u79FB\u9664\u4EFB\u52A1 (after:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):`;
48433
48591
  try {
48434
- await executeTasks(pkgTasks, taskContext, {
48435
- onProgress: (msg) => {
48436
- if (!output.json) writeHumanOutput(`> [${item.packageId}] ${msg}
48437
- `);
48438
- },
48439
- stdio: output.json ? "ignore" : "inherit"
48592
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48593
+ title,
48594
+ verbose: options.verbose,
48595
+ json: options.json
48440
48596
  });
48441
48597
  } catch (err) {
48442
48598
  if (err instanceof Error) {
@@ -48534,6 +48690,7 @@ var init_remove = __esm({
48534
48690
  init_cli_output();
48535
48691
  init_service_locator();
48536
48692
  init_plan_execution();
48693
+ init_task_helper();
48537
48694
  init_i18n();
48538
48695
  }
48539
48696
  });
@@ -49641,18 +49798,12 @@ async function executeUpgrade(opts, cliVersion) {
49641
49798
  previousVersion: oldVersion,
49642
49799
  version: templateResolution.resolvedVersion
49643
49800
  };
49644
- if (!output.json) {
49645
- writeHumanOutput(`
49646
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u5347\u7EA7\u4EFB\u52A1 (before:upgrade) (${targetPackageId}):
49647
- `);
49648
- }
49801
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5347\u7EA7\u4EFB\u52A1 (before:upgrade) (${targetPackageId}):`;
49649
49802
  try {
49650
- await executeTasks(beforeTasks, taskContext, {
49651
- onProgress: (msg) => {
49652
- if (!output.json) writeHumanOutput(`> [${targetPackageId}] ${msg}
49653
- `);
49654
- },
49655
- stdio: output.json ? "ignore" : "inherit"
49803
+ await runTasksWithDynamicUI(beforeTasks, taskContext, {
49804
+ title,
49805
+ verbose: Boolean(opts.verbose),
49806
+ json
49656
49807
  });
49657
49808
  } catch (err) {
49658
49809
  if (err instanceof Error) {
@@ -49703,18 +49854,12 @@ async function executeUpgrade(opts, cliVersion) {
49703
49854
  previousVersion: oldVersion,
49704
49855
  version: templateResolution.resolvedVersion
49705
49856
  };
49706
- if (!output.json) {
49707
- writeHumanOutput(`
49708
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u5347\u7EA7\u4EFB\u52A1 (after:upgrade) (${targetPackageId}):
49709
- `);
49710
- }
49857
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5347\u7EA7\u4EFB\u52A1 (after:upgrade) (${targetPackageId}):`;
49711
49858
  try {
49712
- await executeTasks(afterTasks, taskContext, {
49713
- onProgress: (msg) => {
49714
- if (!output.json) writeHumanOutput(`> [${targetPackageId}] ${msg}
49715
- `);
49716
- },
49717
- stdio: output.json ? "ignore" : "inherit"
49859
+ await runTasksWithDynamicUI(afterTasks, taskContext, {
49860
+ title,
49861
+ verbose: Boolean(opts.verbose),
49862
+ json
49718
49863
  });
49719
49864
  } catch (err) {
49720
49865
  if (err instanceof Error) {
@@ -49783,6 +49928,7 @@ var init_upgrade = __esm({
49783
49928
  init_service_locator();
49784
49929
  init_journal_helper();
49785
49930
  init_plan_execution();
49931
+ init_task_helper();
49786
49932
  init_i18n();
49787
49933
  }
49788
49934
  });
@@ -50449,17 +50595,41 @@ async function verifyCliVersion(binPath, expected) {
50449
50595
  const result = await runCommand(process.execPath, [binPath, "--version"]).catch(() => void 0);
50450
50596
  return result?.exitCode === 0 && result.stdout.trim() === expected;
50451
50597
  }
50452
- async function fetchCliMetadata(registry, request = fetch) {
50453
- const controller = new AbortController();
50454
- const timer = setTimeout(() => controller.abort(), 3e3);
50455
- timer.unref?.();
50456
- try {
50457
- const response = await request(`${registry}/${encodeURIComponent(CLI_PACKAGE_NAME)}`, { signal: controller.signal, redirect: "error" });
50458
- if (!response.ok) throw new Error(`Registry returned HTTP ${response.status}`);
50459
- return await response.json();
50460
- } finally {
50461
- clearTimeout(timer);
50598
+ async function fetchCliMetadata(registry, request = fetch, options) {
50599
+ const envTimeout = process.env["AICODING_FETCH_TIMEOUT"] ? Number.parseInt(process.env["AICODING_FETCH_TIMEOUT"], 10) : void 0;
50600
+ const timeoutMs = options?.timeoutMs ?? (Number.isFinite(envTimeout) && (envTimeout ?? 0) > 0 ? envTimeout : 15e3);
50601
+ const maxRetries = options?.retries ?? 1;
50602
+ let lastError;
50603
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
50604
+ const controller = new AbortController();
50605
+ let timedOut = false;
50606
+ const timer = setTimeout(() => {
50607
+ timedOut = true;
50608
+ controller.abort();
50609
+ }, timeoutMs);
50610
+ timer.unref?.();
50611
+ try {
50612
+ const response = await request(`${registry}/${encodeURIComponent(CLI_PACKAGE_NAME)}`, {
50613
+ signal: controller.signal,
50614
+ redirect: "error"
50615
+ });
50616
+ if (!response.ok) throw new Error(`Registry returned HTTP ${response.status}`);
50617
+ return await response.json();
50618
+ } catch (error) {
50619
+ const isAbort = timedOut || error instanceof Error && (error.name === "AbortError" || error.message.includes("aborted"));
50620
+ if (isAbort) {
50621
+ lastError = new Error(t("selfUpgrade.fetchMetadataTimeout", Math.round(timeoutMs / 1e3)));
50622
+ } else {
50623
+ lastError = error;
50624
+ }
50625
+ if (attempt < maxRetries) {
50626
+ await new Promise((resolve28) => setTimeout(resolve28, 200));
50627
+ }
50628
+ } finally {
50629
+ clearTimeout(timer);
50630
+ }
50462
50631
  }
50632
+ throw lastError;
50463
50633
  }
50464
50634
  async function runCommand(command, args) {
50465
50635
  const useCmd = process.platform === "win32" && (command === "pnpm" || command === "npm");
@@ -50538,7 +50708,7 @@ import { createRequire as createRequire2 } from "node:module";
50538
50708
  import { readFileSync as readFileSync4 } from "node:fs";
50539
50709
  import { fileURLToPath as fileURLToPath5 } from "node:url";
50540
50710
  function resolveVersion() {
50541
- if (true) return "0.1.31";
50711
+ if (true) return "0.1.33";
50542
50712
  const candidates = [
50543
50713
  new URL("../package.json", import.meta.url),
50544
50714
  new URL("../../package.json", import.meta.url),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mano-coding",
3
- "version": "0.1.31",
3
+ "version": "0.1.33",
4
4
  "description": "Mano Coding CLI and toolchain",
5
5
  "type": "module",
6
6
  "main": "index.js",