mano-coding 0.1.32 → 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 +343 -198
  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",
@@ -23353,9 +23353,9 @@ async function persistGitCheckout(workDir, targetDir) {
23353
23353
  return targetDir;
23354
23354
  }
23355
23355
  async function copyGitCheckout(src, dest) {
23356
- 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");
23357
23357
  const { join: joinPath } = await import("node:path");
23358
- await mkdir19(dest, { recursive: true });
23358
+ await mkdir20(dest, { recursive: true });
23359
23359
  const entries = await readdir11(src, { withFileTypes: true });
23360
23360
  for (const entry of entries) {
23361
23361
  if (entry.name === ".git") continue;
@@ -26935,9 +26935,9 @@ var init_tarball_loader = __esm({
26935
26935
  return targetDir;
26936
26936
  }
26937
26937
  async copyDirRecursive(src, dest) {
26938
- 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");
26939
26939
  const { join: joinPath } = await import("node:path");
26940
- await mkdir19(dest, { recursive: true });
26940
+ await mkdir20(dest, { recursive: true });
26941
26941
  const entries = await readdir11(src, { withFileTypes: true });
26942
26942
  for (const entry of entries) {
26943
26943
  const srcPath = joinPath(src, entry.name);
@@ -31387,7 +31387,20 @@ var init_execute = __esm({
31387
31387
  // packages/core/src/execute/task-runner.ts
31388
31388
  import { spawn } from "node:child_process";
31389
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";
31390
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
+ }
31391
31404
  function filterTasksByHook(items, hook) {
31392
31405
  return items.filter((item) => {
31393
31406
  const task = "task" in item ? item.task : item;
@@ -31639,7 +31652,6 @@ async function executeTasks(tasks, ctx, options = {}) {
31639
31652
  if (!varValidation.valid) {
31640
31653
  throw new TaskExecutionError(varValidation.errors.join("; "), 1);
31641
31654
  }
31642
- const stdio = options.stdio ?? "inherit";
31643
31655
  const allowedRoots = [
31644
31656
  ctx.projectDir,
31645
31657
  ctx.templateDir,
@@ -31672,8 +31684,12 @@ async function executeTasks(tasks, ctx, options = {}) {
31672
31684
  }
31673
31685
  }
31674
31686
  const taskLabel = task.name ? `${task.name} (${task.id})` : task.id;
31687
+ if (options.onTaskStart) {
31688
+ options.onTaskStart(task, i, tasks.length);
31689
+ }
31675
31690
  if (options.onProgress) {
31676
- 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}`);
31677
31693
  }
31678
31694
  const rawExecutable = resolveTaskExecutable(command, process.platform, env.PATH);
31679
31695
  const { executable, args: spawnArgs } = prepareSpawnCommand(
@@ -31682,35 +31698,96 @@ async function executeTasks(tasks, ctx, options = {}) {
31682
31698
  process.platform
31683
31699
  );
31684
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
+ }
31685
31711
  const child = spawn(executable, spawnArgs, {
31686
31712
  cwd: resolvedCwd,
31687
31713
  env,
31688
- stdio,
31714
+ stdio: childStdio,
31689
31715
  shell: false,
31690
31716
  windowsHide: true
31691
31717
  });
31692
- child.on("error", (err) => {
31693
- reject(
31694
- new TaskExecutionError(
31695
- `\u6267\u884C\u4EFB\u52A1 '${task.id}' \u5931\u8D25 (${command}): ${err.message}`,
31696
- 1,
31697
- task.id,
31698
- command
31699
- )
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
31700
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);
31701
31784
  });
31702
31785
  child.on("exit", (code) => {
31703
31786
  if (code === 0 || code === null) {
31787
+ options.onTaskSuccess?.(task, i, tasks.length);
31704
31788
  resolvePromise();
31705
31789
  } else {
31706
- reject(
31707
- new TaskExecutionError(
31708
- `\u521D\u59CB\u5316\u4EFB\u52A1 '${task.id}' \u6267\u884C\u5931\u8D25\uFF0C\u9000\u51FA\u7801: ${code}`,
31709
- code,
31710
- task.id,
31711
- command
31712
- )
31713
- );
31790
+ void writeErrorLogAndReject(code, `\u5B50\u8FDB\u7A0B\u9000\u51FA\u7801\u975E 0: ${code}`);
31714
31791
  }
31715
31792
  });
31716
31793
  });
@@ -31721,11 +31798,12 @@ var init_task_runner = __esm({
31721
31798
  "packages/core/src/execute/task-runner.ts"() {
31722
31799
  "use strict";
31723
31800
  TaskExecutionError = class extends Error {
31724
- constructor(message, exitCode, taskId, command) {
31801
+ constructor(message, exitCode, taskId, command, logFile) {
31725
31802
  super(message);
31726
31803
  this.exitCode = exitCode;
31727
31804
  this.taskId = taskId;
31728
31805
  this.command = command;
31806
+ this.logFile = logFile;
31729
31807
  this.name = "TaskExecutionError";
31730
31808
  }
31731
31809
  };
@@ -32508,7 +32586,7 @@ var init_plugin = __esm({
32508
32586
 
32509
32587
  // packages/core/src/journal.ts
32510
32588
  import { createHash as createHash12, randomUUID as randomUUID3 } from "node:crypto";
32511
- 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";
32512
32590
  import { dirname as dirname12, join as join16, resolve as resolve12 } from "node:path";
32513
32591
  function projectHash(projectRoot) {
32514
32592
  return createHash12("sha256").update(resolve12(projectRoot)).digest("hex").slice(0, 32);
@@ -32638,9 +32716,9 @@ async function createJournal(userDataDir, projectRoot, options = {}) {
32638
32716
  userDataDir: resolve12(userDataDir),
32639
32717
  ...paths
32640
32718
  };
32641
- await mkdir13(dirname12(paths.transactionPath), { recursive: true });
32642
- await mkdir13(paths.transactionPath);
32643
- await mkdir13(paths.backupPath);
32719
+ await mkdir14(dirname12(paths.transactionPath), { recursive: true });
32720
+ await mkdir14(paths.transactionPath);
32721
+ await mkdir14(paths.backupPath);
32644
32722
  await atomicWrite(paths.journalPath, documentOf(journal));
32645
32723
  return journal;
32646
32724
  }
@@ -32707,7 +32785,7 @@ async function prepareRecoverySnapshots(journal, scope, root, paths) {
32707
32785
  continue;
32708
32786
  }
32709
32787
  if (!info.isFile()) throw new JournalError(`Recovery \u76EE\u6807\u4E0D\u662F\u6587\u4EF6\u6216\u76EE\u5F55: ${path2}`, "JOURNAL_INVALID");
32710
- await writeFile6(join16(journal.backupPath, backupName), await readFile21(absolutePath));
32788
+ await writeFile7(join16(journal.backupPath, backupName), await readFile21(absolutePath));
32711
32789
  snapshots.push({ scope, path: path2, existed: true, backup: backupName, mode: info.mode & 4095, kind: "file" });
32712
32790
  } catch (error) {
32713
32791
  if (error.code === "ENOENT") {
@@ -32737,8 +32815,8 @@ async function restoreRecovery(journal, projectRoot, recovery) {
32737
32815
  if (snapshot2.mode !== void 0 && process.platform !== "win32") await chmod2(absolutePath, snapshot2.mode);
32738
32816
  continue;
32739
32817
  }
32740
- await mkdir13(dirname12(absolutePath), { recursive: true });
32741
- 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)));
32742
32820
  if (snapshot2.mode !== void 0 && process.platform !== "win32") await chmod2(absolutePath, snapshot2.mode);
32743
32821
  }
32744
32822
  }
@@ -32807,7 +32885,7 @@ var init_journal = __esm({
32807
32885
 
32808
32886
  // packages/core/src/transaction.ts
32809
32887
  import { randomUUID as randomUUID4 } from "node:crypto";
32810
- 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";
32811
32889
  import { dirname as dirname13, resolve as resolve13 } from "node:path";
32812
32890
  function errorCode(error) {
32813
32891
  if (error && typeof error === "object" && "code" in error) {
@@ -32883,7 +32961,7 @@ async function removeIfPresent(path2) {
32883
32961
  }
32884
32962
  }
32885
32963
  async function atomicWrite2(path2, content, mode) {
32886
- await mkdir14(dirname13(path2), { recursive: true });
32964
+ await mkdir15(dirname13(path2), { recursive: true });
32887
32965
  const temporaryPath = `${path2}.${randomUUID4()}.tmp`;
32888
32966
  let handle;
32889
32967
  try {
@@ -32903,7 +32981,7 @@ async function restore(path2, saved) {
32903
32981
  return removeIfPresent(path2);
32904
32982
  }
32905
32983
  await removeIfPresent(path2);
32906
- await mkdir14(dirname13(path2), { recursive: true });
32984
+ await mkdir15(dirname13(path2), { recursive: true });
32907
32985
  if (saved.kind === "symlink") {
32908
32986
  await symlink2(saved.target, path2);
32909
32987
  return;
@@ -33190,7 +33268,7 @@ var init_types5 = __esm({
33190
33268
 
33191
33269
  // packages/core/src/orchestrator/staging-manager.ts
33192
33270
  import { mkdtemp as mkdtemp5, rm as rm6 } from "node:fs/promises";
33193
- import { tmpdir as tmpdir5 } from "node:os";
33271
+ import { tmpdir as tmpdir6 } from "node:os";
33194
33272
  import { join as join17 } from "node:path";
33195
33273
  var StagingManager;
33196
33274
  var init_staging_manager = __esm({
@@ -33204,7 +33282,7 @@ var init_staging_manager = __esm({
33204
33282
  const existing = this.stagingDirs.get(packageId);
33205
33283
  if (existing) return existing;
33206
33284
  if (!this.baseDir) {
33207
- this.baseDir = await mkdtemp5(join17(tmpdir5(), "mano-staging-"));
33285
+ this.baseDir = await mkdtemp5(join17(tmpdir6(), "mano-staging-"));
33208
33286
  }
33209
33287
  const pkgStaging = await mkdtemp5(join17(this.baseDir, `${sanitizedId}-`));
33210
33288
  this.stagingDirs.set(packageId, pkgStaging);
@@ -33380,7 +33458,7 @@ var init_qualification = __esm({
33380
33458
 
33381
33459
  // packages/core/src/orchestrator/lifecycle-orchestrator.ts
33382
33460
  import { randomUUID as randomUUID5 } from "node:crypto";
33383
- import { writeFile as writeFile7, mkdir as mkdir15 } from "node:fs/promises";
33461
+ import { writeFile as writeFile8, mkdir as mkdir16 } from "node:fs/promises";
33384
33462
  import { basename as basename3, dirname as dirname14, join as join19 } from "node:path";
33385
33463
  function resolveStringInputs(globalInputs, packageInputs, packageId) {
33386
33464
  const merged = {};
@@ -33537,8 +33615,8 @@ var init_lifecycle_orchestrator = __esm({
33537
33615
  for (const intent of stagingIntents) {
33538
33616
  if (intent.action === "upsert" && intent.type === "file") {
33539
33617
  const targetPath = join19(options.projectRoot, intent.path);
33540
- await mkdir15(dirname14(targetPath), { recursive: true });
33541
- await writeFile7(targetPath, intent.content);
33618
+ await mkdir16(dirname14(targetPath), { recursive: true });
33619
+ await writeFile8(targetPath, intent.content);
33542
33620
  }
33543
33621
  }
33544
33622
  }
@@ -33781,6 +33859,7 @@ __export(src_exports, {
33781
33859
  resolveTaskExecutable: () => resolveTaskExecutable,
33782
33860
  sanitizeCommand: () => sanitizeCommand,
33783
33861
  sanitizeEnvValue: () => sanitizeEnvValue,
33862
+ sanitizeTaskOutput: () => sanitizeTaskOutput,
33784
33863
  sanitizeUrl: () => sanitizeUrl,
33785
33864
  scanJournals: () => scanJournals,
33786
33865
  scanStagingDirectory: () => scanStagingDirectory,
@@ -43723,7 +43802,7 @@ var require_dist3 = __commonJS({
43723
43802
  });
43724
43803
 
43725
43804
  // packages/cli/src/commands/extension-pipeline.ts
43726
- import { readFile as readFile24, writeFile as writeFile8 } from "node:fs/promises";
43805
+ import { readFile as readFile24, writeFile as writeFile9 } from "node:fs/promises";
43727
43806
  import { existsSync as existsSync5 } from "node:fs";
43728
43807
  import { resolve as resolve14 } from "node:path";
43729
43808
  function generateGitlabCiYaml(packageId) {
@@ -43856,7 +43935,7 @@ async function executeExtensionPipeline(directory, options) {
43856
43935
  }
43857
43936
  }
43858
43937
  const ciContent = generateGitlabCiYaml(packageId);
43859
- await writeFile8(ciFilePath, ciContent, "utf-8");
43938
+ await writeFile9(ciFilePath, ciContent, "utf-8");
43860
43939
  let addedReleaseScript = false;
43861
43940
  if (existsSync5(pkgJsonPath)) {
43862
43941
  try {
@@ -43865,7 +43944,7 @@ async function executeExtensionPipeline(directory, options) {
43865
43944
  parsed.scripts = parsed.scripts || {};
43866
43945
  if (!parsed.scripts.release) {
43867
43946
  parsed.scripts.release = "npm version patch";
43868
- await writeFile8(pkgJsonPath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
43947
+ await writeFile9(pkgJsonPath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
43869
43948
  addedReleaseScript = true;
43870
43949
  }
43871
43950
  } catch {
@@ -43909,7 +43988,7 @@ var init_extension_pipeline = __esm({
43909
43988
  });
43910
43989
 
43911
43990
  // packages/cli/src/commands/extension-create.ts
43912
- 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";
43913
43992
  import { basename as basename4, resolve as resolve15 } from "node:path";
43914
43993
  function createExtensionCreateCommand() {
43915
43994
  const cmd = new Command("create");
@@ -44022,7 +44101,7 @@ async function executeExtensionCreate(directory, options) {
44022
44101
  default: true
44023
44102
  });
44024
44103
  }
44025
- await mkdir16(targetDir, { recursive: true });
44104
+ await mkdir17(targetDir, { recursive: true });
44026
44105
  const scripts = {
44027
44106
  test: "vitest"
44028
44107
  };
@@ -44048,7 +44127,7 @@ async function executeExtensionCreate(directory, options) {
44048
44127
  vitest: "^3.0.5"
44049
44128
  }
44050
44129
  };
44051
- 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");
44052
44131
  const manifestLines = [
44053
44132
  `id: "${packageId}"`,
44054
44133
  "version: 0.1.0",
@@ -44070,7 +44149,7 @@ async function executeExtensionCreate(directory, options) {
44070
44149
  manifestLines.push(" on:");
44071
44150
  manifestLines.push(" - after:create");
44072
44151
  }
44073
- 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");
44074
44153
  const agentsMdContent = `# ${templateName} Agent \u6307\u5357
44075
44154
 
44076
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
@@ -44082,9 +44161,9 @@ async function executeExtensionCreate(directory, options) {
44082
44161
  ## 2. \u4EA4\u4E92\u4E0E\u6CE8\u91CA
44083
44162
  - \u4EE3\u7801\u6CE8\u91CA\u4E0E\u56DE\u7B54\u8BF7\u59CB\u7EC8\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587\u3002
44084
44163
  `;
44085
- await writeFile9(resolve15(targetDir, "AGENTS.md"), agentsMdContent, "utf-8");
44164
+ await writeFile10(resolve15(targetDir, "AGENTS.md"), agentsMdContent, "utf-8");
44086
44165
  const skillDir = resolve15(targetDir, "skills", "example-skill");
44087
- await mkdir16(skillDir, { recursive: true });
44166
+ await mkdir17(skillDir, { recursive: true });
44088
44167
  const skillContent = `---
44089
44168
  name: example-skill
44090
44169
  description: ${templateName} \u793A\u4F8B Agent \u6280\u80FD\uFF0C\u6307\u5BFC AI \u6309\u7167\u6700\u4F73\u5B9E\u8DF5\u5B8C\u6210\u7279\u5B9A\u4EFB\u52A1
@@ -44100,9 +44179,9 @@ description: ${templateName} \u793A\u4F8B Agent \u6280\u80FD\uFF0C\u6307\u5BFC A
44100
44179
  2. \u9075\u5FAA\u672C\u9879\u76EE\u7684\u67B6\u6784\u8BBE\u8BA1\u539F\u5219\u5B9E\u73B0\u4EE3\u7801\u3002
44101
44180
  3. \u7F16\u5199\u5BF9\u5E94\u6D4B\u8BD5\u5E76\u9A8C\u8BC1\u3002
44102
44181
  `;
44103
- await writeFile9(resolve15(skillDir, "SKILL.md"), skillContent, "utf-8");
44182
+ await writeFile10(resolve15(skillDir, "SKILL.md"), skillContent, "utf-8");
44104
44183
  const cursorRulesDir = resolve15(targetDir, "rules", "cursor");
44105
- await mkdir16(cursorRulesDir, { recursive: true });
44184
+ await mkdir17(cursorRulesDir, { recursive: true });
44106
44185
  const cursorRuleContent = `---
44107
44186
  description: ${templateName} Cursor \u7F16\u7801\u89C4\u5219
44108
44187
  globs: *
@@ -44114,17 +44193,17 @@ alwaysApply: false
44114
44193
  - \u4F18\u5148\u4F7F\u7528\u73B0\u6709\u7684\u8BBE\u8BA1\u7CFB\u7EDF\u548C\u516C\u5171\u7EC4\u4EF6\u3002
44115
44194
  - \u4FDD\u6301\u51FD\u6570\u4E0E\u6A21\u5757\u7B80\u6D01\uFF0C\u5355\u4E00\u804C\u8D23\u3002
44116
44195
  `;
44117
- await writeFile9(resolve15(cursorRulesDir, "example-rule.mdc"), cursorRuleContent, "utf-8");
44196
+ await writeFile10(resolve15(cursorRulesDir, "example-rule.mdc"), cursorRuleContent, "utf-8");
44118
44197
  const codebuddyRulesDir = resolve15(targetDir, "rules", "codebuddy");
44119
- await mkdir16(codebuddyRulesDir, { recursive: true });
44198
+ await mkdir17(codebuddyRulesDir, { recursive: true });
44120
44199
  const codebuddyRuleContent = `# ${templateName} \u7F16\u7801\u89C4\u5219 (CodeBuddy)
44121
44200
 
44122
44201
  - \u9075\u5FAA\u4EE3\u7801\u8BBE\u8BA1\u539F\u5219\u3002
44123
44202
  - \u5355\u5143\u6D4B\u8BD5\u8986\u76D6\u6838\u5FC3\u903B\u8F91\u5206\u652F\u3002
44124
44203
  `;
44125
- await writeFile9(resolve15(codebuddyRulesDir, "example-rule.md"), codebuddyRuleContent, "utf-8");
44204
+ await writeFile10(resolve15(codebuddyRulesDir, "example-rule.md"), codebuddyRuleContent, "utf-8");
44126
44205
  const mcpDir = resolve15(targetDir, "mcp");
44127
- await mkdir16(mcpDir, { recursive: true });
44206
+ await mkdir17(mcpDir, { recursive: true });
44128
44207
  const mcpJsonContent = {
44129
44208
  mcpServers: {
44130
44209
  "example-server": {
@@ -44133,9 +44212,9 @@ alwaysApply: false
44133
44212
  }
44134
44213
  }
44135
44214
  };
44136
- 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");
44137
44216
  const testDir = resolve15(targetDir, "test");
44138
- await mkdir16(testDir, { recursive: true });
44217
+ await mkdir17(testDir, { recursive: true });
44139
44218
  const testContent = `import { describe, expect, it } from 'vitest';
44140
44219
  import { readFile } from 'node:fs/promises';
44141
44220
  import { resolve } from 'node:path';
@@ -44148,7 +44227,7 @@ describe('${packageId} template manifest', () => {
44148
44227
  });
44149
44228
  });
44150
44229
  `;
44151
- await writeFile9(resolve15(testDir, "manifest.test.ts"), testContent, "utf-8");
44230
+ await writeFile10(resolve15(testDir, "manifest.test.ts"), testContent, "utf-8");
44152
44231
  const createdFiles = [
44153
44232
  "manifest.yaml",
44154
44233
  "AGENTS.md",
@@ -44161,7 +44240,7 @@ describe('${packageId} template manifest', () => {
44161
44240
  "test/manifest.test.ts"
44162
44241
  ];
44163
44242
  if (withPipeline) {
44164
- await writeFile9(
44243
+ await writeFile10(
44165
44244
  resolve15(targetDir, ".gitlab-ci.yml"),
44166
44245
  generateGitlabCiYaml(packageId),
44167
44246
  "utf-8"
@@ -44175,7 +44254,7 @@ describe('${packageId} template manifest', () => {
44175
44254
  withTasks: Boolean(withTasks),
44176
44255
  withPipeline: Boolean(withPipeline)
44177
44256
  });
44178
- await writeFile9(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44257
+ await writeFile10(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44179
44258
  if (output.json) {
44180
44259
  emitSuccessJson("extension create", {
44181
44260
  directory: targetDir,
@@ -44481,7 +44560,7 @@ var init_shared_options = __esm({
44481
44560
 
44482
44561
  // packages/cli/src/commands/extension-dev.ts
44483
44562
  import { mkdtemp as mkdtemp6, readFile as readFile25 } from "node:fs/promises";
44484
- import { tmpdir as tmpdir6 } from "node:os";
44563
+ import { tmpdir as tmpdir7 } from "node:os";
44485
44564
  import { join as join20, resolve as resolvePath9, relative as relative8, isAbsolute as isAbsolute6, sep as sep4 } from "node:path";
44486
44565
  function createExtensionDevCommand() {
44487
44566
  const cmd = new Command("dev");
@@ -44536,7 +44615,7 @@ async function executeExtensionDev(packageDirectory, options) {
44536
44615
  return ExitCode.SchemaInvalid;
44537
44616
  }
44538
44617
  const effectiveDryRun = options.dryRun || options.watch;
44539
- const isolatedUserData = await mkdtemp6(join20(tmpdir6(), "aicoding-dev-userdata-"));
44618
+ const isolatedUserData = await mkdtemp6(join20(tmpdir7(), "aicoding-dev-userdata-"));
44540
44619
  const prevUserData = process.env["AICODING_USER_DATA"];
44541
44620
  process.env["AICODING_USER_DATA"] = isolatedUserData;
44542
44621
  try {
@@ -44776,7 +44855,7 @@ var init_extension_test = __esm({
44776
44855
  });
44777
44856
 
44778
44857
  // packages/cli/src/commands/extension-pack.ts
44779
- import { readFile as readFile27, mkdir as mkdir17 } from "node:fs/promises";
44858
+ import { readFile as readFile27, mkdir as mkdir18 } from "node:fs/promises";
44780
44859
  import { resolve as resolve17, join as join21, dirname as dirname15 } from "node:path";
44781
44860
  import { execFile as execFile4 } from "node:child_process";
44782
44861
  import { promisify as promisify5 } from "node:util";
@@ -44926,7 +45005,7 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
44926
45005
  }
44927
45006
  }
44928
45007
  const outputDir = options.output ? resolve17(options.output) : resolve17(pkgDir, "dist-package");
44929
- await mkdir17(outputDir, { recursive: true });
45008
+ await mkdir18(outputDir, { recursive: true });
44930
45009
  let tarballName;
44931
45010
  let tarballPath;
44932
45011
  tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
@@ -45170,7 +45249,7 @@ var init_extension_submit = __esm({
45170
45249
  });
45171
45250
 
45172
45251
  // packages/cli/src/commands/extension-adapter.ts
45173
- import { readFile as readFile29, mkdir as mkdir18 } from "node:fs/promises";
45252
+ import { readFile as readFile29, mkdir as mkdir19 } from "node:fs/promises";
45174
45253
  import { dirname as dirname16, resolve as resolve19 } from "node:path";
45175
45254
  import { execFile as execFile5 } from "node:child_process";
45176
45255
  import { promisify as promisify6 } from "node:util";
@@ -45514,7 +45593,7 @@ async function executeAdapterPack(packageDirectory, options) {
45514
45593
  return ExitCode.SchemaInvalid;
45515
45594
  }
45516
45595
  const outputDir = options.output ? resolve19(options.output) : resolve19(pkgDir, "dist-package");
45517
- await mkdir18(outputDir, { recursive: true });
45596
+ await mkdir19(outputDir, { recursive: true });
45518
45597
  const tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
45519
45598
  const tarballPath = resolve19(outputDir, tarballName);
45520
45599
  try {
@@ -46102,7 +46181,7 @@ function summarizePlan(plan) {
46102
46181
  function printPlanSummary(s3) {
46103
46182
  writeHumanOutput(`\u6267\u884C\u6458\u8981\uFF1A
46104
46183
  \u64CD\u4F5C\uFF1A${s3.operation}
46105
- \u6269\u5C55\u5305\uFF1A${s3.packageCount}
46184
+ \u6A21\u677F\uFF1A${s3.packageCount}
46106
46185
  \u6587\u4EF6\uFF1A${s3.fileCount}
46107
46186
  \u914D\u7F6E\u9879\uFF1A${s3.configEntryCount}
46108
46187
  \u63D2\u4EF6\uFF1A${s3.pluginCount}
@@ -46207,11 +46286,27 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46207
46286
  });
46208
46287
  }
46209
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
+ }
46210
46295
  for (const intent of intents) {
46211
- if (intent.action === "remove") continue;
46212
46296
  if (!intent.target) continue;
46213
46297
  const targetId = typeof intent.target === "string" ? intent.target : intent.target.id;
46214
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
+ }
46215
46310
  let digest = intent.digest ?? "";
46216
46311
  if (!digest) {
46217
46312
  if (intent.type === "file") {
@@ -46222,7 +46317,6 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46222
46317
  digest = computeStringDigest(intent.content ?? "");
46223
46318
  }
46224
46319
  }
46225
- const key = `${targetId}:${intent.path}:${selector ?? ""}`;
46226
46320
  const owner = {
46227
46321
  packageId: intent.packageId ?? templateResolution?.packageId ?? addonResolutions[0]?.packageId ?? "unknown",
46228
46322
  assetType: intent.assetType ?? (intent.type === "file" ? "rule" : "config"),
@@ -46234,6 +46328,11 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46234
46328
  if (!existing.owners.some((o) => o.packageId === owner.packageId && o.assetType === owner.assetType && o.assetId === owner.assetId)) {
46235
46329
  existing.owners.push(owner);
46236
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
+ }
46237
46336
  }
46238
46337
  continue;
46239
46338
  }
@@ -46501,6 +46600,85 @@ var init_spinner = __esm({
46501
46600
  }
46502
46601
  });
46503
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
+
46504
46682
  // packages/cli/src/commands/tty-confirm.ts
46505
46683
  var tty_confirm_exports = {};
46506
46684
  __export(tty_confirm_exports, {
@@ -46757,7 +46935,7 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46757
46935
  ),
46758
46936
  {
46759
46937
  enabled: spinnerEnabled,
46760
- 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"})`,
46761
46939
  failText: `\u2716 \u6269\u5C55\u5305\u89E3\u6790\u5931\u8D25: ${spec}`
46762
46940
  }
46763
46941
  ), { packageId: spec });
@@ -46803,7 +46981,7 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46803
46981
  }
46804
46982
  }
