mano-coding 0.1.30 → 0.1.32

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 +532 -352
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -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",
@@ -14962,49 +14963,49 @@ var require_fast_uri = __commonJS({
14962
14963
  schemelessOptions.skipEscape = true;
14963
14964
  return serialize(resolved, schemelessOptions);
14964
14965
  }
14965
- function resolveComponent(base, relative8, options, skipNormalization) {
14966
+ function resolveComponent(base, relative9, options, skipNormalization) {
14966
14967
  const target = {};
14967
14968
  if (!skipNormalization) {
14968
14969
  base = parse(serialize(base, options), options);
14969
- relative8 = parse(serialize(relative8, options), options);
14970
+ relative9 = parse(serialize(relative9, options), options);
14970
14971
  }
14971
14972
  options = options || {};
14972
- if (!options.tolerant && relative8.scheme) {
14973
- target.scheme = relative8.scheme;
14974
- target.userinfo = relative8.userinfo;
14975
- target.host = relative8.host;
14976
- target.port = relative8.port;
14977
- target.path = removeDotSegments(relative8.path || "");
14978
- target.query = relative8.query;
14973
+ if (!options.tolerant && relative9.scheme) {
14974
+ target.scheme = relative9.scheme;
14975
+ target.userinfo = relative9.userinfo;
14976
+ target.host = relative9.host;
14977
+ target.port = relative9.port;
14978
+ target.path = removeDotSegments(relative9.path || "");
14979
+ target.query = relative9.query;
14979
14980
  } else {
14980
- if (relative8.userinfo !== void 0 || relative8.host !== void 0 || relative8.port !== void 0) {
14981
- target.userinfo = relative8.userinfo;
14982
- target.host = relative8.host;
14983
- target.port = relative8.port;
14984
- target.path = removeDotSegments(relative8.path || "");
14985
- target.query = relative8.query;
14981
+ if (relative9.userinfo !== void 0 || relative9.host !== void 0 || relative9.port !== void 0) {
14982
+ target.userinfo = relative9.userinfo;
14983
+ target.host = relative9.host;
14984
+ target.port = relative9.port;
14985
+ target.path = removeDotSegments(relative9.path || "");
14986
+ target.query = relative9.query;
14986
14987
  } else {
14987
- if (!relative8.path) {
14988
+ if (!relative9.path) {
14988
14989
  target.path = base.path;
14989
- if (relative8.query !== void 0) {
14990
- target.query = relative8.query;
14990
+ if (relative9.query !== void 0) {
14991
+ target.query = relative9.query;
14991
14992
  } else {
14992
14993
  target.query = base.query;
14993
14994
  }
14994
14995
  } else {
14995
- if (relative8.path[0] === "/") {
14996
- target.path = removeDotSegments(relative8.path);
14996
+ if (relative9.path[0] === "/") {
14997
+ target.path = removeDotSegments(relative9.path);
14997
14998
  } else {
14998
14999
  if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
14999
- target.path = "/" + relative8.path;
15000
+ target.path = "/" + relative9.path;
15000
15001
  } else if (!base.path) {
15001
- target.path = relative8.path;
15002
+ target.path = relative9.path;
15002
15003
  } else {
15003
- target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative8.path;
15004
+ target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative9.path;
15004
15005
  }
15005
15006
  target.path = removeDotSegments(target.path);
15006
15007
  }
15007
- target.query = relative8.query;
15008
+ target.query = relative9.query;
15008
15009
  }
15009
15010
  target.userinfo = base.userinfo;
15010
15011
  target.host = base.host;
@@ -15012,7 +15013,7 @@ var require_fast_uri = __commonJS({
15012
15013
  }
15013
15014
  target.scheme = base.scheme;
15014
15015
  }
15015
- target.fragment = relative8.fragment;
15016
+ target.fragment = relative9.fragment;
15016
15017
  return target;
15017
15018
  }
15018
15019
  function equal(uriA, uriB, options) {
@@ -23352,10 +23353,10 @@ async function persistGitCheckout(workDir, targetDir) {
23352
23353
  return targetDir;
23353
23354
  }
23354
23355
  async function copyGitCheckout(src, dest) {
23355
- const { readdir: readdir10, mkdir: mkdir18, copyFile: copyFile2 } = await import("node:fs/promises");
23356
+ const { readdir: readdir11, mkdir: mkdir19, copyFile: copyFile2 } = await import("node:fs/promises");
23356
23357
  const { join: joinPath } = await import("node:path");
23357
- await mkdir18(dest, { recursive: true });
23358
- const entries = await readdir10(src, { withFileTypes: true });
23358
+ await mkdir19(dest, { recursive: true });
23359
+ const entries = await readdir11(src, { withFileTypes: true });
23359
23360
  for (const entry of entries) {
23360
23361
  if (entry.name === ".git") continue;
23361
23362
  const srcPath = joinPath(src, entry.name);
@@ -23548,8 +23549,8 @@ var init_git_resolver = __esm({
23548
23549
  }
23549
23550
  const cacheBase = join6(cacheRoot, "git", encodePackageId(packageId));
23550
23551
  try {
23551
- const { readdir: readdir10 } = await import("node:fs/promises");
23552
- const commits = await readdir10(cacheBase, { withFileTypes: true });
23552
+ const { readdir: readdir11 } = await import("node:fs/promises");
23553
+ const commits = await readdir11(cacheBase, { withFileTypes: true });
23553
23554
  for (const entry of commits) {
23554
23555
  if (!entry.isDirectory()) continue;
23555
23556
  const cacheDir = join6(cacheBase, entry.name);
@@ -26934,10 +26935,10 @@ var init_tarball_loader = __esm({
26934
26935
  return targetDir;
26935
26936
  }
26936
26937
  async copyDirRecursive(src, dest) {
26937
- const { readdir: readdir10, mkdir: mkdir18, copyFile: copyFile2 } = await import("node:fs/promises");
26938
+ const { readdir: readdir11, mkdir: mkdir19, copyFile: copyFile2 } = await import("node:fs/promises");
26938
26939
  const { join: joinPath } = await import("node:path");
26939
- await mkdir18(dest, { recursive: true });
26940
- const entries = await readdir10(src, { withFileTypes: true });
26940
+ await mkdir19(dest, { recursive: true });
26941
+ const entries = await readdir11(src, { withFileTypes: true });
26941
26942
  for (const entry of entries) {
26942
26943
  const srcPath = joinPath(src, entry.name);
26943
26944
  const destPath = joinPath(dest, entry.name);
@@ -26996,18 +26997,18 @@ var init_tarball_loader = __esm({
26996
26997
  }
26997
26998
  async findAndReadManifest(workDir, packageId, version) {
26998
26999
  const packageRoot = await this.findPackageRoot(workDir, packageId, version);
26999
- const { readFile: readFile33 } = await import("node:fs/promises");
27000
- return readFile33(join7(packageRoot, "manifest.yaml"), "utf-8");
27000
+ const { readFile: readFile34 } = await import("node:fs/promises");
27001
+ return readFile34(join7(packageRoot, "manifest.yaml"), "utf-8");
27001
27002
  }
27002
27003
  async findPackageRoot(workDir, packageId, version) {
27003
- const { access: access12, readdir: readdir10 } = await import("node:fs/promises");
27004
+ const { access: access12, readdir: readdir11 } = await import("node:fs/promises");
27004
27005
  const { resolve: resolvePath10 } = await import("node:path");
27005
27006
  const candidates = [
27006
27007
  resolvePath10(workDir),
27007
27008
  resolvePath10(workDir, "package")
27008
27009
  ];
27009
27010
  try {
27010
- const entries = await readdir10(workDir, { withFileTypes: true });
27011
+ const entries = await readdir11(workDir, { withFileTypes: true });
27011
27012
  for (const entry of entries) {
27012
27013
  if (entry.isDirectory()) {
27013
27014
  candidates.push(resolvePath10(workDir, entry.name));
@@ -28735,11 +28736,11 @@ var init_claude_code_adapter = __esm({
28735
28736
  return diagnostics;
28736
28737
  }
28737
28738
  const { capability, content, packageRoot } = request;
28738
- const { readFile: readFile33 } = await import("node:fs/promises");
28739
+ const { readFile: readFile34 } = await import("node:fs/promises");
28739
28740
  const { resolve: resolvePath10 } = await import("node:path");
28740
28741
  const variantPath = resolvePath10(packageRoot, content.path);
28741
28742
  try {
28742
- const raw = await readFile33(variantPath, "utf-8");
28743
+ const raw = await readFile34(variantPath, "utf-8");
28743
28744
  switch (capability.type) {
28744
28745
  case "rule":
28745
28746
  if (!variantPath.endsWith(".md")) {
@@ -28899,7 +28900,7 @@ var init_codex_adapter = __esm({
28899
28900
  return diagnostics;
28900
28901
  }
28901
28902
  const { capability, content, packageRoot } = request;
28902
- const { readFile: readFile33 } = await import("node:fs/promises");
28903
+ const { readFile: readFile34 } = await import("node:fs/promises");
28903
28904
  const { resolve: resolvePath10 } = await import("node:path");
28904
28905
  const variantPath = resolvePath10(packageRoot, content.path);
28905
28906
  switch (capability.type) {
@@ -28925,7 +28926,7 @@ var init_codex_adapter = __esm({
28925
28926
  });
28926
28927
  }
28927
28928
  try {
28928
- const raw = await readFile33(variantPath, "utf-8");
28929
+ const raw = await readFile34(variantPath, "utf-8");
28929
28930
  if (!raw.trim()) {
28930
28931
  diagnostics.push({
28931
28932
  severity: "error",
@@ -28940,7 +28941,7 @@ var init_codex_adapter = __esm({
28940
28941
  break;
28941
28942
  case "mcp":
28942
28943
  try {
28943
- const raw = await readFile33(variantPath, "utf-8");
28944
+ const raw = await readFile34(variantPath, "utf-8");
28944
28945
  if (!raw.trim()) {
28945
28946
  diagnostics.push({
28946
28947
  severity: "error",
@@ -29067,7 +29068,7 @@ var init_opencode_adapter = __esm({
29067
29068
  return diagnostics;
29068
29069
  }
29069
29070
  const { capability, content, packageRoot } = request;
29070
- const { readFile: readFile33 } = await import("node:fs/promises");
29071
+ const { readFile: readFile34 } = await import("node:fs/promises");
29071
29072
  const { resolve: resolvePath10 } = await import("node:path");
29072
29073
  const variantPath = resolvePath10(packageRoot, content.path);
29073
29074
  switch (capability.type) {
@@ -29104,7 +29105,7 @@ var init_opencode_adapter = __esm({
29104
29105
  break;
29105
29106
  case "mcp":
29106
29107
  try {
29107
- const raw = await readFile33(variantPath, "utf-8");
29108
+ const raw = await readFile34(variantPath, "utf-8");
29108
29109
  JSON.parse(raw);
29109
29110
  } catch {
29110
29111
  diagnostics.push({
@@ -29241,11 +29242,11 @@ var init_codebuddy_adapter = __esm({
29241
29242
  return diagnostics;
29242
29243
  }
29243
29244
  const { capability, content, packageRoot } = request;
29244
- const { readFile: readFile33 } = await import("node:fs/promises");
29245
+ const { readFile: readFile34 } = await import("node:fs/promises");
29245
29246
  const { resolve: resolvePath10 } = await import("node:path");
29246
29247
  const variantPath = resolvePath10(packageRoot, content.path);
29247
29248
  try {
29248
- const raw = await readFile33(variantPath, "utf-8");
29249
+ const raw = await readFile34(variantPath, "utf-8");
29249
29250
  switch (capability.type) {
29250
29251
  case "rule":
29251
29252
  if (!variantPath.endsWith(".mdc")) {
@@ -29403,11 +29404,11 @@ var init_trae_adapter = __esm({
29403
29404
  return diagnostics;
29404
29405
  }
29405
29406
  const { capability, content, packageRoot } = request;
29406
- const { readFile: readFile33 } = await import("node:fs/promises");
29407
+ const { readFile: readFile34 } = await import("node:fs/promises");
29407
29408
  const { resolve: resolvePath10 } = await import("node:path");
29408
29409
  const variantPath = resolvePath10(packageRoot, content.path);
29409
29410
  try {
29410
- const raw = await readFile33(variantPath, "utf-8");
29411
+ const raw = await readFile34(variantPath, "utf-8");
29411
29412
  switch (capability.type) {
29412
29413
  case "rule":
29413
29414
  if (!variantPath.endsWith(".md")) {
@@ -29798,11 +29799,11 @@ var init_host_packages = __esm({
29798
29799
  import { resolve as resolve9 } from "node:path";
29799
29800
  import { pathToFileURL } from "node:url";
29800
29801
  async function loadAdapterModule(packageRoot) {
29801
- const { readFile: readFile33 } = await import("node:fs/promises");
29802
+ const { readFile: readFile34 } = await import("node:fs/promises");
29802
29803
  const packageJsonPath = resolve9(packageRoot, "package.json");
29803
29804
  let packageJson;
29804
29805
  try {
29805
- const raw = await readFile33(packageJsonPath, "utf-8");
29806
+ const raw = await readFile34(packageJsonPath, "utf-8");
29806
29807
  packageJson = JSON.parse(raw);
29807
29808
  } catch {
29808
29809
  throw new AdapterLoaderError(
@@ -31496,7 +31497,11 @@ function validateTaskVariables(tasks, ctx) {
31496
31497
  if (ctx.targets && ctx.targets.length > 1) {
31497
31498
  errors.push(`\u4EFB\u52A1 '${taskId}' \u7684 ${field} \u5F15\u7528\u4E86\u5355\u503C '\${target}'\uFF0C\u4F46\u5F53\u524D\u9009\u62E9\u4E86\u591A\u4E2A target: [${ctx.targets.join(", ")}]\u3002\u8BF7\u5728 manifest \u4E2D\u4F7F\u7528 '\${targets}' \u6216\u4EC5\u9009\u62E9\u5355\u4E2A target`);
31498
31499
  }
31499
- } else if (varName === "projectName" || varName === "projectDir" || varName === "projectParentDir" || varName === "templateDir" || varName === "stagingDir" || varName === "targets" || varName === "operation" || varName === "version" || varName === "previousVersion" || varName.startsWith("inputs.")) {
31500
+ } else if (varName === "stagingDir") {
31501
+ if (!ctx.stagingDir) {
31502
+ errors.push(`\u4EFB\u52A1 '${taskId}' \u7684 ${field} \u4E2D\u5F15\u7528\u4E86 '\${stagingDir}'\uFF0C\u4F46\u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587\u4E2D\u672A\u5206\u914D stagingDir\uFF08\u4EC5\u5728 before:create \u94A9\u5B50\u4E2D\u53EF\u7528\uFF09`);
31503
+ }
31504
+ } else if (varName === "projectName" || varName === "projectDir" || varName === "projectParentDir" || varName === "templateDir" || varName === "targets" || varName === "operation" || varName === "version" || varName === "previousVersion" || varName.startsWith("inputs.")) {
31500
31505
  } else {
31501
31506
  errors.push(`\u4EFB\u52A1 '${taskId}' \u7684 ${field} \u4E2D\u5F15\u7528\u4E86\u672A\u77E5\u53D8\u91CF '\${${varName}}'`);
31502
31507
  }
@@ -31522,7 +31527,15 @@ function interpolateString(template, ctx, allowEnv = false) {
31522
31527
  if (varName === "projectDir") return ctx.projectDir;
31523
31528
  if (varName === "projectParentDir") return ctx.projectParentDir;
31524
31529
  if (varName === "templateDir") return ctx.templateDir;
31525
- if (varName === "stagingDir") return ctx.stagingDir ?? "";
31530
+ if (varName === "stagingDir") {
31531
+ if (!ctx.stagingDir) {
31532
+ throw new TaskExecutionError(
31533
+ `\u4EFB\u52A1\u5F15\u7528\u4E86 '\${stagingDir}'\uFF0C\u4F46\u5F53\u524D\u64CD\u4F5C\u4E0A\u4E0B\u6587\u4E2D\u672A\u5206\u914D stagingDir\u3002\u8BE5\u53D8\u91CF\u4EC5\u5728 before:create \u94A9\u5B50\u4E2D\u53EF\u7528\u3002`,
31534
+ 1
31535
+ );
31536
+ }
31537
+ return ctx.stagingDir;
31538
+ }
31526
31539
  if (varName === "operation") return ctx.operation ?? "";
31527
31540
  if (varName === "version") return ctx.version ?? "";
31528
31541
  if (varName === "previousVersion") return ctx.previousVersion ?? "";
@@ -33215,6 +33228,68 @@ var init_staging_manager = __esm({
33215
33228
  }
33216
33229
  });
33217
33230
 
33231
+ // packages/core/src/orchestrator/staging-scanner.ts
33232
+ import { readFile as readFile23, readdir as readdir8, stat as stat6 } from "node:fs/promises";
33233
+ import { join as join18, relative as relative7 } from "node:path";
33234
+ async function scanStagingDirectory(options) {
33235
+ const { stagingDir, packageId, ownerKind = "template" } = options;
33236
+ const ignoredDirs = /* @__PURE__ */ new Set([...DEFAULT_IGNORED_DIRS, ...options.ignoredDirs ?? []]);
33237
+ const intents = [];
33238
+ async function walk(currentDir) {
33239
+ let entries;
33240
+ try {
33241
+ entries = await readdir8(currentDir, { withFileTypes: true });
33242
+ } catch {
33243
+ return;
33244
+ }
33245
+ for (const entry of entries) {
33246
+ const fullPath = join18(currentDir, entry.name);
33247
+ if (entry.isDirectory()) {
33248
+ if (ignoredDirs.has(entry.name)) {
33249
+ continue;
33250
+ }
33251
+ await walk(fullPath);
33252
+ } else if (entry.isFile()) {
33253
+ const relPath = relative7(stagingDir, fullPath).replaceAll("\\", "/");
33254
+ if (relPath === "aicoding-lock.yaml" || relPath === "mano-lock.yaml") {
33255
+ continue;
33256
+ }
33257
+ const fileStat = await stat6(fullPath);
33258
+ const content = await readFile23(fullPath);
33259
+ const executable = Boolean(fileStat.mode & 73);
33260
+ intents.push({
33261
+ action: "upsert",
33262
+ type: "file",
33263
+ path: relPath,
33264
+ content,
33265
+ executable: executable ? true : void 0,
33266
+ packageId,
33267
+ ownerKind,
33268
+ assetType: "project-seed"
33269
+ });
33270
+ }
33271
+ }
33272
+ }
33273
+ await walk(stagingDir);
33274
+ return {
33275
+ intents,
33276
+ fileCount: intents.length
33277
+ };
33278
+ }
33279
+ var DEFAULT_IGNORED_DIRS;
33280
+ var init_staging_scanner = __esm({
33281
+ "packages/core/src/orchestrator/staging-scanner.ts"() {
33282
+ "use strict";
33283
+ DEFAULT_IGNORED_DIRS = /* @__PURE__ */ new Set([
33284
+ ".git",
33285
+ "node_modules",
33286
+ ".pnpm-store",
33287
+ ".turbo",
33288
+ ".cache"
33289
+ ]);
33290
+ }
33291
+ });
33292
+
33218
33293
  // packages/core/src/orchestrator/qualification.ts
33219
33294
  function inspectPackageFacts(resolution) {
33220
33295
  const manifest = resolution.manifest;
@@ -33305,7 +33380,8 @@ var init_qualification = __esm({
33305
33380
 
33306
33381
  // packages/core/src/orchestrator/lifecycle-orchestrator.ts
33307
33382
  import { randomUUID as randomUUID5 } from "node:crypto";
33308
- import { basename as basename3, dirname as dirname14 } from "node:path";
33383
+ import { writeFile as writeFile7, mkdir as mkdir15 } from "node:fs/promises";
33384
+ import { basename as basename3, dirname as dirname14, join as join19 } from "node:path";
33309
33385
  function resolveStringInputs(globalInputs, packageInputs, packageId) {
33310
33386
  const merged = {};
33311
33387
  const raw = {
@@ -33342,6 +33418,7 @@ var init_lifecycle_orchestrator = __esm({
33342
33418
  init_journal();
33343
33419
  init_task_runner();
33344
33420
  init_staging_manager();
33421
+ init_staging_scanner();
33345
33422
  init_qualification();
33346
33423
  OrchestratorError = class extends Error {
33347
33424
  code;
@@ -33395,6 +33472,7 @@ var init_lifecycle_orchestrator = __esm({
33395
33472
  options.resolutions,
33396
33473
  options.targets
33397
33474
  );
33475
+ const stagingIntents = [];
33398
33476
  if (hasBeforeCreate) {
33399
33477
  options.onProgress?.("bootstrap-plan", "\u51C6\u5907\u4E24\u9636\u6BB5 Bootstrap Plan");
33400
33478
  for (const res of options.resolutions) {
@@ -33417,6 +33495,17 @@ var init_lifecycle_orchestrator = __esm({
33417
33495
  await executeTasks(beforeTasks, ctx);
33418
33496
  }
33419
33497
  }
33498
+ for (const res of options.resolutions) {
33499
+ const stagingDir = this.stagingManager.getStagingDir(res.packageId);
33500
+ if (stagingDir) {
33501
+ const scanRes = await scanStagingDirectory({
33502
+ stagingDir,
33503
+ packageId: res.packageId,
33504
+ ownerKind: "template"
33505
+ });
33506
+ stagingIntents.push(...scanRes.intents);
33507
+ }
33508
+ }
33420
33509
  }
33421
33510
  options.onProgress?.("materialized-plan", "\u8BA1\u7B97 Materialized Plan \u5E76\u9A8C\u8BC1\u51B2\u7A81");
33422
33511
  const validation = validatePlan(planResult.plan);
@@ -33438,12 +33527,21 @@ var init_lifecycle_orchestrator = __esm({
33438
33527
  success: true,
33439
33528
  operationId,
33440
33529
  plan: planResult.plan,
33441
- intents: []
33530
+ intents: stagingIntents
33442
33531
  };
33443
33532
  }
33444
33533
  options.onProgress?.("commit-core", "\u8FDB\u5165\u4E8B\u52A1\u6267\u884C\u6838\u5FC3\u8D44\u6E90\u5199\u5165");
33445
33534
  const journal = await createJournal(options.userDataDir, options.projectRoot, { operationId });
33446
33535
  let executingJournal = await updateJournal(journal, "executing");
33536
+ if (stagingIntents.length > 0) {
33537
+ for (const intent of stagingIntents) {
33538
+ if (intent.action === "upsert" && intent.type === "file") {
33539
+ const targetPath = join19(options.projectRoot, intent.path);
33540
+ await mkdir15(dirname14(targetPath), { recursive: true });
33541
+ await writeFile7(targetPath, intent.content);
33542
+ }
33543
+ }
33544
+ }
33447
33545
  if (options.operation !== "create") {
33448
33546
  const beforeHookName = `before:${options.operation}`;
33449
33547
  for (const res of options.resolutions) {
@@ -33492,6 +33590,7 @@ var init_orchestrator = __esm({
33492
33590
  "use strict";
33493
33591
  init_types5();
33494
33592
  init_staging_manager();
33593
+ init_staging_scanner();
33495
33594
  init_qualification();
33496
33595
  init_lifecycle_orchestrator();
33497
33596
  }
@@ -33684,6 +33783,7 @@ __export(src_exports, {
33684
33783
  sanitizeEnvValue: () => sanitizeEnvValue,
33685
33784
  sanitizeUrl: () => sanitizeUrl,
33686
33785
  scanJournals: () => scanJournals,
33786
+ scanStagingDirectory: () => scanStagingDirectory,
33687
33787
  scanTemplateDirectoryContract: () => scanTemplateDirectoryContract,
33688
33788
  selectRelease: () => selectRelease,
33689
33789
  serializeTomlValue: () => serializeTomlValue,
@@ -43623,7 +43723,7 @@ var require_dist3 = __commonJS({
43623
43723
  });
43624
43724
 
43625
43725
  // packages/cli/src/commands/extension-pipeline.ts
43626
- import { readFile as readFile23, writeFile as writeFile7 } from "node:fs/promises";
43726
+ import { readFile as readFile24, writeFile as writeFile8 } from "node:fs/promises";
43627
43727
  import { existsSync as existsSync5 } from "node:fs";
43628
43728
  import { resolve as resolve14 } from "node:path";
43629
43729
  function generateGitlabCiYaml(packageId) {
@@ -43705,7 +43805,7 @@ async function executeExtensionPipeline(directory, options) {
43705
43805
  if (!packageId) {
43706
43806
  if (existsSync5(manifestPath)) {
43707
43807
  try {
43708
- const manifestContent = await readFile23(manifestPath, "utf-8");
43808
+ const manifestContent = await readFile24(manifestPath, "utf-8");
43709
43809
  const parsed = import_yaml4.default.parse(manifestContent);
43710
43810
  if (parsed && typeof parsed.id === "string") {
43711
43811
  packageId = parsed.id;
@@ -43715,7 +43815,7 @@ async function executeExtensionPipeline(directory, options) {
43715
43815
  }
43716
43816
  if (!packageId && existsSync5(pkgJsonPath)) {
43717
43817
  try {
43718
- const pkgContent = await readFile23(pkgJsonPath, "utf-8");
43818
+ const pkgContent = await readFile24(pkgJsonPath, "utf-8");
43719
43819
  const parsed = JSON.parse(pkgContent);
43720
43820
  if (parsed && typeof parsed.name === "string") {
43721
43821
  packageId = parsed.name;
@@ -43756,16 +43856,16 @@ async function executeExtensionPipeline(directory, options) {
43756
43856
  }
43757
43857
  }
43758
43858
  const ciContent = generateGitlabCiYaml(packageId);
43759
- await writeFile7(ciFilePath, ciContent, "utf-8");
43859
+ await writeFile8(ciFilePath, ciContent, "utf-8");
43760
43860
  let addedReleaseScript = false;
43761
43861
  if (existsSync5(pkgJsonPath)) {
43762
43862
  try {
43763
- const pkgContent = await readFile23(pkgJsonPath, "utf-8");
43863
+ const pkgContent = await readFile24(pkgJsonPath, "utf-8");
43764
43864
  const parsed = JSON.parse(pkgContent);
43765
43865
  parsed.scripts = parsed.scripts || {};
43766
43866
  if (!parsed.scripts.release) {
43767
43867
  parsed.scripts.release = "npm version patch";
43768
- await writeFile7(pkgJsonPath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
43868
+ await writeFile8(pkgJsonPath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
43769
43869
  addedReleaseScript = true;
43770
43870
  }
43771
43871
  } catch {
@@ -43809,7 +43909,7 @@ var init_extension_pipeline = __esm({
43809
43909
  });
43810
43910
 
43811
43911
  // packages/cli/src/commands/extension-create.ts
43812
- import { mkdir as mkdir15, writeFile as writeFile8, readdir as readdir8 } from "node:fs/promises";
43912
+ import { mkdir as mkdir16, writeFile as writeFile9, readdir as readdir9 } from "node:fs/promises";
43813
43913
  import { basename as basename4, resolve as resolve15 } from "node:path";
43814
43914
  function createExtensionCreateCommand() {
43815
43915
  const cmd = new Command("create");
@@ -43858,7 +43958,7 @@ async function executeExtensionCreate(directory, options) {
43858
43958
  const dirBase = basename4(targetDir);
43859
43959
  const isInteractive = !options.yes && !options.json && Boolean(process.stdin.isTTY);
43860
43960
  try {
43861
- const entries = await readdir8(targetDir);
43961
+ const entries = await readdir9(targetDir);
43862
43962
  if (entries.length > 0) {
43863
43963
  if (output.json) {
43864
43964
  emitFailureJson(
@@ -43922,7 +44022,7 @@ async function executeExtensionCreate(directory, options) {
43922
44022
  default: true
43923
44023
  });
43924
44024
  }
43925
- await mkdir15(targetDir, { recursive: true });
44025
+ await mkdir16(targetDir, { recursive: true });
43926
44026
  const scripts = {
43927
44027
  test: "vitest"
43928
44028
  };
@@ -43948,7 +44048,7 @@ async function executeExtensionCreate(directory, options) {
43948
44048
  vitest: "^3.0.5"
43949
44049
  }
43950
44050
  };
43951
- await writeFile8(resolve15(targetDir, "package.json"), JSON.stringify(pkgJson, null, 2) + "\n", "utf-8");
44051
+ await writeFile9(resolve15(targetDir, "package.json"), JSON.stringify(pkgJson, null, 2) + "\n", "utf-8");
43952
44052
  const manifestLines = [
43953
44053
  `id: "${packageId}"`,
43954
44054
  "version: 0.1.0",
@@ -43970,7 +44070,7 @@ async function executeExtensionCreate(directory, options) {
43970
44070
  manifestLines.push(" on:");
43971
44071
  manifestLines.push(" - after:create");
43972
44072
  }
43973
- await writeFile8(resolve15(targetDir, "manifest.yaml"), manifestLines.join("\n") + "\n", "utf-8");
44073
+ await writeFile9(resolve15(targetDir, "manifest.yaml"), manifestLines.join("\n") + "\n", "utf-8");
43974
44074
  const agentsMdContent = `# ${templateName} Agent \u6307\u5357
43975
44075
 
43976
44076
  \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
@@ -43982,9 +44082,9 @@ async function executeExtensionCreate(directory, options) {
43982
44082
  ## 2. \u4EA4\u4E92\u4E0E\u6CE8\u91CA
43983
44083
  - \u4EE3\u7801\u6CE8\u91CA\u4E0E\u56DE\u7B54\u8BF7\u59CB\u7EC8\u4F7F\u7528\u7B80\u4F53\u4E2D\u6587\u3002
43984
44084
  `;
43985
- await writeFile8(resolve15(targetDir, "AGENTS.md"), agentsMdContent, "utf-8");
44085
+ await writeFile9(resolve15(targetDir, "AGENTS.md"), agentsMdContent, "utf-8");
43986
44086
  const skillDir = resolve15(targetDir, "skills", "example-skill");
43987
- await mkdir15(skillDir, { recursive: true });
44087
+ await mkdir16(skillDir, { recursive: true });
43988
44088
  const skillContent = `---
43989
44089
  name: example-skill
43990
44090
  description: ${templateName} \u793A\u4F8B Agent \u6280\u80FD\uFF0C\u6307\u5BFC AI \u6309\u7167\u6700\u4F73\u5B9E\u8DF5\u5B8C\u6210\u7279\u5B9A\u4EFB\u52A1
@@ -44000,9 +44100,9 @@ description: ${templateName} \u793A\u4F8B Agent \u6280\u80FD\uFF0C\u6307\u5BFC A
44000
44100
  2. \u9075\u5FAA\u672C\u9879\u76EE\u7684\u67B6\u6784\u8BBE\u8BA1\u539F\u5219\u5B9E\u73B0\u4EE3\u7801\u3002
44001
44101
  3. \u7F16\u5199\u5BF9\u5E94\u6D4B\u8BD5\u5E76\u9A8C\u8BC1\u3002
44002
44102
  `;
44003
- await writeFile8(resolve15(skillDir, "SKILL.md"), skillContent, "utf-8");
44103
+ await writeFile9(resolve15(skillDir, "SKILL.md"), skillContent, "utf-8");
44004
44104
  const cursorRulesDir = resolve15(targetDir, "rules", "cursor");
44005
- await mkdir15(cursorRulesDir, { recursive: true });
44105
+ await mkdir16(cursorRulesDir, { recursive: true });
44006
44106
  const cursorRuleContent = `---
44007
44107
  description: ${templateName} Cursor \u7F16\u7801\u89C4\u5219
44008
44108
  globs: *
@@ -44014,17 +44114,17 @@ alwaysApply: false
44014
44114
  - \u4F18\u5148\u4F7F\u7528\u73B0\u6709\u7684\u8BBE\u8BA1\u7CFB\u7EDF\u548C\u516C\u5171\u7EC4\u4EF6\u3002
44015
44115
  - \u4FDD\u6301\u51FD\u6570\u4E0E\u6A21\u5757\u7B80\u6D01\uFF0C\u5355\u4E00\u804C\u8D23\u3002
44016
44116
  `;
44017
- await writeFile8(resolve15(cursorRulesDir, "example-rule.mdc"), cursorRuleContent, "utf-8");
44117
+ await writeFile9(resolve15(cursorRulesDir, "example-rule.mdc"), cursorRuleContent, "utf-8");
44018
44118
  const codebuddyRulesDir = resolve15(targetDir, "rules", "codebuddy");
44019
- await mkdir15(codebuddyRulesDir, { recursive: true });
44119
+ await mkdir16(codebuddyRulesDir, { recursive: true });
44020
44120
  const codebuddyRuleContent = `# ${templateName} \u7F16\u7801\u89C4\u5219 (CodeBuddy)
44021
44121
 
44022
44122
  - \u9075\u5FAA\u4EE3\u7801\u8BBE\u8BA1\u539F\u5219\u3002
44023
44123
  - \u5355\u5143\u6D4B\u8BD5\u8986\u76D6\u6838\u5FC3\u903B\u8F91\u5206\u652F\u3002
44024
44124
  `;
44025
- await writeFile8(resolve15(codebuddyRulesDir, "example-rule.md"), codebuddyRuleContent, "utf-8");
44125
+ await writeFile9(resolve15(codebuddyRulesDir, "example-rule.md"), codebuddyRuleContent, "utf-8");
44026
44126
  const mcpDir = resolve15(targetDir, "mcp");
44027
- await mkdir15(mcpDir, { recursive: true });
44127
+ await mkdir16(mcpDir, { recursive: true });
44028
44128
  const mcpJsonContent = {
44029
44129
  mcpServers: {
44030
44130
  "example-server": {
@@ -44033,9 +44133,9 @@ alwaysApply: false
44033
44133
  }
44034
44134
  }
44035
44135
  };
44036
- await writeFile8(resolve15(mcpDir, "mcp.json"), JSON.stringify(mcpJsonContent, null, 2) + "\n", "utf-8");
44136
+ await writeFile9(resolve15(mcpDir, "mcp.json"), JSON.stringify(mcpJsonContent, null, 2) + "\n", "utf-8");
44037
44137
  const testDir = resolve15(targetDir, "test");
44038
- await mkdir15(testDir, { recursive: true });
44138
+ await mkdir16(testDir, { recursive: true });
44039
44139
  const testContent = `import { describe, expect, it } from 'vitest';
44040
44140
  import { readFile } from 'node:fs/promises';
44041
44141
  import { resolve } from 'node:path';
@@ -44048,7 +44148,7 @@ describe('${packageId} template manifest', () => {
44048
44148
  });
44049
44149
  });
44050
44150
  `;
44051
- await writeFile8(resolve15(testDir, "manifest.test.ts"), testContent, "utf-8");
44151
+ await writeFile9(resolve15(testDir, "manifest.test.ts"), testContent, "utf-8");
44052
44152
  const createdFiles = [
44053
44153
  "manifest.yaml",
44054
44154
  "AGENTS.md",
@@ -44061,7 +44161,7 @@ describe('${packageId} template manifest', () => {
44061
44161
  "test/manifest.test.ts"
44062
44162
  ];
44063
44163
  if (withPipeline) {
44064
- await writeFile8(
44164
+ await writeFile9(
44065
44165
  resolve15(targetDir, ".gitlab-ci.yml"),
44066
44166
  generateGitlabCiYaml(packageId),
44067
44167
  "utf-8"
@@ -44075,7 +44175,7 @@ describe('${packageId} template manifest', () => {
44075
44175
  withTasks: Boolean(withTasks),
44076
44176
  withPipeline: Boolean(withPipeline)
44077
44177
  });
44078
- await writeFile8(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44178
+ await writeFile9(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44079
44179
  if (output.json) {
44080
44180
  emitSuccessJson("extension create", {
44081
44181
  directory: targetDir,
@@ -44380,9 +44480,9 @@ var init_shared_options = __esm({
44380
44480
  });
44381
44481
 
44382
44482
  // packages/cli/src/commands/extension-dev.ts
44383
- import { mkdtemp as mkdtemp6, readFile as readFile24 } from "node:fs/promises";
44483
+ import { mkdtemp as mkdtemp6, readFile as readFile25 } from "node:fs/promises";
44384
44484
  import { tmpdir as tmpdir6 } from "node:os";
44385
- import { join as join18, resolve as resolvePath9, relative as relative7, isAbsolute as isAbsolute6, sep as sep4 } from "node:path";
44485
+ import { join as join20, resolve as resolvePath9, relative as relative8, isAbsolute as isAbsolute6, sep as sep4 } from "node:path";
44386
44486
  function createExtensionDevCommand() {
44387
44487
  const cmd = new Command("dev");
44388
44488
  cmd.description(t("extension.dev.description")).argument("[package-directory]", t("extension.dev.argPackageDirectory"), ".").requiredOption("--project <fixture-directory>", t("extension.dev.optionProject")).option("--operation <create|apply|sync|remove>", t("extension.dev.optionOperation"), "apply").option("--target <id>", t("mutation.target"), collectString2, []).option("--set <name=value>", t("mutation.set"), collectString2, []).option("--dry-run", t("mutation.dryRun")).option("--yes", t("mutation.yes")).option("--allow <permission>", t("mutation.allow"), collectString2, []).option("--watch", t("extension.dev.optionWatch")).action(async (packageDirectory, opts) => {
@@ -44436,7 +44536,7 @@ async function executeExtensionDev(packageDirectory, options) {
44436
44536
  return ExitCode.SchemaInvalid;
44437
44537
  }
44438
44538
  const effectiveDryRun = options.dryRun || options.watch;
44439
- const isolatedUserData = await mkdtemp6(join18(tmpdir6(), "aicoding-dev-userdata-"));
44539
+ const isolatedUserData = await mkdtemp6(join20(tmpdir6(), "aicoding-dev-userdata-"));
44440
44540
  const prevUserData = process.env["AICODING_USER_DATA"];
44441
44541
  process.env["AICODING_USER_DATA"] = isolatedUserData;
44442
44542
  try {
@@ -44497,7 +44597,7 @@ async function readPackageId(packageDirectory) {
44497
44597
  const manifestPath = resolvePath9(process.cwd(), packageDirectory, "manifest.yaml");
44498
44598
  let content;
44499
44599
  try {
44500
- content = await readFile24(manifestPath, "utf-8");
44600
+ content = await readFile25(manifestPath, "utf-8");
44501
44601
  } catch {
44502
44602
  throw new CliError(`\u672A\u5728 '${packageDirectory}' \u4E0B\u627E\u5230 manifest.yaml`, ExitCode.ResolveFailed, "DEV_MANIFEST_NOT_FOUND");
44503
44603
  }
@@ -44510,7 +44610,7 @@ async function readPackageId(packageDirectory) {
44510
44610
  function getProjectRelativeSourcePath(packageDirectory, project) {
44511
44611
  const packageAbs = resolvePath9(process.cwd(), packageDirectory);
44512
44612
  const projectAbs = resolvePath9(process.cwd(), project);
44513
- const relativePath = relative7(projectAbs, packageAbs).split(sep4).join("/");
44613
+ const relativePath = relative8(projectAbs, packageAbs).split(sep4).join("/");
44514
44614
  if (relativePath === ".." || relativePath.startsWith("../") || isAbsolute6(relativePath)) {
44515
44615
  throw new CliError(
44516
44616
  `\u6269\u5C55\u5305\u76EE\u5F55\u5FC5\u987B\u5728 fixture \u9879\u76EE\u76EE\u5F55\u5185\uFF08local \u6E90\u8DEF\u5F84\u9700\u4E3A\u9879\u76EE\u76F8\u5BF9\u8DEF\u5F84\uFF09\u3002\u8BF7\u5C06 '${packageDirectory}' \u79FB\u52A8\u6216\u94FE\u63A5\u5230 '${project}' \u5185\u3002`,
@@ -44532,7 +44632,7 @@ var init_extension_dev = __esm({
44532
44632
  });
44533
44633
 
44534
44634
  // packages/cli/src/commands/extension-test.ts
44535
- import { readFile as readFile25 } from "node:fs/promises";
44635
+ import { readFile as readFile26 } from "node:fs/promises";
44536
44636
  import { resolve as resolve16 } from "node:path";
44537
44637
  import { execFile as execFile3 } from "node:child_process";
44538
44638
  import { promisify as promisify4 } from "node:util";
@@ -44597,7 +44697,7 @@ async function executeExtensionTest(packageDirectory, options, cliVersion) {
44597
44697
  let hasTestScript = false;
44598
44698
  let isNpmPackage = false;
44599
44699
  try {
44600
- const pkgJsonContent = await readFile25(resolve16(pkgDir, "package.json"), "utf-8");
44700
+ const pkgJsonContent = await readFile26(resolve16(pkgDir, "package.json"), "utf-8");
44601
44701
  const pkgJson = JSON.parse(pkgJsonContent);
44602
44702
  hasTestScript = Boolean(pkgJson.scripts?.test);
44603
44703
  isNpmPackage = Boolean(pkgJson.name);
@@ -44676,8 +44776,8 @@ var init_extension_test = __esm({
44676
44776
  });
44677
44777
 
44678
44778
  // packages/cli/src/commands/extension-pack.ts
44679
- import { readFile as readFile26, mkdir as mkdir16 } from "node:fs/promises";
44680
- import { resolve as resolve17, join as join19, dirname as dirname15 } from "node:path";
44779
+ import { readFile as readFile27, mkdir as mkdir17 } from "node:fs/promises";
44780
+ import { resolve as resolve17, join as join21, dirname as dirname15 } from "node:path";
44681
44781
  import { execFile as execFile4 } from "node:child_process";
44682
44782
  import { promisify as promisify5 } from "node:util";
44683
44783
  import { createHash as createHash13 } from "node:crypto";
@@ -44747,7 +44847,7 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
44747
44847
  let pkgJson;
44748
44848
  let pkgJsonRaw;
44749
44849
  try {
44750
- pkgJsonRaw = await readFile26(resolve17(pkgDir, "package.json"), "utf-8");
44850
+ pkgJsonRaw = await readFile27(resolve17(pkgDir, "package.json"), "utf-8");
44751
44851
  pkgJson = JSON.parse(pkgJsonRaw);
44752
44852
  } catch {
44753
44853
  if (output.json) {
@@ -44826,11 +44926,11 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
44826
44926
  }
44827
44927
  }
44828
44928
  const outputDir = options.output ? resolve17(options.output) : resolve17(pkgDir, "dist-package");
44829
- await mkdir16(outputDir, { recursive: true });
44929
+ await mkdir17(outputDir, { recursive: true });
44830
44930
  let tarballName;
44831
44931
  let tarballPath;
44832
44932
  tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
44833
- tarballPath = join19(outputDir, tarballName);
44933
+ tarballPath = join21(outputDir, tarballName);
44834
44934
  try {
44835
44935
  await packWithNpm(pkgDir, outputDir);
44836
44936
  } catch (err) {
@@ -44847,7 +44947,7 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
44847
44947
  let sri = "";
44848
44948
  let manifestDigest = "";
44849
44949
  try {
44850
- const tarballContent = await readFile26(tarballPath);
44950
+ const tarballContent = await readFile27(tarballPath);
44851
44951
  sri = "sha512-" + createHash13("sha512").update(tarballContent).digest("base64");
44852
44952
  } catch {
44853
44953
  if (output.json) {
@@ -44859,7 +44959,7 @@ async function executeExtensionPack(packageDirectory, options, cliVersion) {
44859
44959
  return ExitCode.ExecuteFailed;
44860
44960
  }
44861
44961
  try {
44862
- const manifestContent = await readFile26(resolve17(pkgDir, "manifest.yaml"));
44962
+ const manifestContent = await readFile27(resolve17(pkgDir, "manifest.yaml"));
44863
44963
  manifestDigest = createHash13("sha256").update(manifestContent).digest("hex");
44864
44964
  } catch {
44865
44965
  }
@@ -44899,7 +44999,7 @@ var init_extension_pack = __esm({
44899
44999
  });
44900
45000
 
44901
45001
  // packages/cli/src/commands/extension-submit.ts
44902
- import { readFile as readFile27 } from "node:fs/promises";
45002
+ import { readFile as readFile28 } from "node:fs/promises";
44903
45003
  import { resolve as resolve18 } from "node:path";
44904
45004
  function createExtensionSubmitCommand(cliVersion) {
44905
45005
  const cmd = new Command("submit");
@@ -44962,7 +45062,7 @@ async function executeExtensionSubmit(packageDirectory, options, cliVersion) {
44962
45062
  let pkgName = "";
44963
45063
  let pkgVersion = "";
44964
45064
  try {
44965
- const pkgJsonRaw = await readFile27(resolve18(pkgDir, "package.json"), "utf-8");
45065
+ const pkgJsonRaw = await readFile28(resolve18(pkgDir, "package.json"), "utf-8");
44966
45066
  const pkgJson = JSON.parse(pkgJsonRaw);
44967
45067
  pkgName = pkgJson.name ?? "";
44968
45068
  pkgVersion = pkgJson.version ?? "";
@@ -45070,7 +45170,7 @@ var init_extension_submit = __esm({
45070
45170
  });
45071
45171
 
45072
45172
  // packages/cli/src/commands/extension-adapter.ts
45073
- import { readFile as readFile28, mkdir as mkdir17 } from "node:fs/promises";
45173
+ import { readFile as readFile29, mkdir as mkdir18 } from "node:fs/promises";
45074
45174
  import { dirname as dirname16, resolve as resolve19 } from "node:path";
45075
45175
  import { execFile as execFile5 } from "node:child_process";
45076
45176
  import { promisify as promisify6 } from "node:util";
@@ -45293,7 +45393,7 @@ async function executeAdapterTest(packageDirectory, options) {
45293
45393
  }
45294
45394
  let hasTestScript = false;
45295
45395
  try {
45296
- const pkgJsonRaw = await readFile28(resolve19(pkgDir, "package.json"), "utf-8");
45396
+ const pkgJsonRaw = await readFile29(resolve19(pkgDir, "package.json"), "utf-8");
45297
45397
  const pkgJson = JSON.parse(pkgJsonRaw);
45298
45398
  hasTestScript = Boolean(pkgJson.scripts?.test);
45299
45399
  } catch {
@@ -45381,7 +45481,7 @@ async function executeAdapterPack(packageDirectory, options) {
45381
45481
  let pkgVersion = "";
45382
45482
  let files = [];
45383
45483
  try {
45384
- const pkgJsonRaw = await readFile28(resolve19(pkgDir, "package.json"), "utf-8");
45484
+ const pkgJsonRaw = await readFile29(resolve19(pkgDir, "package.json"), "utf-8");
45385
45485
  const pkgJson = JSON.parse(pkgJsonRaw);
45386
45486
  pkgName = pkgJson.name ?? "";
45387
45487
  pkgVersion = pkgJson.version ?? "";
@@ -45414,7 +45514,7 @@ async function executeAdapterPack(packageDirectory, options) {
45414
45514
  return ExitCode.SchemaInvalid;
45415
45515
  }
45416
45516
  const outputDir = options.output ? resolve19(options.output) : resolve19(pkgDir, "dist-package");
45417
- await mkdir17(outputDir, { recursive: true });
45517
+ await mkdir18(outputDir, { recursive: true });
45418
45518
  const tarballName = `${pkgName.replace(/^@/, "").replace(/\//g, "-")}-${pkgVersion}.tgz`;
45419
45519
  const tarballPath = resolve19(outputDir, tarballName);
45420
45520
  try {
@@ -45429,7 +45529,7 @@ async function executeAdapterPack(packageDirectory, options) {
45429
45529
  }
45430
45530
  return ExitCode.ExecuteFailed;
45431
45531
  }
45432
- const tarballContent = await readFile28(tarballPath);
45532
+ const tarballContent = await readFile29(tarballPath);
45433
45533
  const sri = "sha512-" + createHash14("sha512").update(tarballContent).digest("base64");
45434
45534
  if (output.json) {
45435
45535
  emitSuccessJson("extension adapter pack", {
@@ -45615,7 +45715,7 @@ var init_journal_helper = __esm({
45615
45715
 
45616
45716
  // packages/cli/src/commands/service-locator.ts
45617
45717
  import { homedir as homedir2 } from "node:os";
45618
- import { join as join20, resolve as resolve20 } from "node:path";
45718
+ import { join as join22, resolve as resolve20 } from "node:path";
45619
45719
  var ServiceLocator;
45620
45720
  var init_service_locator = __esm({
45621
45721
  "packages/cli/src/commands/service-locator.ts"() {
@@ -45649,13 +45749,13 @@ var init_service_locator = __esm({
45649
45749
  return `mano-coding@${this.config.cliVersion}`;
45650
45750
  }
45651
45751
  getUserDataDir() {
45652
- return this.config.userDataDir ?? process.env["MANO_USER_DATA"] ?? process.env["AICODING_USER_DATA"] ?? join20(homedir2(), ".mano-coding");
45752
+ return this.config.userDataDir ?? process.env["MANO_USER_DATA"] ?? process.env["AICODING_USER_DATA"] ?? join22(homedir2(), ".mano-coding");
45653
45753
  }
45654
45754
  getRegistryUrl() {
45655
45755
  return this.config.registryUrl || process.env["MANO_REGISTRY"] || process.env["AICODING_REGISTRY"] || DEFAULT_PUBLIC_REGISTRY_URL;
45656
45756
  }
45657
45757
  getCacheRoot() {
45658
- return this.config.cacheRoot ?? join20(this.getUserDataDir(), "cache");
45758
+ return this.config.cacheRoot ?? join22(this.getUserDataDir(), "cache");
45659
45759
  }
45660
45760
  getRegistryClient() {
45661
45761
  if (!this._registryClient) {
@@ -45810,8 +45910,8 @@ var init_service_locator = __esm({
45810
45910
  });
45811
45911
 
45812
45912
  // packages/cli/src/commands/plan-execution.ts
45813
- import { readFile as readFile29, readdir as readdir9, stat as stat6 } from "node:fs/promises";
45814
- import { join as join21, resolve as resolve21 } from "node:path";
45913
+ import { readFile as readFile30, readdir as readdir10, stat as stat7 } from "node:fs/promises";
45914
+ import { join as join23, resolve as resolve21 } from "node:path";
45815
45915
  import { createHash as createHash15 } from "node:crypto";
45816
45916
  async function buildIntentsFromPlan(_plan, resolutions, service, projectTargets, _userInstallationKeys, options) {
45817
45917
  const adapterRegistry = service.getAdapterRegistry();
@@ -45920,14 +46020,14 @@ async function executeUserCapabilityInstallations(_resolutions, _service, _input
45920
46020
  }
45921
46021
  async function collectAssetIntents(packageRoot, source, destination, metadata) {
45922
46022
  const sourcePath = resolve21(packageRoot, source);
45923
- const sourceStat = await stat6(sourcePath);
46023
+ const sourceStat = await stat7(sourcePath);
45924
46024
  if (sourceStat.isFile()) {
45925
- return [{ action: "upsert", type: "file", path: destination, content: await readFile29(sourcePath), executable: metadata.executable, packageId: metadata.packageId, ownerKind: metadata.ownerKind }];
46025
+ return [{ action: "upsert", type: "file", path: destination, content: await readFile30(sourcePath), executable: metadata.executable, packageId: metadata.packageId, ownerKind: metadata.ownerKind }];
45926
46026
  }
45927
46027
  if (!sourceStat.isDirectory()) throw new Error(`Asset '${source}' \u65E2\u4E0D\u662F\u6587\u4EF6\u4E5F\u4E0D\u662F\u76EE\u5F55`);
45928
46028
  const intents = [];
45929
- for (const entry of await readdir9(sourcePath, { withFileTypes: true })) {
45930
- intents.push(...await collectAssetIntents(packageRoot, join21(source, entry.name), join21(destination, entry.name).replaceAll("\\", "/"), metadata));
46029
+ for (const entry of await readdir10(sourcePath, { withFileTypes: true })) {
46030
+ intents.push(...await collectAssetIntents(packageRoot, join23(source, entry.name), join23(destination, entry.name).replaceAll("\\", "/"), metadata));
45931
46031
  }
45932
46032
  return intents;
45933
46033
  }
@@ -46764,243 +46864,300 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
46764
46864
  await service.registerThirdPartyAdapters(
46765
46865
  allResolutions.map((r) => ({ manifest: r.manifest, resolution: r }))
46766
46866
  );
46767
- const planStartedAt = Date.now();
46768
- const planBuilder = service.getPlanBuilder();
46769
- let planResult = planBuilder.build(
46770
- "create",
46771
- service.projectRoot,
46772
- allResolutions,
46773
- projectTargets
46774
- );
46775
- const userInstallationKeys = /* @__PURE__ */ new Set();
46776
- const intents = await withSpinner(
46777
- "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
46778
- () => buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys),
46779
- {
46780
- enabled: spinnerEnabled,
46781
- successText: (res) => `\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 ${res.length} \u9879\u8D44\u6E90\u53D8\u66F4)`,
46782
- failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
46783
- }
46784
- );
46785
- planResult = materializePlan(planResult.plan, intents);
46786
- events.report("plan", "success", Date.now() - planStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: intents.length } });
46787
- if (planResult.conflicts.length > 0) {
46788
- events.report("plan", "failure", 0, { errorCode: "PLAN_CONFLICT", planDigest: planResult.plan.planDigest });
46789
- const conflictDiags = planResult.conflicts.flatMap((c) => c.diagnostics);
46790
- writeDiagnostics(conflictDiags, output);
46791
- if (output.json) {
46792
- emitFailureJson(
46793
- "create",
46794
- "PLAN_CONFLICT",
46795
- t("create.planConflict"),
46796
- { conflicts: planResult.conflicts.map((c) => ({ type: c.type, resourceKey: c.resourceKey })) },
46797
- [],
46798
- conflictDiags,
46799
- jsonEvents()
46800
- );
46801
- } else {
46802
- process.stderr.write(`error: PLAN_CONFLICT: ${t("create.planConflict")}
46803
- `);
46867
+ const stagingManager = new StagingManager();
46868
+ try {
46869
+ const hasBeforeCreate = allResolutions.some((res) => {
46870
+ const tasks = res.manifest.tasks ?? [];
46871
+ return filterTasksByHook2(tasks, "before:create").length > 0;
46872
+ });
46873
+ const stagingDirMap = /* @__PURE__ */ new Map();
46874
+ if (hasBeforeCreate) {
46875
+ for (const res of allResolutions) {
46876
+ const tasks = res.manifest.tasks ?? [];
46877
+ if (filterTasksByHook2(tasks, "before:create").length > 0) {
46878
+ const sDir = await stagingManager.getOrCreateStagingDir(res.manifest.id);
46879
+ stagingDirMap.set(res.manifest.id, sDir);
46880
+ }
46881
+ }
46804
46882
  }
46805
- return ExitCode.ConflictOrDrift;
46806
- }
46807
- let grantedPermissions = [];
46808
- if (!options.dryRun && !options.yes) {
46809
- if (options.noInput || !process.stdin.isTTY) {
46810
- events.report("authorize", "failure", 0, { errorCode: "NEEDS_CONFIRMATION", planDigest: planResult.plan.planDigest });
46883
+ const planStartedAt = Date.now();
46884
+ const planBuilder = service.getPlanBuilder();
46885
+ let planResult = planBuilder.build(
46886
+ "create",
46887
+ service.projectRoot,
46888
+ allResolutions,
46889
+ projectTargets
46890
+ );
46891
+ const userInstallationKeys = /* @__PURE__ */ new Set();
46892
+ let staticIntents = await withSpinner(
46893
+ "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
46894
+ () => buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys),
46895
+ {
46896
+ enabled: spinnerEnabled,
46897
+ successText: (res) => `\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 ${res.length} \u9879\u8D44\u6E90\u53D8\u66F4)`,
46898
+ failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
46899
+ }
46900
+ );
46901
+ planResult = materializePlan(planResult.plan, staticIntents);
46902
+ events.report("plan", "success", Date.now() - planStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: staticIntents.length } });
46903
+ if (planResult.conflicts.length > 0) {
46904
+ events.report("plan", "failure", 0, { errorCode: "PLAN_CONFLICT", planDigest: planResult.plan.planDigest });
46905
+ const conflictDiags = planResult.conflicts.flatMap((c) => c.diagnostics);
46906
+ writeDiagnostics(conflictDiags, output);
46811
46907
  if (output.json) {
46812
46908
  emitFailureJson(
46813
46909
  "create",
46814
- "NEEDS_CONFIRMATION",
46815
- t("create.needsConfirmation"),
46816
- { planDigest: planResult.plan.planDigest },
46817
- [],
46910
+ "PLAN_CONFLICT",
46911
+ t("create.planConflict"),
46912
+ { conflicts: planResult.conflicts.map((c) => ({ type: c.type, resourceKey: c.resourceKey })) },
46818
46913
  [],
46914
+ conflictDiags,
46819
46915
  jsonEvents()
46820
46916
  );
46821
46917
  } else {
46822
- process.stderr.write(
46823
- `error: NEEDS_CONFIRMATION: ${t("create.needsConfirmation")}
46918
+ process.stderr.write(`error: PLAN_CONFLICT: ${t("create.planConflict")}
46919
+ `);
46920
+ }
46921
+ return ExitCode.ConflictOrDrift;
46922
+ }
46923
+ let grantedPermissions = [];
46924
+ if (!options.dryRun && !options.yes) {
46925
+ if (options.noInput || !process.stdin.isTTY) {
46926
+ events.report("authorize", "failure", 0, { errorCode: "NEEDS_CONFIRMATION", planDigest: planResult.plan.planDigest });
46927
+ if (output.json) {
46928
+ emitFailureJson(
46929
+ "create",
46930
+ "NEEDS_CONFIRMATION",
46931
+ t("create.needsConfirmation"),
46932
+ { planDigest: planResult.plan.planDigest },
46933
+ [],
46934
+ [],
46935
+ jsonEvents()
46936
+ );
46937
+ } else {
46938
+ process.stderr.write(
46939
+ `error: NEEDS_CONFIRMATION: ${t("create.needsConfirmation")}
46824
46940
  `
46825
- );
46941
+ );
46942
+ }
46943
+ return ExitCode.NeedsInputOrDenied;
46826
46944
  }
46827
- return ExitCode.NeedsInputOrDenied;
46945
+ const { confirmPlanInteractive: confirmPlanInteractive2 } = await Promise.resolve().then(() => (init_tty_confirm(), tty_confirm_exports));
46946
+ const confirmResult = await confirmPlanInteractive2({
46947
+ output,
46948
+ command: "create",
46949
+ plan: planResult.plan,
46950
+ allowedPermissions: options.allow
46951
+ });
46952
+ if (!confirmResult.confirmed) {
46953
+ events.report("authorize", "failure", 0, { errorCode: "PERMISSION_DENIED", planDigest: planResult.plan.planDigest });
46954
+ if (output.json) {
46955
+ emitFailureJson("create", "PERMISSION_DENIED", t("create.userDeclined"), { planDigest: planResult.plan.planDigest }, [], [], jsonEvents());
46956
+ } else {
46957
+ process.stderr.write(`error: PERMISSION_DENIED: ${t("create.userDeclined")}
46958
+ `);
46959
+ }
46960
+ return ExitCode.NeedsInputOrDenied;
46961
+ }
46962
+ events.report("authorize", "success", 0, { planDigest: planResult.plan.planDigest });
46963
+ grantedPermissions = confirmResult.granted;
46828
46964
  }
46829
- const { confirmPlanInteractive: confirmPlanInteractive2 } = await Promise.resolve().then(() => (init_tty_confirm(), tty_confirm_exports));
46830
- const confirmResult = await confirmPlanInteractive2({
46831
- output,
46832
- command: "create",
46833
- plan: planResult.plan,
46834
- allowedPermissions: options.allow
46835
- });
46836
- if (!confirmResult.confirmed) {
46837
- events.report("authorize", "failure", 0, { errorCode: "PERMISSION_DENIED", planDigest: planResult.plan.planDigest });
46965
+ if (options.dryRun) {
46966
+ events.report("authorize", "skipped", 0, { planDigest: planResult.plan.planDigest });
46967
+ events.report("execute", "skipped", 0, { planDigest: planResult.plan.planDigest });
46968
+ events.report("record", "skipped", 0, { planDigest: planResult.plan.planDigest });
46969
+ const summary2 = summarizePlan(planResult.plan);
46838
46970
  if (output.json) {
46839
- emitFailureJson("create", "PERMISSION_DENIED", t("create.userDeclined"), { planDigest: planResult.plan.planDigest }, [], [], jsonEvents());
46971
+ emitSuccessJson("create", { dryRun: true, ...summary2 }, [], [], jsonEvents());
46840
46972
  } else {
46841
- process.stderr.write(`error: PERMISSION_DENIED: ${t("create.userDeclined")}
46842
- `);
46973
+ printPlanSummary(summary2);
46843
46974
  }
46844
- return ExitCode.NeedsInputOrDenied;
46845
- }
46846
- events.report("authorize", "success", 0, { planDigest: planResult.plan.planDigest });
46847
- grantedPermissions = confirmResult.granted;
46848
- }
46849
- if (options.dryRun) {
46850
- events.report("authorize", "skipped", 0, { planDigest: planResult.plan.planDigest });
46851
- events.report("execute", "skipped", 0, { planDigest: planResult.plan.planDigest });
46852
- events.report("record", "skipped", 0, { planDigest: planResult.plan.planDigest });
46853
- const summary2 = summarizePlan(planResult.plan);
46854
- if (output.json) {
46855
- emitSuccessJson("create", { dryRun: true, ...summary2 }, [], [], jsonEvents());
46856
- } else {
46857
- printPlanSummary(summary2);
46975
+ return ExitCode.Success;
46858
46976
  }
46859
- return ExitCode.Success;
46860
- }
46861
- const { basename: basename8, dirname: dirname20 } = await import("node:path");
46862
- for (let pkgIdx = 0; pkgIdx < allResolutions.length; pkgIdx++) {
46863
- const resolution = allResolutions[pkgIdx];
46864
- const pkgTasks = filterTasksByHook2(resolution.manifest.tasks ?? [], "before:create");
46865
- if (pkgTasks.length > 0) {
46866
- const templateDir = service.getPackageRoot(resolution) ?? service.projectRoot;
46867
- const taskContext = {
46868
- projectName: basename8(service.projectRoot),
46869
- projectDir: service.projectRoot,
46870
- projectParentDir: dirname20(service.projectRoot),
46871
- templateDir,
46872
- inputs: { ...inputValues, ...packageValues[resolution.manifest.id] ?? {} },
46873
- target: projectTargets[0]?.id,
46874
- targets: projectTargets.map((t2) => t2.id),
46875
- operation: "create",
46876
- version: resolution.manifest.version
46877
- };
46878
- if (!output.json) {
46879
- writeHumanOutput(`
46977
+ const { basename: basename8, dirname: dirname20 } = await import("node:path");
46978
+ const dynamicIntents = [];
46979
+ for (let pkgIdx = 0; pkgIdx < allResolutions.length; pkgIdx++) {
46980
+ const resolution = allResolutions[pkgIdx];
46981
+ const pkgTasks = filterTasksByHook2(resolution.manifest.tasks ?? [], "before:create");
46982
+ if (pkgTasks.length > 0) {
46983
+ const templateDir = service.getPackageRoot(resolution) ?? service.projectRoot;
46984
+ const stagingDir = stagingDirMap.get(resolution.manifest.id);
46985
+ const taskContext = {
46986
+ projectName: basename8(service.projectRoot),
46987
+ projectDir: service.projectRoot,
46988
+ projectParentDir: dirname20(service.projectRoot),
46989
+ templateDir,
46990
+ stagingDir,
46991
+ inputs: { ...inputValues, ...packageValues[resolution.manifest.id] ?? {} },
46992
+ target: projectTargets[0]?.id,
46993
+ targets: projectTargets.map((t2) => t2.id),
46994
+ operation: "create",
46995
+ version: resolution.manifest.version
46996
+ };
46997
+ if (!output.json) {
46998
+ writeHumanOutput(`
46880
46999
  \u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
46881
47000
  `);
46882
- }
46883
- try {
46884
- await executeTasks2(pkgTasks, taskContext, {
46885
- onProgress: (msg) => {
46886
- if (!output.json) writeHumanOutput(`> ${msg}
47001
+ }
47002
+ try {
47003
+ await executeTasks2(pkgTasks, taskContext, {
47004
+ onProgress: (msg) => {
47005
+ if (!output.json) writeHumanOutput(`> ${msg}
46887
47006
  `);
46888
- },
46889
- stdio: output.json ? "ignore" : "inherit"
46890
- });
46891
- } catch (err) {
46892
- if (err instanceof Error) {
46893
- throw new CliError(err.message, ExitCode.ExecuteFailed, "TASK_EXECUTION_FAILED");
47007
+ },
47008
+ stdio: output.json ? "ignore" : "inherit"
47009
+ });
47010
+ } catch (err) {
47011
+ if (err instanceof Error) {
47012
+ throw new CliError(err.message, ExitCode.ExecuteFailed, "TASK_EXECUTION_FAILED");
47013
+ }
47014
+ throw err;
47015
+ }
47016
+ if (stagingDir) {
47017
+ const scanRes = await scanStagingDirectory({
47018
+ stagingDir,
47019
+ packageId: resolution.manifest.id,
47020
+ ownerKind: "template"
47021
+ });
47022
+ dynamicIntents.push(...scanRes.intents);
46894
47023
  }
46895
- throw err;
46896
47024
  }
46897
47025
  }
46898
- }
46899
- const executor = service.getExecutor();
46900
- const executeStartedAt = Date.now();
46901
- if (!output.json) writeHumanOutput(t("create.writingResources", intents.length));
46902
- const { journal, result: executeResult } = await withJournalTransaction(service, async (journal2) => {
46903
- await prepareJournalRecovery(journal2, service.projectRoot, intents, ["aicoding-lock.yaml"]);
46904
- return executor.execute(
46905
- planResult.plan,
46906
- intents,
46907
- {
46908
- projectRoot: service.projectRoot,
46909
- dryRun: false,
46910
- deferCommit: true
47026
+ let intents = staticIntents;
47027
+ if (hasBeforeCreate && dynamicIntents.length > 0) {
47028
+ const mergedIntents = deduplicateIntents([...staticIntents, ...dynamicIntents]);
47029
+ planResult = materializePlan(planResult.plan, mergedIntents);
47030
+ if (planResult.conflicts.length > 0) {
47031
+ events.report("plan", "failure", 0, { errorCode: "PLAN_CONFLICT", planDigest: planResult.plan.planDigest });
47032
+ const conflictDiags = planResult.conflicts.flatMap((c) => c.diagnostics);
47033
+ writeDiagnostics(conflictDiags, output);
47034
+ if (output.json) {
47035
+ emitFailureJson(
47036
+ "create",
47037
+ "PLAN_CONFLICT",
47038
+ t("create.planConflict"),
47039
+ { conflicts: planResult.conflicts.map((c) => ({ type: c.type, resourceKey: c.resourceKey })) },
47040
+ [],
47041
+ conflictDiags,
47042
+ jsonEvents()
47043
+ );
47044
+ } else {
47045
+ process.stderr.write(`error: PLAN_CONFLICT: ${t("create.planConflict")}
47046
+ `);
47047
+ }
47048
+ return ExitCode.ConflictOrDrift;
46911
47049
  }
46912
- );
46913
- });
46914
- if (!executeResult.success) {
46915
- events.report("execute", "failure", Date.now() - executeStartedAt, { errorCode: "EXECUTE_FAILED", planDigest: planResult.plan.planDigest });
46916
- writeDiagnostics(executeResult.diagnostics, output);
46917
- if (output.json) {
46918
- emitFailureJson(
46919
- "create",
46920
- "EXECUTE_FAILED",
46921
- t("create.executionFailed"),
46922
- { planDigest: planResult.plan.planDigest, operationId: journal.operationId },
46923
- [],
46924
- executeResult.diagnostics,
46925
- jsonEvents()
47050
+ intents = mergedIntents;
47051
+ }
47052
+ const executor = service.getExecutor();
47053
+ const executeStartedAt = Date.now();
47054
+ if (!output.json) writeHumanOutput(t("create.writingResources", intents.length));
47055
+ const { journal, result: executeResult } = await withJournalTransaction(service, async (journal2) => {
47056
+ await prepareJournalRecovery(journal2, service.projectRoot, intents, ["aicoding-lock.yaml"]);
47057
+ return executor.execute(
47058
+ planResult.plan,
47059
+ intents,
47060
+ {
47061
+ projectRoot: service.projectRoot,
47062
+ dryRun: false,
47063
+ deferCommit: true
47064
+ }
46926
47065
  );
46927
- } else {
46928
- process.stderr.write(`error: EXECUTE_FAILED: ${t("create.executionFailedShort")}
47066
+ });
47067
+ if (!executeResult.success) {
47068
+ events.report("execute", "failure", Date.now() - executeStartedAt, { errorCode: "EXECUTE_FAILED", planDigest: planResult.plan.planDigest });
47069
+ writeDiagnostics(executeResult.diagnostics, output);
47070
+ if (output.json) {
47071
+ emitFailureJson(
47072
+ "create",
47073
+ "EXECUTE_FAILED",
47074
+ t("create.executionFailed"),
47075
+ { planDigest: planResult.plan.planDigest, operationId: journal.operationId },
47076
+ [],
47077
+ executeResult.diagnostics,
47078
+ jsonEvents()
47079
+ );
47080
+ } else {
47081
+ process.stderr.write(`error: EXECUTE_FAILED: ${t("create.executionFailedShort")}
46929
47082
  `);
46930
- }
46931
- return ExitCode.ExecuteFailed;
46932
- }
46933
- events.report("execute", "success", Date.now() - executeStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: intents.length } });
46934
- if (!output.json) writeHumanOutput(t("create.wroteResources", formatElapsed(executeStartedAt)));
46935
- const previousLock = await lockRepo.read().catch(() => void 0);
46936
- const recordStartedAt = Date.now();
46937
- await commitExecution(executor, executeResult, async (addRollback) => {
46938
- const userInstallationStartedAt = Date.now();
46939
- if (!output.json && userInstallationKeys.size > 0) writeHumanOutput(t("create.installingUserTools", userInstallationKeys.size));
46940
- const userLifecycle = await executeUserCapabilityInstallations(
46941
- allResolutions,
46942
- service,
46943
- inputValues,
46944
- [...options.allow, ...grantedPermissions],
46945
- userInstallationKeys,
46946
- journal,
46947
- output.json ? void 0 : (progress) => writeUserInstallationProgress(progress)
46948
- );
46949
- if (!output.json && userInstallationKeys.size > 0) writeHumanOutput(t("create.userToolsInstalled", formatElapsed(userInstallationStartedAt)));
46950
- addRollback(userLifecycle.rollback);
46951
- const lock = await buildLock("create", templateResolution, addonResolutions, projectTargets, planResult.plan, service.cliVersion, inputValues, service, intents, userInstallationKeys);
46952
- await lockRepo.write(lock);
46953
- addRollback(async () => previousLock ? lockRepo.write(previousLock) : unlink9(lockRepo.path).catch(() => void 0));
46954
- await userLifecycle.addReferences(lock);
46955
- await finishJournal(journal);
46956
- });
46957
- events.report("record", "success", Date.now() - recordStartedAt, { planDigest: planResult.plan.planDigest });
46958
- for (let pkgIdx = 0; pkgIdx < allResolutions.length; pkgIdx++) {
46959
- const resolution = allResolutions[pkgIdx];
46960
- const pkgTasks = filterTasksByHook2(resolution.manifest.tasks ?? [], "after:create");
46961
- if (pkgTasks.length > 0) {
46962
- const templateDir = service.getPackageRoot(resolution) ?? service.projectRoot;
46963
- const taskContext = {
46964
- projectName: basename8(service.projectRoot),
46965
- projectDir: service.projectRoot,
46966
- projectParentDir: dirname20(service.projectRoot),
46967
- templateDir,
46968
- inputs: { ...inputValues, ...packageValues[resolution.manifest.id] ?? {} },
46969
- target: projectTargets[0]?.id,
46970
- targets: projectTargets.map((t2) => t2.id),
46971
- operation: "create",
46972
- version: resolution.manifest.version
46973
- };
46974
- if (!output.json) {
46975
- writeHumanOutput(`
47083
+ }
47084
+ return ExitCode.ExecuteFailed;
47085
+ }
47086
+ events.report("execute", "success", Date.now() - executeStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: intents.length } });
47087
+ if (!output.json) writeHumanOutput(t("create.wroteResources", formatElapsed(executeStartedAt)));
47088
+ const previousLock = await lockRepo.read().catch(() => void 0);
47089
+ const recordStartedAt = Date.now();
47090
+ await commitExecution(executor, executeResult, async (addRollback) => {
47091
+ const userInstallationStartedAt = Date.now();
47092
+ if (!output.json && userInstallationKeys.size > 0) writeHumanOutput(t("create.installingUserTools", userInstallationKeys.size));
47093
+ const userLifecycle = await executeUserCapabilityInstallations(
47094
+ allResolutions,
47095
+ service,
47096
+ inputValues,
47097
+ [...options.allow, ...grantedPermissions],
47098
+ userInstallationKeys,
47099
+ journal,
47100
+ output.json ? void 0 : (progress) => writeUserInstallationProgress(progress)
47101
+ );
47102
+ if (!output.json && userInstallationKeys.size > 0) writeHumanOutput(t("create.userToolsInstalled", formatElapsed(userInstallationStartedAt)));
47103
+ addRollback(userLifecycle.rollback);
47104
+ const lock = await buildLock("create", templateResolution, addonResolutions, projectTargets, planResult.plan, service.cliVersion, inputValues, service, intents, userInstallationKeys);
47105
+ await lockRepo.write(lock);
47106
+ addRollback(async () => previousLock ? lockRepo.write(previousLock) : unlink9(lockRepo.path).catch(() => void 0));
47107
+ await userLifecycle.addReferences(lock);
47108
+ await finishJournal(journal);
47109
+ });
47110
+ events.report("record", "success", Date.now() - recordStartedAt, { planDigest: planResult.plan.planDigest });
47111
+ for (let pkgIdx = 0; pkgIdx < allResolutions.length; pkgIdx++) {
47112
+ const resolution = allResolutions[pkgIdx];
47113
+ const pkgTasks = filterTasksByHook2(resolution.manifest.tasks ?? [], "after:create");
47114
+ if (pkgTasks.length > 0) {
47115
+ const templateDir = service.getPackageRoot(resolution) ?? service.projectRoot;
47116
+ const taskContext = {
47117
+ projectName: basename8(service.projectRoot),
47118
+ projectDir: service.projectRoot,
47119
+ projectParentDir: dirname20(service.projectRoot),
47120
+ templateDir,
47121
+ inputs: { ...inputValues, ...packageValues[resolution.manifest.id] ?? {} },
47122
+ target: projectTargets[0]?.id,
47123
+ targets: projectTargets.map((t2) => t2.id),
47124
+ operation: "create",
47125
+ version: resolution.manifest.version
47126
+ };
47127
+ if (!output.json) {
47128
+ writeHumanOutput(`
46976
47129
  \u6B63\u5728\u6267\u884C\u540E\u7F6E\u521D\u59CB\u5316\u4EFB\u52A1 (after:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):
46977
47130
  `);
46978
- }
46979
- try {
46980
- await executeTasks2(pkgTasks, taskContext, {
46981
- onProgress: (msg) => {
46982
- if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
47131
+ }
47132
+ try {
47133
+ await executeTasks2(pkgTasks, taskContext, {
47134
+ onProgress: (msg) => {
47135
+ if (!output.json) writeHumanOutput(`> [${resolution.manifest.id}] ${msg}
46983
47136
  `);
46984
- },
46985
- stdio: output.json ? "ignore" : "inherit"
46986
- });
46987
- } catch (err) {
46988
- if (err instanceof Error) {
46989
- throw new CliError(err.message, ExitCode.ExecuteFailed, "TASK_EXECUTION_FAILED");
47137
+ },
47138
+ stdio: output.json ? "ignore" : "inherit"
47139
+ });
47140
+ } catch (err) {
47141
+ if (err instanceof Error) {
47142
+ throw new CliError(err.message, ExitCode.ExecuteFailed, "TASK_EXECUTION_FAILED");
47143
+ }
47144
+ throw err;
46990
47145
  }
46991
- throw err;
46992
47146
  }
46993
47147
  }
47148
+ const summary = summarizePlan(planResult.plan);
47149
+ if (output.json) {
47150
+ emitSuccessJson("create", { dryRun: false, ...summary, lockPath: lockRepo.path, operationId: journal.operationId }, [], [], jsonEvents());
47151
+ } else {
47152
+ printPlanSummary(summary);
47153
+ writeHumanOutput(t("create.createdProject", service.projectRoot) + "\n");
47154
+ writeHumanOutput(t("create.lockFile", lockRepo.path) + "\n");
47155
+ }
47156
+ return ExitCode.Success;
47157
+ } finally {
47158
+ await stagingManager.cleanup().catch(() => {
47159
+ });
46994
47160
  }
46995
- const summary = summarizePlan(planResult.plan);
46996
- if (output.json) {
46997
- emitSuccessJson("create", { dryRun: false, ...summary, lockPath: lockRepo.path, operationId: journal.operationId }, [], [], jsonEvents());
46998
- } else {
46999
- printPlanSummary(summary);
47000
- writeHumanOutput(t("create.createdProject", service.projectRoot) + "\n");
47001
- writeHumanOutput(t("create.lockFile", lockRepo.path) + "\n");
47002
- }
47003
- return ExitCode.Success;
47004
47161
  });
47005
47162
  }
47006
47163
  function formatElapsed(startedAt) {
@@ -47052,7 +47209,6 @@ var init_create = __esm({
47052
47209
  init_src2();
47053
47210
  init_resolve_helper();
47054
47211
  init_journal_helper();
47055
- init_src2();
47056
47212
  init_shared_options();
47057
47213
  init_cli_output();
47058
47214
  init_service_locator();
@@ -47984,8 +48140,8 @@ var init_config = __esm({
47984
48140
 
47985
48141
  // packages/cli/src/commands/remove.ts
47986
48142
  import { randomUUID as randomUUID9 } from "node:crypto";
47987
- import { unlink as unlink11, readFile as readFile30 } from "node:fs/promises";
47988
- import { basename as basename6, dirname as dirname18, join as join22, resolve as resolve23 } from "node:path";
48143
+ import { unlink as unlink11, readFile as readFile31 } from "node:fs/promises";
48144
+ import { basename as basename6, dirname as dirname18, join as join24, resolve as resolve23 } from "node:path";
47989
48145
  function createRemoveCommand(cliVersion) {
47990
48146
  const cmd = new Command("remove");
47991
48147
  cmd.description(t("remove.description")).option("--package <package-id>", t("remove.optionPackage")).action(async (opts) => {
@@ -48162,7 +48318,7 @@ async function executeRemove(packageId, options, cliVersion, events) {
48162
48318
  templateDir = service.projectRoot;
48163
48319
  }
48164
48320
  try {
48165
- const manifestContent = await readFile30(join22(templateDir, "manifest.yaml"), "utf-8");
48321
+ const manifestContent = await readFile31(join24(templateDir, "manifest.yaml"), "utf-8");
48166
48322
  const parsed = parseManifest(manifestContent);
48167
48323
  if (parsed.manifest) {
48168
48324
  packageManifests.push({
@@ -48735,7 +48891,7 @@ var init_inspect = __esm({
48735
48891
  // packages/cli/src/commands/doctor.ts
48736
48892
  import { execFile as execFile6 } from "node:child_process";
48737
48893
  import { createHash as createHash16 } from "node:crypto";
48738
- import { access as access11, readFile as readFile31 } from "node:fs/promises";
48894
+ import { access as access11, readFile as readFile32 } from "node:fs/promises";
48739
48895
  import { resolve as resolve25 } from "node:path";
48740
48896
  import { promisify as promisify7 } from "node:util";
48741
48897
  function createDoctorCommand(cliVersion) {
@@ -48809,7 +48965,7 @@ async function checkSecretReferences(findings, projectRoot, lock) {
48809
48965
  const sourcePath = pkg.source.path ?? ".";
48810
48966
  const manifestPath = resolve25(projectRoot, sourcePath, "manifest.yaml");
48811
48967
  try {
48812
- const manifestContent = await readFile31(manifestPath, "utf-8");
48968
+ const manifestContent = await readFile32(manifestPath, "utf-8");
48813
48969
  const manifest = parseManifest(manifestContent).manifest;
48814
48970
  if (!manifest.capabilities) continue;
48815
48971
  for (const cap of manifest.capabilities) {
@@ -49191,7 +49347,7 @@ async function executeDoctor(projectRoot, repair, drift, yes, online, offline, c
49191
49347
  });
49192
49348
  }
49193
49349
  try {
49194
- const stateLock = JSON.parse(await readFile31(`${lockRepo.path}.lock`, "utf8"));
49350
+ const stateLock = JSON.parse(await readFile32(`${lockRepo.path}.lock`, "utf8"));
49195
49351
  findings.push({ severity: "warning", code: "DOCTOR_TRANSACTION_LOCK", message: `\u53D1\u73B0\u672A\u91CA\u653E\u7684\u72B6\u6001\u9501 (pid=${String(stateLock.pid ?? "unknown")})`, category: "transaction", path: `${lockRepo.path}.lock`, fix: "\u786E\u8BA4\u5BF9\u5E94\u8FDB\u7A0B\u5DF2\u9000\u51FA\u540E\u518D\u6B21\u5199\u5165\uFF0C\u7CFB\u7EDF\u4F1A\u6E05\u7406\u5931\u6548\u9501" });
49196
49352
  } catch (error) {
49197
49353
  if (error.code !== "ENOENT") findings.push({ severity: "warning", code: "DOCTOR_TRANSACTION_LOCK_INVALID", message: "\u72B6\u6001\u9501\u6587\u4EF6\u65E0\u6CD5\u89E3\u6790", category: "transaction" });
@@ -49634,8 +49790,8 @@ var init_upgrade = __esm({
49634
49790
 
49635
49791
  // packages/cli/src/commands/cache.ts
49636
49792
  import { homedir as homedir3 } from "node:os";
49637
- import { join as join23, resolve as resolve26 } from "node:path";
49638
- import { rm as rm7, stat as stat7 } from "node:fs/promises";
49793
+ import { join as join25, resolve as resolve26 } from "node:path";
49794
+ import { rm as rm7, stat as stat8 } from "node:fs/promises";
49639
49795
  function createCacheCommand(cliVersion) {
49640
49796
  const cmd = new Command("cache");
49641
49797
  cmd.description(t("cache.description"));
@@ -49676,7 +49832,7 @@ function createCacheCommand(cliVersion) {
49676
49832
  return cmd;
49677
49833
  }
49678
49834
  function getUserDataDir() {
49679
- return process.env["MANO_USER_DATA"] ?? process.env["AICODING_USER_DATA"] ?? join23(homedir3(), ".mano-coding");
49835
+ return process.env["MANO_USER_DATA"] ?? process.env["AICODING_USER_DATA"] ?? join25(homedir3(), ".mano-coding");
49680
49836
  }
49681
49837
  function parsePositiveInt(value, name) {
49682
49838
  if (value === void 0) return void 0;
@@ -49821,7 +49977,7 @@ async function executeGc(opts, cliVersion) {
49821
49977
  continue;
49822
49978
  }
49823
49979
  try {
49824
- const stats = await stat7(rootPath);
49980
+ const stats = await stat8(rootPath);
49825
49981
  if (!stats.isDirectory()) {
49826
49982
  failedRoots.push(`${rootPath} (${t("cache.notDirectory")})`);
49827
49983
  continue;
@@ -49878,8 +50034,8 @@ async function executeClean(opts, cliVersion) {
49878
50034
  throw new CliError(t("cache.cleanRequiresYes"), ExitCode.NeedsInputOrDenied, "NEEDS_CONFIRMATION");
49879
50035
  }
49880
50036
  if (cleanRegistry && !dryRun) await updateCache.clear();
49881
- if (cleanAudit && !dryRun) await rm7(join23(userDataDir, "audit"), { recursive: true, force: true });
49882
- if (!dryRun) await rm7(join23(userDataDir, "cache"), { recursive: true, force: true });
50037
+ if (cleanAudit && !dryRun) await rm7(join25(userDataDir, "audit"), { recursive: true, force: true });
50038
+ if (!dryRun) await rm7(join25(userDataDir, "cache"), { recursive: true, force: true });
49883
50039
  if (json) {
49884
50040
  emitSuccessJson("cache clean", { dryRun, cleanedLeases: 0, clearedUpdateCache: cleanRegistry, clearedAudit: cleanAudit, message: t("cache.noInstallationsClean") });
49885
50041
  } else {
@@ -49894,8 +50050,8 @@ async function executeClean(opts, cliVersion) {
49894
50050
  throw new CliError(t("cache.cleanRequiresYes"), ExitCode.NeedsInputOrDenied, "NEEDS_CONFIRMATION");
49895
50051
  }
49896
50052
  if (cleanRegistry && !dryRun) await updateCache.clear();
49897
- if (cleanAudit && !dryRun) await rm7(join23(userDataDir, "audit"), { recursive: true, force: true });
49898
- if (!dryRun) await rm7(join23(userDataDir, "cache"), { recursive: true, force: true });
50053
+ if (cleanAudit && !dryRun) await rm7(join25(userDataDir, "audit"), { recursive: true, force: true });
50054
+ if (!dryRun) await rm7(join25(userDataDir, "cache"), { recursive: true, force: true });
49899
50055
  if (json) {
49900
50056
  emitSuccessJson("cache clean", { dryRun, cleanedLeases: 0, clearedUpdateCache: cleanRegistry, clearedAudit: cleanAudit, message: t("cache.noInstallationsClean") });
49901
50057
  } else {
@@ -49940,8 +50096,8 @@ async function executeClean(opts, cliVersion) {
49940
50096
  totalCleaned += cleaned;
49941
50097
  }
49942
50098
  if (cleanRegistry && !dryRun) await updateCache.clear();
49943
- if (cleanAudit && !dryRun) await rm7(join23(userDataDir, "audit"), { recursive: true, force: true });
49944
- if (!dryRun) await rm7(join23(userDataDir, "cache"), { recursive: true, force: true });
50099
+ if (cleanAudit && !dryRun) await rm7(join25(userDataDir, "audit"), { recursive: true, force: true });
50100
+ if (!dryRun) await rm7(join25(userDataDir, "cache"), { recursive: true, force: true });
49945
50101
  if (json) {
49946
50102
  emitSuccessJson("cache clean", { dryRun: false, cleanedLeases: totalCleaned, clearedUpdateCache: cleanRegistry, clearedAudit: cleanAudit });
49947
50103
  } else {
@@ -49963,7 +50119,7 @@ var init_cache = __esm({
49963
50119
  // packages/cli/src/commands/launch.ts
49964
50120
  import { spawn as spawn2 } from "node:child_process";
49965
50121
  import { homedir as homedir4 } from "node:os";
49966
- import { join as join24 } from "node:path";
50122
+ import { join as join26 } from "node:path";
49967
50123
  function createLaunchCommand() {
49968
50124
  const cmd = new Command("_launch");
49969
50125
  cmd.description(t("launch.description")).option("--kind <kind>", t("launch.optionKind")).option("--package <package-id>", t("launch.optionPackage")).option("--id <id>", t("launch.optionId")).option("--version <version>", t("launch.optionVersion")).option("--command <name>", t("launch.optionCommand")).allowUnknownOption(true).allowExcessArguments(true).action(async (_opts, command) => {
@@ -49996,7 +50152,7 @@ function createLaunchCommand() {
49996
50152
  return cmd;
49997
50153
  }
49998
50154
  function getUserDataDir2() {
49999
- return process.env["AICODING_USER_DATA"] ?? join24(homedir4(), ".aicoding");
50155
+ return process.env["AICODING_USER_DATA"] ?? join26(homedir4(), ".aicoding");
50000
50156
  }
50001
50157
  async function executeLaunch(launcherArgs) {
50002
50158
  const userDataDir = getUserDataDir2();
@@ -50047,9 +50203,9 @@ var init_launch = __esm({
50047
50203
 
50048
50204
  // packages/cli/src/commands/self-upgrade.ts
50049
50205
  import { spawn as spawn3 } from "node:child_process";
50050
- import { readFile as readFile32, realpath as realpath2 } from "node:fs/promises";
50206
+ import { readFile as readFile33, realpath as realpath2 } from "node:fs/promises";
50051
50207
  import { homedir as homedir5 } from "node:os";
50052
- import { extname, join as join25, resolve as resolve27 } from "node:path";
50208
+ import { extname, join as join27, resolve as resolve27 } from "node:path";
50053
50209
  import { createInterface as createInterface2 } from "node:readline/promises";
50054
50210
  import { stdin, stderr } from "node:process";
50055
50211
  function createSelfUpgradeCommand(cliVersion) {
@@ -50111,7 +50267,7 @@ async function executeSelfUpgrade(options, cliVersion) {
50111
50267
  });
50112
50268
  await auditLog.prune().catch(() => void 0);
50113
50269
  try {
50114
- const result = await withStateLock(join25(userDataDir, "cli-update"), async () => {
50270
+ const result = await withStateLock(join27(userDataDir, "cli-update"), async () => {
50115
50271
  const target = await resolveTarget(options, cacheRepository, registry);
50116
50272
  ensureTargetAllowed(target.version, installation.currentVersion, options.allowDowngrade);
50117
50273
  if (!isCliVersionCompatible(process.version, target.enginesNode)) {
@@ -50163,7 +50319,7 @@ function validateOptions(options) {
50163
50319
  }
50164
50320
  }
50165
50321
  function getUserDataDir3() {
50166
- return process.env["AICODING_USER_DATA"] ?? join25(homedir5(), ".aicoding");
50322
+ return process.env["AICODING_USER_DATA"] ?? join27(homedir5(), ".aicoding");
50167
50323
  }
50168
50324
  function getRegistryUrl() {
50169
50325
  const raw = process.env["AICODING_NPM_REGISTRY"] || DEFAULT_NPM_REGISTRY;
@@ -50276,13 +50432,13 @@ async function detectGlobalCliInstallation(cliPath = process.argv[1], runner = r
50276
50432
  }
50277
50433
  async function isWindowsCmdShimFor(shimPath, expectedBin) {
50278
50434
  if (process.platform !== "win32" || extname(shimPath).toLowerCase() !== ".cmd") return false;
50279
- const shim = await readFile32(shimPath, "utf8").catch(() => void 0);
50435
+ const shim = await readFile33(shimPath, "utf8").catch(() => void 0);
50280
50436
  if (!shim) return false;
50281
50437
  return shim.replaceAll("/", "\\").toLowerCase().includes(expectedBin.replaceAll("/", "\\").toLowerCase());
50282
50438
  }
50283
50439
  async function readPackageJson(root) {
50284
50440
  try {
50285
- const value = JSON.parse(await readFile32(join25(root, "package.json"), "utf8"));
50441
+ const value = JSON.parse(await readFile33(join27(root, "package.json"), "utf8"));
50286
50442
  if (!value || typeof value !== "object") return void 0;
50287
50443
  const item = value;
50288
50444
  return typeof item["name"] === "string" && typeof item["version"] === "string" ? { name: item["name"], version: item["version"], bin: item["bin"] } : void 0;
@@ -50294,17 +50450,41 @@ async function verifyCliVersion(binPath, expected) {
50294
50450
  const result = await runCommand(process.execPath, [binPath, "--version"]).catch(() => void 0);
50295
50451
  return result?.exitCode === 0 && result.stdout.trim() === expected;
50296
50452
  }
50297
- async function fetchCliMetadata(registry, request = fetch) {
50298
- const controller = new AbortController();
50299
- const timer = setTimeout(() => controller.abort(), 3e3);
50300
- timer.unref?.();
50301
- try {
50302
- const response = await request(`${registry}/${encodeURIComponent(CLI_PACKAGE_NAME)}`, { signal: controller.signal, redirect: "error" });
50303
- if (!response.ok) throw new Error(`Registry returned HTTP ${response.status}`);
50304
- return await response.json();
50305
- } finally {
50306
- clearTimeout(timer);
50453
+ async function fetchCliMetadata(registry, request = fetch, options) {
50454
+ const envTimeout = process.env["AICODING_FETCH_TIMEOUT"] ? Number.parseInt(process.env["AICODING_FETCH_TIMEOUT"], 10) : void 0;
50455
+ const timeoutMs = options?.timeoutMs ?? (Number.isFinite(envTimeout) && (envTimeout ?? 0) > 0 ? envTimeout : 15e3);
50456
+ const maxRetries = options?.retries ?? 1;
50457
+ let lastError;
50458
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
50459
+ const controller = new AbortController();
50460
+ let timedOut = false;
50461
+ const timer = setTimeout(() => {
50462
+ timedOut = true;
50463
+ controller.abort();
50464
+ }, timeoutMs);
50465
+ timer.unref?.();
50466
+ try {
50467
+ const response = await request(`${registry}/${encodeURIComponent(CLI_PACKAGE_NAME)}`, {
50468
+ signal: controller.signal,
50469
+ redirect: "error"
50470
+ });
50471
+ if (!response.ok) throw new Error(`Registry returned HTTP ${response.status}`);
50472
+ return await response.json();
50473
+ } catch (error) {
50474
+ const isAbort = timedOut || error instanceof Error && (error.name === "AbortError" || error.message.includes("aborted"));
50475
+ if (isAbort) {
50476
+ lastError = new Error(t("selfUpgrade.fetchMetadataTimeout", Math.round(timeoutMs / 1e3)));
50477
+ } else {
50478
+ lastError = error;
50479
+ }
50480
+ if (attempt < maxRetries) {
50481
+ await new Promise((resolve28) => setTimeout(resolve28, 200));
50482
+ }
50483
+ } finally {
50484
+ clearTimeout(timer);
50485
+ }
50307
50486
  }
50487
+ throw lastError;
50308
50488
  }
50309
50489
  async function runCommand(command, args) {
50310
50490
  const useCmd = process.platform === "win32" && (command === "pnpm" || command === "npm");
@@ -50347,11 +50527,11 @@ var init_self_upgrade = __esm({
50347
50527
 
50348
50528
  // packages/cli/src/commands/update-notice.ts
50349
50529
  import { homedir as homedir6 } from "node:os";
50350
- import { join as join26 } from "node:path";
50530
+ import { join as join28 } from "node:path";
50351
50531
  async function getCachedUpdateNotice(argv, currentVersion) {
50352
50532
  const json = argv.includes("--json");
50353
50533
  const disabled = argv.includes("--offline") || argv[2] === "self-upgrade" || Boolean(process.env["AICODING_NO_UPDATE_CHECK"]) || Boolean(process.env["CI"]);
50354
- const repository = new CliUpdateCacheRepository(process.env["AICODING_USER_DATA"] ?? join26(homedir6(), ".aicoding"));
50534
+ const repository = new CliUpdateCacheRepository(process.env["AICODING_USER_DATA"] ?? join28(homedir6(), ".aicoding"));
50355
50535
  if (disabled || !json && !process.stdout.isTTY) return { json, markNotified: async () => void 0 };
50356
50536
  const cache = await repository.read();
50357
50537
  const notifiedAt = cache?.lastNotifiedAt ? Date.parse(cache.lastNotifiedAt) : Number.NaN;
@@ -50383,7 +50563,7 @@ import { createRequire as createRequire2 } from "node:module";
50383
50563
  import { readFileSync as readFileSync4 } from "node:fs";
50384
50564
  import { fileURLToPath as fileURLToPath5 } from "node:url";
50385
50565
  function resolveVersion() {
50386
- if (true) return "0.1.30";
50566
+ if (true) return "0.1.32";
50387
50567
  const candidates = [
50388
50568
  new URL("../package.json", import.meta.url),
50389
50569
  new URL("../../package.json", import.meta.url),