46805
46983
  }
46806
- 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));
46807
46985
  const rawInputs = [...options.input ?? [], ...options.set ?? []];
46808
46986
  const { values: inputValues, packageValues, warnings: inputWarnings } = parseInputFlags3(rawInputs);
46809
46987
  writeWarnings(inputWarnings, output);
@@ -46994,18 +47172,12 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
46994
47172
  operation: "create",
46995
47173
  version: resolution.manifest.version
46996
47174
  };
46997
- if (!output.json) {
46998
- writeHumanOutput(`
46999
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
47000
- `);
47001
- }
47175
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47002
47176
  try {
47003
- await executeTasks2(pkgTasks, taskContext, {
47004
- onProgress: (msg) => {
47005
- if (!output.json) writeHumanOutput(`> ${msg}
47006
- `);
47007
- },
47008
- stdio: output.json ? "ignore" : "inherit"
47177
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
47178
+ title,
47179
+ verbose: options.verbose,
47180
+ json: options.json
47009
47181
  });
47010
47182
  } catch (err) {
47011
47183
  if (err instanceof Error) {
@@ -47124,18 +47296,12 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47124
47296
  operation: "create",
47125
47297
  version: resolution.manifest.version
47126
47298
  };
47127
- if (!output.json) {
47128
- writeHumanOutput(`
47129
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u521D\u59CB\u5316\u4EFB\u52A1 (after:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
47130
- `);
47131
- }
47299
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u521D\u59CB\u5316\u4EFB\u52A1 (after:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47132
47300
  try {
47133
- await executeTasks2(pkgTasks, taskContext, {
47134
- onProgress: (msg) => {
47135
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
47136
- `);
47137
- },
47138
- stdio: output.json ? "ignore" : "inherit"
47301
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
47302
+ title,
47303
+ verbose: options.verbose,
47304
+ json: options.json
47139
47305
  });
47140
47306
  } catch (err) {
47141
47307
  if (err instanceof Error) {
@@ -47215,6 +47381,7 @@ var init_create = __esm({
47215
47381
  init_plan_execution();
47216
47382
  init_searchable_select();
47217
47383
  init_spinner();
47384
+ init_task_helper();
47218
47385
  init_i18n();
47219
47386
  }
47220
47387
  });
@@ -47224,7 +47391,7 @@ import { unlink as unlink10 } from "node:fs/promises";
47224
47391
  import { randomUUID as randomUUID7 } from "node:crypto";
47225
47392
  function createApplyCommand(cliVersion) {
47226
47393
  const cmd = new Command("apply");
47227
- 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) => {
47228
47395
  const options = extractMutationOptions(opts);
47229
47396
  const output = {
47230
47397
  json: options.json,
@@ -47329,7 +47496,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47329
47496
  addonResolutions = existing.addons;
47330
47497
  }
47331
47498
  const newAddonResolution = await withSpinner(
47332
- `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6269\u5C55 (${packageSpec})...`,
47499
+ `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6A21\u677F (${packageSpec})...`,
47333
47500
  () => resolvePackageWith2(
47334
47501
  service,
47335
47502
  packageSpec,
@@ -47338,8 +47505,8 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47338
47505
  ),
47339
47506
  {
47340
47507
  enabled: spinnerEnabled,
47341
- 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"})`,
47342
- 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}`
47343
47510
  }
47344
47511
  );
47345
47512
  addonResolutions = [...addonResolutions.filter((resolution) => resolution.packageId !== newAddonResolution.packageId), newAddonResolution];
@@ -47397,10 +47564,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47397
47564
  );
47398
47565
  const planStartedAt = Date.now();
47399
47566
  const planBuilder = service.getPlanBuilder();
47567
+ const packagesToApply = [newAddonResolution];
47400
47568
  let planResult = planBuilder.build(
47401
47569
  "apply",
47402
47570
  service.projectRoot,
47403
- allResolutions,
47571
+ packagesToApply,
47404
47572
  projectTargets
47405
47573
  );
47406
47574
  const userInstallationKeys = /* @__PURE__ */ new Set();
@@ -47408,7 +47576,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47408
47576
  "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
47409
47577
  () => buildIntentsFromPlan(
47410
47578
  planResult.plan,
47411
- allResolutions,
47579
+ packagesToApply,
47412
47580
  service,
47413
47581
  projectTargets,
47414
47582
  userInstallationKeys,
@@ -47427,6 +47595,28 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47427
47595
  failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
47428
47596
  }
47429
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
+ }
47430
47620
  const { filterTasksByHook: filterTasksByHook2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
47431
47621
  const skippedCreateTasks = [
47432
47622
  ...filterTasksByHook2(newAddonResolution.manifest.tasks ?? [], "before:create"),
@@ -47546,14 +47736,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47546
47736
  }
47547
47737
  return ExitCode.Success;
47548
47738
  }
47549
- const allTasksWithContext = allResolutions.flatMap((resolution) => {
47550
- const tTasks = resolution.manifest.tasks ?? [];
47551
- return tTasks.map((task) => ({
47552
- task,
47553
- templateDir: service.getPackageRoot(resolution) ?? service.projectRoot
47554
- }));
47555
- });
47556
- 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 }) => {
47557
47744
  return filterTasksByHook2([task], "before:apply").length > 0;
47558
47745
  });
47559
47746
  if (beforeApplyTasks.length > 0) {
@@ -47569,16 +47756,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47569
47756
  target: projectTargets[0]?.id,
47570
47757
  targets: projectTargets.map((t2) => t2.id)
47571
47758
  };
47572
- if (!output.json && i === 0) {
47573
- writeHumanOutput("\n\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5E94\u7528\u4EFB\u52A1 (before:apply):\n");
47574
- }
47575
47759
  try {
47576
- await executeTasks([task], taskContext, {
47577
- onProgress: (msg) => {
47578
- if (!output.json) writeHumanOutput(`> ${msg}
47579
- `);
47580
- },
47581
- 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
47582
47764
  });
47583
47765
  } catch (err) {
47584
47766
  if (err instanceof Error) {
@@ -47624,7 +47806,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47624
47806
  addRollback(userLifecycle.rollback);
47625
47807
  const activeAssetTypes = onlyTypes ?? (skipTypes ? ["skills", "rules", "subagents", "mcp", "agents-md"].filter((t2) => !skipTypes.includes(t2)) : void 0);
47626
47808
  const packageAssetTypes = activeAssetTypes ? { [newAddonResolution.packageId]: activeAssetTypes } : void 0;
47627
- 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);
47628
47810
  for (const desired of [lock.desired.template, ...lock.desired.addons ?? []]) {
47629
47811
  if (!desired) continue;
47630
47812
  const previous = [existingLock?.desired.template, ...existingLock?.desired.addons ?? []].find((item) => item?.id === desired.id);
@@ -47636,7 +47818,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47636
47818
  await finishJournal(journal);
47637
47819
  });
47638
47820
  events.report("record", "success", Date.now() - recordStartedAt, { planDigest: planResult.plan.planDigest });
47639
- const afterApplyTasks = allTasksWithContext.filter(({ task }) => {
47821
+ const afterApplyTasks = newTasksWithContext.filter(({ task }) => {
47640
47822
  return filterTasksByHook2([task], "after:apply").length > 0;
47641
47823
  });
47642
47824
  if (afterApplyTasks.length > 0) {
@@ -47652,16 +47834,11 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47652
47834
  target: projectTargets[0]?.id,
47653
47835
  targets: projectTargets.map((t2) => t2.id)
47654
47836
  };
47655
- if (!output.json && i === 0) {
47656
- writeHumanOutput("\n\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5E94\u7528\u4EFB\u52A1 (after:apply):\n");
47657
- }
47658
47837
  try {
47659
- await executeTasks([task], taskContext, {
47660
- onProgress: (msg) => {
47661
- if (!output.json) writeHumanOutput(`> ${msg}
47662
- `);
47663
- },
47664
- 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
47665
47842
  });
47666
47843
  } catch (err) {
47667
47844
  if (err instanceof Error) {
@@ -47721,6 +47898,7 @@ var init_apply = __esm({
47721
47898
  init_cli_output();
47722
47899
  init_service_locator();
47723
47900
  init_spinner();
47901
+ init_task_helper();
47724
47902
  init_i18n();
47725
47903
  init_plan_execution();
47726
47904
  init_searchable_select();
@@ -47969,18 +48147,12 @@ async function executeSync(options, cliVersion, silent = false, events = new Lif
47969
48147
  operation: "sync",
47970
48148
  version: resolution.manifest.version
47971
48149
  };
47972
- if (!output.json) {
47973
- writeHumanOutput(`
47974
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u540C\u6B65\u4EFB\u52A1 (before:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
47975
- `);
47976
- }
48150
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u540C\u6B65\u4EFB\u52A1 (before:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47977
48151
  try {
47978
- await executeTasks(pkgTasks, taskContext, {
47979
- onProgress: (msg) => {
47980
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
47981
- `);
47982
- },
47983
- stdio: output.json ? "ignore" : "inherit"
48152
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48153
+ title,
48154
+ verbose: options.verbose,
48155
+ json: options.json
47984
48156
  });
47985
48157
  } catch (err) {
47986
48158
  if (err instanceof Error) {
@@ -48037,18 +48209,12 @@ async function executeSync(options, cliVersion, silent = false, events = new Lif
48037
48209
  operation: "sync",
48038
48210
  version: resolution.manifest.version
48039
48211
  };
48040
- if (!output.json) {
48041
- writeHumanOutput(`
48042
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u540C\u6B65\u4EFB\u52A1 (after:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
48043
- `);
48044
- }
48212
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u540C\u6B65\u4EFB\u52A1 (after:sync) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
48045
48213
  try {
48046
- await executeTasks(pkgTasks, taskContext, {
48047
- onProgress: (msg) => {
48048
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
48049
- `);
48050
- },
48051
- stdio: output.json ? "ignore" : "inherit"
48214
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48215
+ title,
48216
+ verbose: options.verbose,
48217
+ json: options.json
48052
48218
  });
48053
48219
  } catch (err) {
48054
48220
  if (err instanceof Error) {
@@ -48083,6 +48249,7 @@ var init_sync = __esm({
48083
48249
  init_cli_output();
48084
48250
  init_service_locator();
48085
48251
  init_plan_execution();
48252
+ init_task_helper();
48086
48253
  init_i18n();
48087
48254
  }
48088
48255
  });
@@ -48346,18 +48513,12 @@ async function executeRemove(packageId, options, cliVersion, events) {
48346
48513
  operation: "remove",
48347
48514
  version: item.manifest.version
48348
48515
  };
48349
- if (!output.json) {
48350
- writeHumanOutput(`
48351
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u79FB\u9664\u4EFB\u52A1 (before:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):
48352
- `);
48353
- }
48516
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u79FB\u9664\u4EFB\u52A1 (before:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):`;
48354
48517
  try {
48355
- await executeTasks(pkgTasks, taskContext, {
48356
- onProgress: (msg) => {
48357
- if (!output.json) writeHumanOutput(`> [${item.packageId}] ${msg}
48358
- `);
48359
- },
48360
- stdio: output.json ? "ignore" : "inherit"
48518
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48519
+ title,
48520
+ verbose: options.verbose,
48521
+ json: options.json
48361
48522
  });
48362
48523
  } catch (err) {
48363
48524
  if (err instanceof Error) {
@@ -48426,18 +48587,12 @@ async function executeRemove(packageId, options, cliVersion, events) {
48426
48587
  operation: "remove",
48427
48588
  version: item.manifest.version
48428
48589
  };
48429
- if (!output.json) {
48430
- writeHumanOutput(`
48431
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u79FB\u9664\u4EFB\u52A1 (after:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):
48432
- `);
48433
- }
48590
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u79FB\u9664\u4EFB\u52A1 (after:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):`;
48434
48591
  try {
48435
- await executeTasks(pkgTasks, taskContext, {
48436
- onProgress: (msg) => {
48437
- if (!output.json) writeHumanOutput(`> [${item.packageId}] ${msg}
48438
- `);
48439
- },
48440
- stdio: output.json ? "ignore" : "inherit"
48592
+ await runTasksWithDynamicUI(pkgTasks, taskContext, {
48593
+ title,
48594
+ verbose: options.verbose,
48595
+ json: options.json
48441
48596
  });
48442
48597
  } catch (err) {
48443
48598
  if (err instanceof Error) {
@@ -48535,6 +48690,7 @@ var init_remove = __esm({
48535
48690
  init_cli_output();
48536
48691
  init_service_locator();
48537
48692
  init_plan_execution();
48693
+ init_task_helper();
48538
48694
  init_i18n();
48539
48695
  }
48540
48696
  });
@@ -49642,18 +49798,12 @@ async function executeUpgrade(opts, cliVersion) {
49642
49798
  previousVersion: oldVersion,
49643
49799
  version: templateResolution.resolvedVersion
49644
49800
  };
49645
- if (!output.json) {
49646
- writeHumanOutput(`
49647
- \u6B63\u5728\u6267\u884C\u524D\u7F6E\u5347\u7EA7\u4EFB\u52A1 (before:upgrade) (${targetPackageId}):
49648
- `);
49649
- }
49801
+ const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5347\u7EA7\u4EFB\u52A1 (before:upgrade) (${targetPackageId}):`;
49650
49802
  try {
49651
- await executeTasks(beforeTasks, taskContext, {
49652
- onProgress: (msg) => {
49653
- if (!output.json) writeHumanOutput(`> [${targetPackageId}] ${msg}
49654
- `);
49655
- },
49656
- stdio: output.json ? "ignore" : "inherit"
49803
+ await runTasksWithDynamicUI(beforeTasks, taskContext, {
49804
+ title,
49805
+ verbose: Boolean(opts.verbose),
49806
+ json
49657
49807
  });
49658
49808
  } catch (err) {
49659
49809
  if (err instanceof Error) {
@@ -49704,18 +49854,12 @@ async function executeUpgrade(opts, cliVersion) {
49704
49854
  previousVersion: oldVersion,
49705
49855
  version: templateResolution.resolvedVersion
49706
49856
  };
49707
- if (!output.json) {
49708
- writeHumanOutput(`
49709
- \u6B63\u5728\u6267\u884C\u540E\u7F6E\u5347\u7EA7\u4EFB\u52A1 (after:upgrade) (${targetPackageId}):
49710
- `);
49711
- }
49857
+ const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5347\u7EA7\u4EFB\u52A1 (after:upgrade) (${targetPackageId}):`;
49712
49858
  try {
49713
- await executeTasks(afterTasks, taskContext, {
49714
- onProgress: (msg) => {
49715
- if (!output.json) writeHumanOutput(`> [${targetPackageId}] ${msg}
49716
- `);
49717
- },
49718
- stdio: output.json ? "ignore" : "inherit"
49859
+ await runTasksWithDynamicUI(afterTasks, taskContext, {
49860
+ title,
49861
+ verbose: Boolean(opts.verbose),
49862
+ json
49719
49863
  });
49720
49864
  } catch (err) {
49721
49865
  if (err instanceof Error) {
@@ -49784,6 +49928,7 @@ var init_upgrade = __esm({
49784
49928
  init_service_locator();
49785
49929
  init_journal_helper();
49786
49930
  init_plan_execution();
49931
+ init_task_helper();
49787
49932
  init_i18n();
49788
49933
  }
49789
49934
  });
@@ -50563,7 +50708,7 @@ import { createRequire as createRequire2 } from "node:module";
50563
50708
  import { readFileSync as readFileSync4 } from "node:fs";
50564
50709
  import { fileURLToPath as fileURLToPath5 } from "node:url";
50565
50710
  function resolveVersion() {
50566
- if (true) return "0.1.32";
50711
+ if (true) return "0.1.33";
50567
50712
  const candidates = [
50568
50713
  new URL("../package.json", import.meta.url),
50569
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.32",
3
+ "version": "0.1.33",
4
4
  "description": "Mano Coding CLI and toolchain",
5
5
  "type": "module",
6
6
  "main": "index.js",