mano-coding 0.1.33 → 0.1.35

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 +508 -272
  2. package/package.json +1 -1
package/dist/bin.js CHANGED
@@ -3404,17 +3404,19 @@ var init_zh = __esm({
3404
3404
  "version.description": "\u663E\u793A CLI \u7248\u672C",
3405
3405
  // create.ts
3406
3406
  "create.description": "\u5411\u6307\u5B9A\u76EE\u5F55\u521B\u5EFA\u5DE5\u7A0B\u5E76\u5B89\u88C5 AI Coding \u8D44\u4EA7",
3407
- "create.argPackageSpec": "\u6269\u5C55\u5305\u89C4\u683C\u6216\u9879\u76EE\u76EE\u5F55",
3407
+ "create.argTemplateSpec": "\u6A21\u677F\u89C4\u683C\uFF08\u672A\u6307\u5B9A\u65F6\u5728\u4EA4\u4E92\u7EC8\u7AEF\u4E2D\u9009\u62E9\uFF09",
3408
3408
  "create.argDirectory": "\u9879\u76EE\u76EE\u5F55\uFF08\u9ED8\u8BA4\uFF1A\u5F53\u524D\u76EE\u5F55\uFF09",
3409
- "create.optionPackage": "\u6269\u5C55\u5305\u89C4\u683C\uFF08\u53EF\u91CD\u590D\uFF0C\u6240\u6709\u5305\u6309\u540C\u540D\u751F\u547D\u5468\u671F\u4E32\u884C\u6267\u884C\uFF09",
3410
- "create.optionTemplate": "\u6269\u5C55\u5305\u89C4\u683C\uFF08\u5411\u540E\u517C\u5BB9\u522B\u540D\uFF0C\u5EFA\u8BAE\u4F7F\u7528 --package\uFF09",
3411
- "create.optionAddon": "\u6269\u5C55\u5305\u89C4\u683C\uFF08\u5411\u540E\u517C\u5BB9\u522B\u540D\uFF0C\u5EFA\u8BAE\u4F7F\u7528 --package\uFF09",
3412
- "create.templateRequired": "\u975E\u4EA4\u4E92\u73AF\u5883\u5FC5\u987B\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B\u81F3\u5C11\u4E00\u4E2A\u6269\u5C55\u5305\u89C4\u683C",
3413
- "create.registryIndexUnsupported": "\u5F53\u524D Registry \u5BA2\u6237\u7AEF\u4E0D\u652F\u6301\u5305\u7D22\u5F15",
3414
- "create.chooseTemplate": "\u9009\u62E9\u8981\u5B89\u88C5\u7684\u6269\u5C55\u5305",
3415
- "create.templateSelectionCancelled": "\u6269\u5C55\u5305\u9009\u62E9\u5DF2\u53D6\u6D88",
3416
- "create.packageKindMismatch": "\u5305 {0} \u7684\u5185\u5BB9\u4E0D\u7B26\u5408 create \u547D\u4EE4\u8981\u6C42",
3417
- "create.addonKindMismatch": "\u5305 {0} \u7684\u5185\u5BB9\u4E0D\u7B26\u5408\u8981\u6C42",
3409
+ "create.optionTemplate": "\u6A21\u677F\u89C4\u683C\uFF08\u53EF\u91CD\u590D\uFF0C\u652F\u6301\u4E00\u6B21\u6027\u6307\u5B9A\u591A\u4E2A\u6A21\u677F\uFF09",
3410
+ "create.templateRequired": "\u975E\u4EA4\u4E92\u73AF\u5883\u5FC5\u987B\u901A\u8FC7\u53C2\u6570\u63D0\u4F9B\u81F3\u5C11\u4E00\u4E2A\u6A21\u677F\u89C4\u683C",
3411
+ "create.registryIndexUnsupported": "\u5F53\u524D Registry \u5BA2\u6237\u7AEF\u4E0D\u652F\u6301\u6A21\u677F\u7D22\u5F15",
3412
+ "create.chooseTemplate": "\u9009\u62E9\u8981\u5B89\u88C5\u7684\u6A21\u677F",
3413
+ "create.templateSelectionCancelled": "\u6A21\u677F\u9009\u62E9\u5DF2\u53D6\u6D88",
3414
+ "create.templateKindMismatch": "\u6A21\u677F {0} \u7684\u5185\u5BB9\u4E0D\u7B26\u5408 create \u547D\u4EE4\u8981\u6C42",
3415
+ "create.filterUnsupported": "create \u547D\u4EE4\u4E0D\u652F\u6301 --only / --skip \u8D44\u4EA7\u8FC7\u6EE4\uFF0C\u4EE5\u4FDD\u8BC1\u6A21\u677F\u5B8C\u6574\u4EA4\u4ED8\u3002\u5982\u9700\u5B9A\u5236\u53D7\u7BA1\u8D44\u4EA7\u8BF7\u4F7F\u7528 apply \u547D\u4EE4\u3002",
3416
+ "create.templateAlreadyInstalled": "\u6A21\u677F '{0}' \u5DF2\u7ECF\u5B89\u88C5\u5728\u5F53\u524D\u5DE5\u7A0B\u4E2D\u3002\u4E0D\u80FD\u901A\u8FC7 create \u91CD\u65B0\u5B89\u88C5\u3002\u5982\u9700\u66F4\u65B0\u914D\u7F6E\u6216\u540C\u6B65\u8D44\u4EA7\u8BF7\u4F7F\u7528 'apply'\u3001'sync' \u6216 'upgrade' \u547D\u4EE4\u3002",
3417
+ "create.missingTaskInputs": "\u6A21\u677F '{0}' \u7F3A\u5C11\u521D\u59CB\u5316\u53C2\u6570: {1}\uFF0C\u8BF7\u4F7F\u7528\uFF1A\n{2}",
3418
+ "create.promptTaskInput": "[{0}] \u8BF7\u8F93\u5165\u521D\u59CB\u5316\u53C2\u6570 '{1}':",
3419
+ "create.taskValidationFailed": "\u53C2\u6570\u6821\u9A8C\u5931\u8D25",
3418
3420
  "create.missingInputs": "\u7F3A\u5C11\u5FC5\u586B\u8F93\u5165\uFF1A{0}",
3419
3421
  "create.missingInputsHint": "\u7F3A\u5C11\u5FC5\u586B\u8F93\u5165\uFF1A{0}\u3002\u8BF7\u901A\u8FC7 --input <name>=<value> \u63D0\u4F9B",
3420
3422
  "create.chooseTargets": "\u9009\u62E9\u8981\u521D\u59CB\u5316\u7684 IDE \u76EE\u6807",
@@ -3425,7 +3427,7 @@ var init_zh = __esm({
3425
3427
  "create.userDeclined": "\u7528\u6237\u62D2\u7EDD\u4E86 Plan \u786E\u8BA4",
3426
3428
  "create.executionFailed": "\u6267\u884C\u5931\u8D25\uFF1B\u5DF2\u5C1D\u8BD5\u56DE\u6EDA",
3427
3429
  "create.executionFailedShort": "\u6267\u884C\u5931\u8D25",
3428
- "create.projectExtensionFailed": "\u5DE5\u7A0B\u6269\u5C55 create \u5931\u8D25\uFF1A{0}",
3430
+ "create.projectExtensionFailed": "\u5DE5\u7A0B\u6A21\u677F create \u5931\u8D25\uFF1A{0}",
3429
3431
  "create.createdProject": "\u9879\u76EE\u5DF2\u521B\u5EFA\u5728 {0}",
3430
3432
  "create.lockFile": "Lock \u6587\u4EF6\uFF1A{0}",
3431
3433
  "create.enterInput": "\u8F93\u5165 {0}",
@@ -3434,23 +3436,46 @@ var init_zh = __esm({
3434
3436
  "create.initializingWorkspace": "\u6B63\u5728\u521D\u59CB\u5316\u5DE5\u7A0B\u5DE5\u4F5C\u533A\u2026\n",
3435
3437
  "create.workspaceInitialized": "\u2713 \u5DE5\u7A0B\u5DE5\u4F5C\u533A\u521D\u59CB\u5316\u5B8C\u6210\uFF08{0}\uFF09\n",
3436
3438
  "create.installingUserTools": "\u6B63\u5728\u5B89\u88C5\u7528\u6237\u7EA7\u5DE5\u5177\uFF08{0} \u9879\uFF09\u2026\n",
3437
- "create.userToolsInstalled": "\u2713 \u7528\u6237\u7EA7\u5DE5\u5177\u5B89\u88C5\u5B8C\u6210\uFF08{0}\uFF09\n",
3439
+ "create.computingPlan": "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
3440
+ "create.planReady": "\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 {0} \u9879\u8D44\u6E90\u53D8\u66F4)",
3441
+ "create.planFailed": "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25",
3438
3442
  "create.installing": "\u6B63\u5728\u5B89\u88C5\uFF1A{0}\n",
3439
3443
  "create.installed": "\u2713 \u5DF2\u5B89\u88C5\uFF1A{0}\n",
3440
3444
  "create.reused": "\u2713 \u5DF2\u590D\u7528\uFF1A{0}\n",
3441
3445
  "create.skipped": "- \u65E0\u9700\u5B89\u88C5\uFF1A{0}\n",
3446
+ "common.seconds": "{0} \u79D2",
3447
+ // 模板通用解析文案
3448
+ "template.resolving": "\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6A21\u677F ({0})...",
3449
+ "template.resolved": "\u2714 \u6A21\u677F\u89E3\u6790\u5B8C\u6210: {0} (v{1})",
3450
+ "template.resolveFailed": "\u2716 \u6A21\u677F\u89E3\u6790\u5931\u8D25: {0}",
3451
+ // 任务通用执行文案
3452
+ "task.runningBeforeCreate": "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [{0}/{1}] ({2}):",
3453
+ "task.runningAfterCreate": "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u521B\u5EFA\u4EFB\u52A1 (after:create) [{0}/{1}] ({2}):",
3454
+ "task.runningBeforeApply": "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5E94\u7528\u4EFB\u52A1 (before:apply) [{0}/{1}] ({2}):",
3455
+ "task.runningAfterApply": "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5E94\u7528\u4EFB\u52A1 (after:apply) [{0}/{1}] ({2}):",
3456
+ "task.runningBeforeRemove": "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u79FB\u9664\u4EFB\u52A1 (before:remove) [{0}/{1}] ({2}):",
3457
+ "task.runningAfterRemove": "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u79FB\u9664\u4EFB\u52A1 (after:remove) [{0}/{1}] ({2}):",
3458
+ "task.runningBeforeSync": "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u540C\u6B65\u4EFB\u52A1 (before:sync) [{0}/{1}] ({2}):",
3459
+ "task.runningAfterSync": "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u540C\u6B65\u4EFB\u52A1 (after:sync) [{0}/{1}] ({2}):",
3442
3460
  // apply.ts
3443
3461
  "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\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",
3462
+ "apply.argTemplateSpec": "\u8981\u5E94\u7528\u7684\u6A21\u677F\u89C4\u683C\uFF08\u672A\u6307\u5B9A\u65F6\u5728\u4EA4\u4E92\u7EC8\u7AEF\u4E2D\u9009\u62E9\uFF09",
3463
+ "apply.optionTemplate": "\u8981\u5E94\u7528\u7684\u6A21\u677F\u89C4\u683C\uFF08\u53EF\u91CD\u590D\uFF0C\u6240\u6709\u6A21\u677F\u6309\u540C\u540D\u751F\u547D\u5468\u671F\u4E32\u884C\u6267\u884C\uFF09",
3464
+ "apply.templateRequired": "\u975E\u4EA4\u4E92\u73AF\u5883\u5FC5\u987B\u663E\u5F0F\u6307\u5B9A\u81F3\u5C11\u4E00\u4E2A\u6A21\u677F",
3465
+ "apply.chooseTemplate": "\u9009\u62E9\u8981\u5E94\u7528\u7684\u6A21\u677F",
3466
+ "apply.templateSelectionCancelled": "\u6A21\u677F\u9009\u62E9\u5DF2\u53D6\u6D88",
3467
+ "apply.chooseTargets": "\u9009\u62E9\u8981\u5E94\u7528\u7684 IDE \u76EE\u6807",
3468
+ "apply.targetSelectionCancelled": "\u76EE\u6807\u9009\u62E9\u5DF2\u53D6\u6D88",
3469
+ "apply.targetRequired": "\u7F3A\u5C11\u76EE\u6807 IDE \u53C2\u6570\uFF0C\u8BF7\u4F7F\u7528 --target <ide...>",
3470
+ "apply.noAvailableTemplates": "\u6CA1\u6709\u53EF\u4F9B\u5B89\u88C5\u7684\u65B0\u6A21\u677F\u6216\u5168\u90E8\u5019\u9009\u6A21\u677F\u5DF2\u5B89\u88C5",
3446
3471
  "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
3472
  "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
3473
  "apply.onlySkipExclusive": "--only \u4E0E --skip \u53C2\u6570\u4E92\u65A5\uFF0C\u4E0D\u80FD\u540C\u65F6\u4F7F\u7528",
3449
3474
  "apply.invalidAssetType": "\u65E0\u6548\u7684\u8D44\u4EA7\u7C7B\u578B '{0}'\uFF0C\u4EC5\u652F\u6301: skills, rules, subagents, mcp, agents-md",
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",
3475
+ "apply.emptyAfterFilter": "\u8FC7\u6EE4\u540E\u65E0\u53EF\u4EA4\u4ED8\u7684\u6838\u5FC3\u53D7\u7BA1\u8D44\u4EA7\u4E14\u6A21\u677F\u4E0D\u5305\u542B apply \u751F\u547D\u5468\u671F\u4EFB\u52A1",
3451
3476
  "apply.driftDetected": "\u53D7\u7BA1\u8D44\u6E90\u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD apply\uFF1B\u8BF7\u5148\u8FD0\u884C sync --drift restore \u6216 accept",
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 '\u6A21\u677F'",
3477
+ "apply.packageSpecRequired": "\u9879\u76EE\u65E0 lock \u6587\u4EF6\u65F6 apply \u9700\u8981\u6307\u5B9A\u6A21\u677F\u3002\u4F7F\u7528 --dry-run \u9884\u89C8\u3002",
3478
+ "apply.templateKindMismatch": "\u6A21\u677F {0} \u7684\u7C7B\u578B\u4E3A '{1}'\uFF0C\u671F\u671B 'template'",
3454
3479
  "apply.missingInputs": "\u7F3A\u5C11\u5FC5\u586B\u8F93\u5165\uFF1A{0}\u3002\u901A\u8FC7 --set \u63D0\u4F9B\u3002",
3455
3480
  "apply.planConflict": "Plan \u5B58\u5728\u51B2\u7A81",
3456
3481
  "apply.needsConfirmation": "\u6267\u884C Plan \u9700\u8981 --yes\u3002\u4F7F\u7528 --dry-run \u9884\u89C8\u3002",
@@ -3460,8 +3485,18 @@ var init_zh = __esm({
3460
3485
  "apply.projectExtensionFailed": "\u6A21\u677F {0} \u7684\u5DE5\u7A0B\u6269\u5C55 apply \u5931\u8D25\uFF1A{1}",
3461
3486
  "apply.applied": "\u5DF2\u5C06\u6A21\u677F\u5E94\u7528\u5230 {0}",
3462
3487
  "apply.lockFile": "Lock \u6587\u4EF6\uFF1A{0}",
3488
+ "apply.alreadyUpToDate": "\u5DF2\u5E94\u7528\uFF0C\u65E0\u53D8\u5316",
3489
+ "apply.computingPlan": "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
3490
+ "apply.planReady": "\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 {0} \u9879\u8D44\u6E90\u53D8\u66F4)",
3491
+ "apply.planFailed": "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25",
3492
+ "apply.resourceConflict": "\u8D44\u6E90 '{0}' \u4E0E\u5DF2\u6709\u6A21\u677F\u8D44\u6E90\u5B58\u5728\u51B2\u7A81",
3493
+ "apply.lockedConfigLoaded": "\u2714 \u5DF2\u52A0\u8F7D\u9501\u5B9A\u914D\u7F6E",
3494
+ "apply.skippedCreateTasks": "- \u5DF2\u8DF3\u8FC7 {0} \u4E2A create \u751F\u547D\u5468\u671F\u94A9\u5B50\u4EFB\u52A1\uFF08apply \u8BED\u4E49\u4E0D\u6267\u884C before:create / after:create \u94A9\u5B50\uFF09\n",
3495
+ "apply.templateUpdatedNeedsUpgrade": "\u6A21\u677F '{0}' \u7248\u672C\u76F8\u540C\u4F46\u5185\u5BB9\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u4F7F\u7528 upgrade \u547D\u4EE4\u8FDB\u884C\u66F4\u65B0",
3463
3496
  // sync.ts
3464
3497
  "sync.description": "\u4ECE lock \u6587\u4EF6\u6062\u590D\u9879\u76EE\u72B6\u6001\uFF08\u4E0D\u89E3\u6790\u7248\u672C\uFF09",
3498
+ "sync.optionTemplate": "\u4EC5\u540C\u6B65\u6307\u5B9A\u7684\u5DF2\u5B89\u88C5\u6A21\u677F",
3499
+ "sync.templateNotFound": "\u672A\u5728 Lock \u6587\u4EF6\u4E2D\u627E\u5230\u6A21\u677F '{0}'\u3002\u8BE5\u6A21\u677F\u672A\u5B89\u88C5\u6216\u65E0\u6CD5\u540C\u6B65\u3002",
3465
3500
  "sync.lockNotFound": "\u5728 {0} \u672A\u627E\u5230 lock \u6587\u4EF6\u3002\u8BF7\u5148\u4F7F\u7528 create \u6216 apply\u3002",
3466
3501
  "sync.acceptMissing": "sync --drift accept \u4E0D\u5141\u8BB8 missing \u8D44\u6E90\uFF1B\u8BF7\u5148\u6062\u590D\u6216\u4F7F\u7528 remove \u91CA\u653E\uFF1A{0}",
3467
3502
  "sync.driftDetected": "\u68C0\u6D4B\u5230 {0} \u9879\u8D44\u6E90\u6F02\u79FB\uFF1B\u4F7F\u7528 --drift restore \u6062\u590D\u6216 --drift accept \u63A5\u7EB3",
@@ -3475,35 +3510,41 @@ var init_zh = __esm({
3475
3510
  "sync.lockFile": "Lock \u6587\u4EF6\uFF1A{0}",
3476
3511
  "sync.locateDriftFailed": "\u65E0\u6CD5\u5B9A\u4F4D\u6F02\u79FB\u8D44\u6E90 {0}",
3477
3512
  // remove.ts
3478
- "remove.description": "\u4ECE\u9879\u76EE\u4E2D\u79FB\u9664\u5305\u6216\u5168\u90E8\u53D7\u7BA1\u5185\u5BB9",
3479
- "remove.optionPackage": "\u8981\u79FB\u9664\u7684\u5305 ID\uFF08\u5355\u4E2A\uFF09",
3480
- "remove.lockNotFound": "\u5728 {0} \u672A\u627E\u5230 lock \u6587\u4EF6\u3002\u65E0\u5185\u5BB9\u53EF\u79FB\u9664\u3002",
3481
- "remove.packageNotInLock": "\u5305 {0} \u4E0D\u5728\u9879\u76EE lock \u4E2D\u3002\u53EF\u7528\uFF1A{1}",
3513
+ "remove.description": "\u4ECE\u9879\u76EE\u4E2D\u79FB\u9664\u6307\u5B9A\u7684\u6A21\u677F\u6216\u5168\u90E8\u53D7\u7BA1\u5185\u5BB9",
3514
+ "remove.argTemplate": "\u8981\u79FB\u9664\u7684\u6A21\u677F ID\uFF08\u53EF\u9009\uFF0C\u672A\u6307\u5B9A\u65F6\u79FB\u9664\u5168\u90E8\uFF09",
3515
+ "remove.optionTemplate": "\u8981\u79FB\u9664\u7684\u6A21\u677F ID\uFF08\u5355\u4E2A\uFF09",
3516
+ "remove.chooseTemplate": "\u9009\u62E9\u8981\u79FB\u9664\u7684\u6A21\u677F",
3517
+ "remove.templateSelectionCancelled": "\u6A21\u677F\u79FB\u9664\u9009\u62E9\u5DF2\u53D6\u6D88",
3518
+ "remove.lockNotFound": "\u5728 {0} \u672A\u627E\u5230 lock \u6587\u4EF6\u3002\u65E0\u6A21\u677F\u53EF\u79FB\u9664\u3002",
3519
+ "remove.templateNotInLock": "\u6A21\u677F {0} \u4E0D\u5728\u9879\u76EE lock \u4E2D\u3002\u5F53\u524D\u53EF\u7528\u6A21\u677F\uFF1A{1}",
3520
+ "remove.bootstrapTemplateCannotBeRemoved": "\u6A21\u677F '{0}' \u662F\u9879\u76EE\u7684\u521D\u59CB\u5DE5\u7A0B\u6A21\u677F (bootstrap-only)\uFF0C\u4E0D\u5305\u542B\u53D7\u7BA1\u77E5\u8BC6\u8D44\u4EA7\uFF0C\u65E0\u6CD5\u88AB remove\u3002\u82E5\u9700\u5220\u9664\u6574\u4E2A\u9879\u76EE\uFF0C\u8BF7\u76F4\u63A5\u5220\u9664\u9879\u76EE\u76EE\u5F55\u3002",
3482
3521
  "remove.driftDetected": "\u68C0\u6D4B\u5230 {0} \u9879\u8D44\u6E90\u6F02\u79FB\uFF1B\u5982\u786E\u8BA4\u5220\u9664\u5DF2\u4FEE\u6539\u5185\u5BB9\uFF0C\u8BF7\u4F7F\u7528 --drift accept",
3483
3522
  "remove.needsConfirmation": "\u6267\u884C Remove \u9700\u8981 --yes\u3002\u4F7F\u7528 --dry-run \u9884\u89C8\u3002",
3484
3523
  "remove.userDeclined": "\u7528\u6237\u62D2\u7EDD\u4E86 Plan \u786E\u8BA4",
3485
3524
  "remove.executionFailed": "\u6267\u884C\u5931\u8D25\uFF1B\u5DF2\u5C1D\u8BD5\u56DE\u6EDA",
3486
3525
  "remove.executionFailedShort": "\u6267\u884C\u5931\u8D25",
3487
- "remove.removed": "\u5DF2\u4ECE {1} \u79FB\u9664 {0}",
3488
- "remove.allPackages": "\u6240\u6709\u5305",
3526
+ "remove.removed": "\u5DF2\u4ECE {1} \u79FB\u9664\u6A21\u677F {0}",
3527
+ "remove.allTemplates": "\u6240\u6709\u6A21\u677F",
3489
3528
  "remove.lockRemoved": "Lock \u6587\u4EF6\u5DF2\u79FB\u9664\u3002",
3490
3529
  "remove.lockUpdated": "Lock \u6587\u4EF6\u5DF2\u66F4\u65B0\u3002",
3491
3530
  "remove.userReferenceFailed": "\u79FB\u9664 {0}/{1}@{2} \u7684\u7528\u6237\u7EA7\u5F15\u7528\u5931\u8D25\uFF1A{3}",
3492
3531
  // upgrade.ts
3493
3532
  "upgrade.description": "\u5C06 Capability \u5347\u7EA7\u5230\u65B0\u7248\u672C\u5E76\u5207\u6362\u9879\u76EE\u5F15\u7528",
3494
3533
  "upgrade.optionProject": "\u9879\u76EE\u6839\u76EE\u5F55",
3495
- "upgrade.optionPackage": "Capability \u7684\u5305 ID",
3534
+ "upgrade.optionTemplate": "Capability \u6240\u5C5E\u7684\u6A21\u677F ID",
3496
3535
  "upgrade.optionCapability": "\u8981\u5347\u7EA7\u7684 Capability ID",
3497
3536
  "upgrade.optionVersion": "\u76EE\u6807\u5347\u7EA7\u7248\u672C",
3498
3537
  "upgrade.optionDryRun": "\u4EC5\u9884\u89C8\uFF0C\u4E0D\u6267\u884C",
3499
3538
  "upgrade.optionYes": "\u65E0\u9700\u786E\u8BA4\u5373\u6279\u51C6",
3500
3539
  "upgrade.optionAllow": "\u6388\u6743\u9AD8\u98CE\u9669\u64CD\u4F5C\uFF08\u53EF\u91CD\u590D\uFF09",
3501
- "upgrade.missingOptions": "upgrade \u9700\u8981 --package\u3001--capability \u548C --version",
3540
+ "upgrade.missingOptions": "upgrade \u9700\u8981 --template\u3001--capability \u548C --version",
3541
+ "upgrade.missingTemplate": "\u8BF7\u901A\u8FC7 --template <template-id> \u6307\u5B9A\u9700\u8981\u5347\u7EA7\u7684\u6A21\u677F\u3002",
3542
+ "upgrade.planSummary": "\u5347\u7EA7\u8BA1\u5212\uFF1A\n \u6A21\u677F\uFF1A{0}\n \u5F53\u524D\uFF1A{1}\n \u76EE\u6807\uFF1A{2}\n \u9879\u76EE\uFF1A{3}\n",
3502
3543
  "upgrade.lockNotFound": "\u5728 {0} \u672A\u627E\u5230 lock \u6587\u4EF6\u3002\u8BF7\u5148\u4F7F\u7528 create \u6216 apply\u3002",
3503
3544
  "upgrade.driftDetected": "\u53D7\u7BA1\u8D44\u6E90\u5DF2\u6F02\u79FB\uFF0C\u62D2\u7EDD\u5347\u7EA7",
3504
- "upgrade.packageNotInLock": "\u5728 lock \u6587\u4EF6\u7684 template \u4E2D\u672A\u627E\u5230\u5305 {0}",
3545
+ "upgrade.templateNotInLock": "\u5728 lock \u6587\u4EF6\u7684 template \u4E2D\u672A\u627E\u5230\u6A21\u677F {0}",
3505
3546
  "upgrade.alreadyAtVersion": "\u5DF2\u5904\u4E8E\u7248\u672C {0}\uFF0C\u65E0\u9700\u5347\u7EA7",
3506
- "upgrade.noDesiredTemplate": "\u5305 {0} \u6CA1\u6709 desired template \u6761\u76EE",
3547
+ "upgrade.noDesiredTemplate": "\u6A21\u677F {0} \u6CA1\u6709 desired template \u6761\u76EE",
3507
3548
  "upgrade.resolveFailed": "\u65E0\u6CD5\u89E3\u6790\u6A21\u677F {0}@{1}\uFF1A{2}",
3508
3549
  "upgrade.resolveInvalid": "\u65E0\u6CD5\u89E3\u6790\u6A21\u677F {0}@{1}",
3509
3550
  "upgrade.capabilityAbsent": "Capability {0}/{1} \u5728 {2} \u4E2D\u4E0D\u5B58\u5728",
@@ -3513,6 +3554,9 @@ var init_zh = __esm({
3513
3554
  "upgrade.upgraded": "\u5DF2\u5347\u7EA7 {0}/{1}\uFF1A{2} -> {3}",
3514
3555
  "upgrade.dryRunPlan": "CLI \u5347\u7EA7\u8BA1\u5212\uFF1A\n current: {0}\n target: {1}\n integrity: {2}\n manager: {3}\n bin: {4}\n",
3515
3556
  "upgrade.alreadyCurrent": "aicoding \u5DF2\u662F {0}\u3002",
3557
+ // 任务通用执行文案 (upgrade)
3558
+ "task.runningBeforeUpgrade": "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5347\u7EA7\u4EFB\u52A1 (before:upgrade) ({0}):",
3559
+ "task.runningAfterUpgrade": "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5347\u7EA7\u4EFB\u52A1 (after:upgrade) ({0}):",
3516
3560
  // self-upgrade.ts
3517
3561
  "selfUpgrade.description": "\u68C0\u67E5\u6216\u5347\u7EA7\u7531 npm/pnpm \u5B89\u88C5\u7684 mano-coding CLI",
3518
3562
  "selfUpgrade.optionCheck": "\u4EC5\u5237\u65B0\u7248\u672C\u4FE1\u606F",
@@ -3615,7 +3659,8 @@ var init_zh = __esm({
3615
3659
  // launch.ts
3616
3660
  "launch.description": "\u9690\u85CF\u542F\u52A8\u547D\u4EE4 - \u542F\u52A8\u7CBE\u786E\u5B89\u88C5\uFF08\u8BF7\u52FF\u76F4\u63A5\u4F7F\u7528\uFF09",
3617
3661
  "launch.optionKind": "\u6240\u6709\u8005\u7C7B\u578B\uFF08project|capability|plugin\uFF09",
3618
- "launch.optionPackage": "\u5305 ID",
3662
+ "launch.optionTemplate": "\u6A21\u677F ID",
3663
+ "launch.optionPackage": "\u6A21\u677F ID",
3619
3664
  "launch.optionId": "\u6240\u6709\u8005 ID",
3620
3665
  "launch.optionVersion": "\u7CBE\u786E\u7248\u672C",
3621
3666
  "launch.optionCommand": "\u547D\u4EE4\u540D\u79F0\uFF08\u53EA\u6709\u4E00\u4E2A\u547D\u4EE4\u65F6\u53EF\u9009\uFF09",
@@ -3644,17 +3689,37 @@ var init_zh = __esm({
3644
3689
  // extension commands
3645
3690
  "extension.create.description": "\u521D\u59CB\u5316\u6807\u51C6\u6269\u5C55/\u6A21\u677F\u5DE5\u7A0B",
3646
3691
  "extension.create.argDirectory": "\u76EE\u6807\u5DE5\u7A0B\u76EE\u5F55",
3647
- "extension.create.optionName": "\u6269\u5C55\u5305 ID (package-id)",
3648
- "extension.create.optionCategory": "\u6269\u5C55\u5206\u7C7B",
3649
- "extension.create.optionWithProject": "\u662F\u5426\u5305\u542B\u5DE5\u7A0B\u6A21\u677F",
3692
+ "extension.create.optionName": "\u6A21\u677F ID (template-id)",
3693
+ "extension.create.optionTemplateName": "\u6A21\u677F\u663E\u793A\u540D\u79F0 (name)",
3694
+ "extension.create.optionDescription": "\u6A21\u677F\u63CF\u8FF0",
3695
+ "extension.create.optionCategory": "\u6A21\u677F\u5206\u7C7B",
3696
+ "extension.create.optionWithProject": "\u662F\u5426\u5305\u542B\u9759\u6001\u5DE5\u7A0B\u811A\u624B\u67B6 (project/)",
3697
+ "extension.create.optionWithTasks": "\u662F\u5426\u751F\u6210\u521D\u59CB\u5316\u4EFB\u52A1\u793A\u4F8B",
3650
3698
  "extension.create.optionWithCapability": "\u5305\u542B\u7684\u80FD\u529B\u7279\u6027",
3651
3699
  "extension.create.optionWithPipeline": "\u662F\u5426\u751F\u6210 GitLab CI/CD \u81EA\u52A8\u540C\u6B65\u6D41\u6C34\u7EBF\u914D\u7F6E (.gitlab-ci.yml)",
3652
3700
  "extension.create.optionYes": "\u8DF3\u8FC7\u4EA4\u4E92\u786E\u8BA4\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u503C",
3653
3701
  "extension.create.directoryNotEmpty": "\u76EE\u6807\u76EE\u5F55\u5DF2\u5B58\u5728\u4E14\u975E\u7A7A\uFF1A{0}",
3654
- "extension.pipeline.description": "\u751F\u6210\u6216\u66F4\u65B0\u6269\u5C55\u5305\u7684 GitLab CI/CD \u81EA\u52A8\u540C\u6B65\u6D41\u6C34\u7EBF\u914D\u7F6E (.gitlab-ci.yml)",
3655
- "extension.pipeline.argDirectory": "\u6269\u5C55\u5305\u5DE5\u7A0B\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09",
3702
+ "extension.create.promptName": "\u8BF7\u8F93\u5165\u6A21\u677F ID (Template ID):",
3703
+ "extension.create.promptTemplateName": "\u8BF7\u8F93\u5165\u6A21\u677F\u540D\u79F0 (Name):",
3704
+ "extension.create.promptDescription": "\u8BF7\u8F93\u5165\u6A21\u677F\u7B80\u8981\u63CF\u8FF0 (Description):",
3705
+ "extension.create.promptWithTasks": "\u662F\u5426\u5305\u542B\u9879\u76EE\u811A\u624B\u67B6\u521D\u59CB\u5316\u4EFB\u52A1 (Tasks) \u793A\u4F8B\uFF1F",
3706
+ "extension.create.promptWithProject": "\u662F\u5426\u751F\u6210\u9759\u6001\u5DE5\u7A0B\u811A\u624B\u67B6\u76EE\u5F55 (project/)\uFF1F",
3707
+ "extension.create.promptWithPipeline": "\u662F\u5426\u751F\u6210 GitLab CI/CD \u81EA\u52A8\u540C\u6B65\u6D41\u6C34\u7EBF\u914D\u7F6E (.gitlab-ci.yml)\uFF1F",
3708
+ "extension.create.created": "\u6A21\u677F\u5DE5\u7A0B\u5DF2\u521B\u5EFA\u5728\uFF1A{0}",
3709
+ "extension.create.success": "\u2713 \u6210\u529F\u521D\u59CB\u5316\u6A21\u677F\u5DE5\u7A0B: {0}",
3710
+ "extension.create.generatedFiles": "\u5DF2\u751F\u6210\u6587\u4EF6\u6E05\u5355:",
3711
+ "extension.pipeline.description": "\u751F\u6210\u6216\u66F4\u65B0\u6A21\u677F\u5DE5\u7A0B\u7684 GitLab CI/CD \u81EA\u52A8\u540C\u6B65\u6D41\u6C34\u7EBF\u914D\u7F6E (.gitlab-ci.yml)",
3712
+ "extension.pipeline.argDirectory": "\u6A21\u677F\u5DE5\u7A0B\u76EE\u5F55\uFF08\u9ED8\u8BA4\u5F53\u524D\u76EE\u5F55\uFF09",
3656
3713
  "extension.pipeline.optionForce": "\u82E5\u5DF2\u5B58\u5728 .gitlab-ci.yml \u5219\u5F3A\u5236\u8986\u76D6",
3657
- "extension.pipeline.optionPackageId": "\u6269\u5C55\u5305 ID\uFF08\u9ED8\u8BA4\u4ECE manifest.yaml \u6216 package.json \u89E3\u6790\uFF09"
3714
+ "extension.pipeline.optionTemplateId": "\u6A21\u677F ID\uFF08\u9ED8\u8BA4\u4ECE manifest.yaml \u6216 package.json \u89E3\u6790\uFF09",
3715
+ "extension.pipeline.optionYes": "\u8DF3\u8FC7\u4EA4\u4E92\u786E\u8BA4",
3716
+ "extension.pipeline.idNotFound": "\u672A\u80FD\u81EA\u52A8\u8BC6\u522B\u6A21\u677F ID\u3002\u8BF7\u786E\u4FDD\u5F53\u524D\u76EE\u5F55\u4E0B\u5B58\u5728\u6709\u6548\u7684 manifest.yaml \u6216 package.json\uFF0C\u6216\u4F7F\u7528 --template-id \u663E\u5F0F\u4F20\u5165\u3002",
3717
+ "extension.pipeline.overwritePrompt": "\u68C0\u6D4B\u5230\u5F53\u524D\u76EE\u5F55\u5DF2\u5B58\u5728 .gitlab-ci.yml\uFF0C\u662F\u5426\u8986\u76D6\uFF1F",
3718
+ "extension.pipeline.cancelled": "\u64CD\u4F5C\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FEE\u6539\u73B0\u6709\u6D41\u6C34\u7EBF\u914D\u7F6E\u3002",
3719
+ "extension.pipeline.alreadyExists": "\u5F53\u524D\u76EE\u5F55\u5DF2\u5B58\u5728 .gitlab-ci.yml\uFF0C\u5982\u9700\u8986\u76D6\u8BF7\u4F20\u9012 --force \u53C2\u6570\u3002",
3720
+ "extension.pipeline.success": "\u2713 \u6210\u529F\u751F\u6210 CI/CD \u6D41\u6C34\u7EBF\u914D\u7F6E: {0}",
3721
+ "extension.pipeline.addedReleaseScript": '\u2713 \u5DF2\u5728 package.json \u7684 scripts \u4E2D\u6DFB\u52A0\u53D1\u7248\u547D\u4EE4: "release": "npm version patch"',
3722
+ "extension.pipeline.gitlabNotice": '\n\u2699\uFE0F GitLab \u9879\u76EE\u914D\u7F6E\u63D0\u793A:\n \u8BF7\u5728\u5F53\u524D\u6A21\u677F\u4ED3\u5E93\u7684\u3010Settings -> CI/CD -> Variables\u3011\u4E2D\u914D\u7F6E\u4EE5\u4E0B\u73AF\u5883\u53D8\u91CF\uFF1A\n - REGISTRY_TRIGGER_TOKEN: Registry \u4ED3\u5E93\u751F\u6210\u7684 Pipeline Trigger Token\n - REGISTRY_PROJECT_ID: Registry \u4ED3\u5E93\u5728 GitLab \u4E0A\u7684\u9879\u76EE ID\n\n\u{1F680} \u65E5\u5E38\u53D1\u7248\u5DE5\u4F5C\u6D41:\n 1. \u63D0\u4EA4\u4EE3\u7801: git add . && git commit -m "feat: xxx"\n 2. \u4E00\u952E\u63D0\u5347\u7248\u672C\u5E76\u6253 Tag: npm run release\n 3. \u63A8\u9001\u5230\u8FDC\u7A0B\u89E6\u53D1\u81EA\u52A8\u5408\u5E76: git push --follow-tags origin main\n\n'
3658
3723
  };
3659
3724
  }
3660
3725
  });
@@ -23353,10 +23418,10 @@ async function persistGitCheckout(workDir, targetDir) {
23353
23418
  return targetDir;
23354
23419
  }
23355
23420
  async function copyGitCheckout(src, dest) {
23356
- const { readdir: readdir11, mkdir: mkdir20, copyFile: copyFile2 } = await import("node:fs/promises");
23421
+ const { readdir: readdir12, mkdir: mkdir20, copyFile: copyFile2 } = await import("node:fs/promises");
23357
23422
  const { join: joinPath } = await import("node:path");
23358
23423
  await mkdir20(dest, { recursive: true });
23359
- const entries = await readdir11(src, { withFileTypes: true });
23424
+ const entries = await readdir12(src, { withFileTypes: true });
23360
23425
  for (const entry of entries) {
23361
23426
  if (entry.name === ".git") continue;
23362
23427
  const srcPath = joinPath(src, entry.name);
@@ -23549,8 +23614,8 @@ var init_git_resolver = __esm({
23549
23614
  }
23550
23615
  const cacheBase = join6(cacheRoot, "git", encodePackageId(packageId));
23551
23616
  try {
23552
- const { readdir: readdir11 } = await import("node:fs/promises");
23553
- const commits = await readdir11(cacheBase, { withFileTypes: true });
23617
+ const { readdir: readdir12 } = await import("node:fs/promises");
23618
+ const commits = await readdir12(cacheBase, { withFileTypes: true });
23554
23619
  for (const entry of commits) {
23555
23620
  if (!entry.isDirectory()) continue;
23556
23621
  const cacheDir = join6(cacheBase, entry.name);
@@ -26935,10 +27000,10 @@ var init_tarball_loader = __esm({
26935
27000
  return targetDir;
26936
27001
  }
26937
27002
  async copyDirRecursive(src, dest) {
26938
- const { readdir: readdir11, mkdir: mkdir20, copyFile: copyFile2 } = await import("node:fs/promises");
27003
+ const { readdir: readdir12, mkdir: mkdir20, copyFile: copyFile2 } = await import("node:fs/promises");
26939
27004
  const { join: joinPath } = await import("node:path");
26940
27005
  await mkdir20(dest, { recursive: true });
26941
- const entries = await readdir11(src, { withFileTypes: true });
27006
+ const entries = await readdir12(src, { withFileTypes: true });
26942
27007
  for (const entry of entries) {
26943
27008
  const srcPath = joinPath(src, entry.name);
26944
27009
  const destPath = joinPath(dest, entry.name);
@@ -27001,14 +27066,14 @@ var init_tarball_loader = __esm({
27001
27066
  return readFile34(join7(packageRoot, "manifest.yaml"), "utf-8");
27002
27067
  }
27003
27068
  async findPackageRoot(workDir, packageId, version) {
27004
- const { access: access12, readdir: readdir11 } = await import("node:fs/promises");
27069
+ const { access: access12, readdir: readdir12 } = await import("node:fs/promises");
27005
27070
  const { resolve: resolvePath10 } = await import("node:path");
27006
27071
  const candidates = [
27007
27072
  resolvePath10(workDir),
27008
27073
  resolvePath10(workDir, "package")
27009
27074
  ];
27010
27075
  try {
27011
- const entries = await readdir11(workDir, { withFileTypes: true });
27076
+ const entries = await readdir12(workDir, { withFileTypes: true });
27012
27077
  for (const entry of entries) {
27013
27078
  if (entry.isDirectory()) {
27014
27079
  candidates.push(resolvePath10(workDir, entry.name));
@@ -30530,10 +30595,27 @@ var init_toml_editor = __esm({
30530
30595
  });
30531
30596
 
30532
30597
  // packages/core/src/execute/executor.ts
30533
- import { readFile as readFile17, writeFile as writeFile5, unlink as unlink7, mkdir as mkdir12, access as access9, rename as rename4, rm as rm4, mkdtemp as mkdtemp4, chmod } from "node:fs/promises";
30598
+ import { readFile as readFile17, writeFile as writeFile5, unlink as unlink7, mkdir as mkdir12, access as access9, rename as rename4, rm as rm4, mkdtemp as mkdtemp4, chmod, readdir as readdir5, rmdir } from "node:fs/promises";
30534
30599
  import { resolve as resolvePath7, dirname as dirname11, join as join12 } from "node:path";
30535
30600
  import { tmpdir as tmpdir4 } from "node:os";
30536
30601
  import { createHash as createHash9 } from "node:crypto";
30602
+ async function cleanEmptyParentDirs(startDir, rootDir) {
30603
+ let current = resolvePath7(startDir);
30604
+ const normalizedRoot = resolvePath7(rootDir);
30605
+ while (current !== normalizedRoot && current.startsWith(normalizedRoot)) {
30606
+ try {
30607
+ const files = await readdir5(current);
30608
+ if (files.length === 0) {
30609
+ await rmdir(current);
30610
+ current = dirname11(current);
30611
+ } else {
30612
+ break;
30613
+ }
30614
+ } catch {
30615
+ break;
30616
+ }
30617
+ }
30618
+ }
30537
30619
  async function getTmpBase() {
30538
30620
  return mkdtemp4(join12(tmpdir4(), "aicoding-tx-"));
30539
30621
  }
@@ -30931,6 +31013,7 @@ var init_executor = __esm({
30931
31013
  throw err;
30932
31014
  }
30933
31015
  });
31016
+ await cleanEmptyParentDirs(dirname11(absPath), projectRoot);
30934
31017
  addFileRollback(absPath, backupPath, rollbackActions, `\u6062\u590D\u5DF2\u5220\u9664\u7684\u6587\u4EF6 ${intent.path}`);
30935
31018
  } else if (intent.type === "config-entry") {
30936
31019
  await removeConfigEntry(absPath, intent.selector, intent.format, backupDir, rollbackActions, intent.path);
@@ -31831,7 +31914,7 @@ var init_task_runner = __esm({
31831
31914
  });
31832
31915
 
31833
31916
  // packages/core/src/execute/template-contract.ts
31834
- import { readFile as readFile19, readdir as readdir5 } from "node:fs/promises";
31917
+ import { readFile as readFile19, readdir as readdir6 } from "node:fs/promises";
31835
31918
  import { join as join14, relative as relative6 } from "node:path";
31836
31919
  function validateMcpConfig(rawConfig) {
31837
31920
  if (typeof rawConfig !== "object" || rawConfig === null) {
@@ -31974,7 +32057,7 @@ async function scanTemplateDirectoryContract(options) {
31974
32057
  if (shouldIncludeAssetType("skills", filter)) {
31975
32058
  const skillsDir = join14(templateDir, "skills");
31976
32059
  try {
31977
- const skillEntries = await readdir5(skillsDir, { withFileTypes: true });
32060
+ const skillEntries = await readdir6(skillsDir, { withFileTypes: true });
31978
32061
  for (const skillEntry of skillEntries) {
31979
32062
  if (!skillEntry.isDirectory()) continue;
31980
32063
  const skillId = skillEntry.name;
@@ -32001,7 +32084,7 @@ async function scanTemplateDirectoryContract(options) {
32001
32084
  if (shouldIncludeAssetType("rules", filter)) {
32002
32085
  const rulesDir = join14(templateDir, "rules");
32003
32086
  try {
32004
- const ruleIdeEntries = await readdir5(rulesDir, { withFileTypes: true });
32087
+ const ruleIdeEntries = await readdir6(rulesDir, { withFileTypes: true });
32005
32088
  for (const ideEntry of ruleIdeEntries) {
32006
32089
  if (!ideEntry.isDirectory()) continue;
32007
32090
  const ide = ideEntry.name;
@@ -32027,7 +32110,7 @@ async function scanTemplateDirectoryContract(options) {
32027
32110
  if (shouldIncludeAssetType("subagents", filter)) {
32028
32111
  const subagentsDir = join14(templateDir, "subagents");
32029
32112
  try {
32030
- const agentIdeEntries = await readdir5(subagentsDir, { withFileTypes: true });
32113
+ const agentIdeEntries = await readdir6(subagentsDir, { withFileTypes: true });
32031
32114
  for (const ideEntry of agentIdeEntries) {
32032
32115
  if (!ideEntry.isDirectory()) continue;
32033
32116
  const ide = ideEntry.name;
@@ -32075,12 +32158,30 @@ async function scanTemplateDirectoryContract(options) {
32075
32158
  }
32076
32159
  }
32077
32160
  }
32161
+ if (!filter?.skipProjectDir) {
32162
+ const projectDir = join14(templateDir, "project");
32163
+ try {
32164
+ const allProjectFiles = await listAllFilesRecursive(projectDir);
32165
+ for (const relFile of allProjectFiles) {
32166
+ const fileContent = await readFile19(join14(projectDir, relFile));
32167
+ const normalizedRel = relFile.replaceAll("\\", "/");
32168
+ intents.push({
32169
+ action: "upsert",
32170
+ type: "file",
32171
+ path: normalizedRel,
32172
+ content: fileContent,
32173
+ assetType: "project-seed"
32174
+ });
32175
+ }
32176
+ } catch {
32177
+ }
32178
+ }
32078
32179
  return intents;
32079
32180
  }
32080
32181
  async function listAllFilesRecursive(dir, baseDir = dir) {
32081
32182
  const files = [];
32082
32183
  try {
32083
- const entries = await readdir5(dir, { withFileTypes: true });
32184
+ const entries = await readdir6(dir, { withFileTypes: true });
32084
32185
  for (const entry of entries) {
32085
32186
  const full = join14(dir, entry.name);
32086
32187
  if (entry.isDirectory()) {
@@ -32109,7 +32210,7 @@ var init_template_contract = __esm({
32109
32210
  });
32110
32211
 
32111
32212
  // packages/core/src/plugin/plugin-delivery.ts
32112
- import { readFile as readFile20, stat as stat4, readdir as readdir6 } from "node:fs/promises";
32213
+ import { readFile as readFile20, stat as stat4, readdir as readdir7 } from "node:fs/promises";
32113
32214
  import { join as join15, resolve as resolve11 } from "node:path";
32114
32215
  import { createHash as createHash11 } from "node:crypto";
32115
32216
  function isPluginTargetSupported(target) {
@@ -32467,7 +32568,7 @@ function buildSettingsUpdate(plugin, target) {
32467
32568
  }
32468
32569
  async function collectDirectoryCopyIntents(sourceDir, sourceRelPath, destDir, packageRoot, metadata) {
32469
32570
  const intents = [];
32470
- const entries = await readdir6(sourceDir, { withFileTypes: true });
32571
+ const entries = await readdir7(sourceDir, { withFileTypes: true });
32471
32572
  for (const entry of entries) {
32472
32573
  const entrySourcePath = join15(sourceDir, entry.name);
32473
32574
  const entryDestPath = `${destDir}/${entry.name}`;
@@ -32586,7 +32687,7 @@ var init_plugin = __esm({
32586
32687
 
32587
32688
  // packages/core/src/journal.ts
32588
32689
  import { createHash as createHash12, randomUUID as randomUUID3 } from "node:crypto";
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";
32690
+ import { chmod as chmod2, cp as cp2, mkdir as mkdir14, open as open4, readdir as readdir8, readFile as readFile21, rename as rename5, rm as rm5, stat as stat5, writeFile as writeFile7 } from "node:fs/promises";
32590
32691
  import { dirname as dirname12, join as join16, resolve as resolve12 } from "node:path";
32591
32692
  function projectHash(projectRoot) {
32592
32693
  return createHash12("sha256").update(resolve12(projectRoot)).digest("hex").slice(0, 32);
@@ -32734,7 +32835,7 @@ async function scanJournals(userDataDir, projectRoot) {
32734
32835
  const directory = join16(resolve12(userDataDir), "transactions", projectHash(projectRoot));
32735
32836
  let entries;
32736
32837
  try {
32737
- entries = await readdir7(directory, { withFileTypes: true });
32838
+ entries = await readdir8(directory, { withFileTypes: true });
32738
32839
  } catch (error) {
32739
32840
  if (error.code === "ENOENT") return [];
32740
32841
  throw error;
@@ -33307,7 +33408,7 @@ var init_staging_manager = __esm({
33307
33408
  });
33308
33409
 
33309
33410
  // packages/core/src/orchestrator/staging-scanner.ts
33310
- import { readFile as readFile23, readdir as readdir8, stat as stat6 } from "node:fs/promises";
33411
+ import { readFile as readFile23, readdir as readdir9, stat as stat6 } from "node:fs/promises";
33311
33412
  import { join as join18, relative as relative7 } from "node:path";
33312
33413
  async function scanStagingDirectory(options) {
33313
33414
  const { stagingDir, packageId, ownerKind = "template" } = options;
@@ -33316,7 +33417,7 @@ async function scanStagingDirectory(options) {
33316
33417
  async function walk(currentDir) {
33317
33418
  let entries;
33318
33419
  try {
33319
- entries = await readdir8(currentDir, { withFileTypes: true });
33420
+ entries = await readdir9(currentDir, { withFileTypes: true });
33320
33421
  } catch {
33321
33422
  return;
33322
33423
  }
@@ -43846,9 +43947,9 @@ notify_registry:
43846
43947
  }
43847
43948
  function createExtensionPipelineCommand() {
43848
43949
  const cmd = new Command("pipeline");
43849
- cmd.alias("ci").description(t("extension.pipeline.description")).argument("[directory]", t("extension.pipeline.argDirectory"), ".").option("--package-id <id>", t("extension.pipeline.optionPackageId")).option("--force", t("extension.pipeline.optionForce")).option("--yes", "\u8DF3\u8FC7\u4EA4\u4E92\u786E\u8BA4").option("--json", t("global.json")).option("--no-color", t("global.noColor")).option("--verbose", t("global.verbose")).action(async (directory, opts) => {
43950
+ cmd.alias("ci").description(t("extension.pipeline.description")).argument("[directory]", t("extension.pipeline.argDirectory"), ".").option("--template-id <id>", t("extension.pipeline.optionTemplateId")).option("--force", t("extension.pipeline.optionForce")).option("--yes", t("extension.pipeline.optionYes")).option("--json", t("global.json")).option("--no-color", t("global.noColor")).option("--verbose", t("global.verbose")).action(async (directory, opts) => {
43850
43951
  const options = {
43851
- packageId: opts.packageId,
43952
+ templateId: opts.templateId ?? opts.packageId,
43852
43953
  force: Boolean(opts.force),
43853
43954
  yes: Boolean(opts.yes),
43854
43955
  json: Boolean(opts.json),
@@ -43880,35 +43981,35 @@ async function executeExtensionPipeline(directory, options) {
43880
43981
  const pkgJsonPath = resolve14(targetDir, "package.json");
43881
43982
  const ciFilePath = resolve14(targetDir, ".gitlab-ci.yml");
43882
43983
  const isInteractive = !options.yes && !options.json && Boolean(process.stdin.isTTY);
43883
- let packageId = options.packageId;
43884
- if (!packageId) {
43984
+ let templateId = options.templateId;
43985
+ if (!templateId) {
43885
43986
  if (existsSync5(manifestPath)) {
43886
43987
  try {
43887
43988
  const manifestContent = await readFile24(manifestPath, "utf-8");
43888
43989
  const parsed = import_yaml4.default.parse(manifestContent);
43889
43990
  if (parsed && typeof parsed.id === "string") {
43890
- packageId = parsed.id;
43991
+ templateId = parsed.id;
43891
43992
  }
43892
43993
  } catch {
43893
43994
  }
43894
43995
  }
43895
- if (!packageId && existsSync5(pkgJsonPath)) {
43996
+ if (!templateId && existsSync5(pkgJsonPath)) {
43896
43997
  try {
43897
43998
  const pkgContent = await readFile24(pkgJsonPath, "utf-8");
43898
43999
  const parsed = JSON.parse(pkgContent);
43899
44000
  if (parsed && typeof parsed.name === "string") {
43900
- packageId = parsed.name;
44001
+ templateId = parsed.name;
43901
44002
  }
43902
44003
  } catch {
43903
44004
  }
43904
44005
  }
43905
44006
  }
43906
- if (!packageId) {
43907
- const errorMsg = "\u672A\u80FD\u81EA\u52A8\u8BC6\u522B\u6269\u5C55\u5305 ID\u3002\u8BF7\u786E\u4FDD\u5F53\u524D\u76EE\u5F55\u4E0B\u5B58\u5728\u6709\u6548\u7684 manifest.yaml \u6216 package.json\uFF0C\u6216\u4F7F\u7528 --package-id \u663E\u5F0F\u4F20\u5165\u3002";
44007
+ if (!templateId) {
44008
+ const errorMsg = t("extension.pipeline.idNotFound");
43908
44009
  if (output.json) {
43909
- emitFailureJson("extension pipeline", "PACKAGE_ID_NOT_FOUND", errorMsg);
44010
+ emitFailureJson("extension pipeline", "TEMPLATE_ID_NOT_FOUND", errorMsg);
43910
44011
  } else {
43911
- process.stderr.write(`error: PACKAGE_ID_NOT_FOUND: ${errorMsg}
44012
+ process.stderr.write(`error: TEMPLATE_ID_NOT_FOUND: ${errorMsg}
43912
44013
  `);
43913
44014
  }
43914
44015
  return ExitCode.ResolveFailed;
@@ -43916,15 +44017,16 @@ async function executeExtensionPipeline(directory, options) {
43916
44017
  if (existsSync5(ciFilePath) && !options.force) {
43917
44018
  if (isInteractive) {
43918
44019
  const overwrite = await dist_default5({
43919
- message: "\u68C0\u6D4B\u5230\u5F53\u524D\u76EE\u5F55\u5DF2\u5B58\u5728 .gitlab-ci.yml\uFF0C\u662F\u5426\u8986\u76D6\uFF1F",
44020
+ message: t("extension.pipeline.overwritePrompt"),
43920
44021
  default: false
43921
44022
  });
43922
44023
  if (!overwrite) {
43923
- process.stdout.write("\u64CD\u4F5C\u5DF2\u53D6\u6D88\uFF0C\u672A\u4FEE\u6539\u73B0\u6709\u6D41\u6C34\u7EBF\u914D\u7F6E\u3002\n");
44024
+ process.stdout.write(`${t("extension.pipeline.cancelled")}
44025
+ `);
43924
44026
  return ExitCode.Success;
43925
44027
  }
43926
44028
  } else {
43927
- const errorMsg = "\u5F53\u524D\u76EE\u5F55\u5DF2\u5B58\u5728 .gitlab-ci.yml\uFF0C\u5982\u9700\u8986\u76D6\u8BF7\u4F20\u9012 --force \u53C2\u6570\u3002";
44029
+ const errorMsg = t("extension.pipeline.alreadyExists");
43928
44030
  if (output.json) {
43929
44031
  emitFailureJson("extension pipeline", "FILE_ALREADY_EXISTS", errorMsg);
43930
44032
  } else {
@@ -43934,7 +44036,7 @@ async function executeExtensionPipeline(directory, options) {
43934
44036
  return ExitCode.ConflictOrDrift;
43935
44037
  }
43936
44038
  }
43937
- const ciContent = generateGitlabCiYaml(packageId);
44039
+ const ciContent = generateGitlabCiYaml(templateId);
43938
44040
  await writeFile9(ciFilePath, ciContent, "utf-8");
43939
44041
  let addedReleaseScript = false;
43940
44042
  if (existsSync5(pkgJsonPath)) {
@@ -43953,25 +44055,18 @@ async function executeExtensionPipeline(directory, options) {
43953
44055
  if (output.json) {
43954
44056
  emitSuccessJson("extension pipeline", {
43955
44057
  directory: targetDir,
43956
- packageId,
44058
+ templateId,
43957
44059
  ciFile: ciFilePath,
43958
44060
  addedReleaseScript
43959
44061
  });
43960
44062
  } else {
43961
- process.stdout.write(`\u2713 \u6210\u529F\u751F\u6210 CI/CD \u6D41\u6C34\u7EBF\u914D\u7F6E: ${ciFilePath}
44063
+ process.stdout.write(`${t("extension.pipeline.success", ciFilePath)}
43962
44064
  `);
43963
44065
  if (addedReleaseScript) {
43964
- process.stdout.write(`\u2713 \u5DF2\u5728 package.json \u7684 scripts \u4E2D\u6DFB\u52A0\u53D1\u7248\u547D\u4EE4: "release": "npm version patch"
44066
+ process.stdout.write(`${t("extension.pipeline.addedReleaseScript")}
43965
44067
  `);
43966
44068
  }
43967
- process.stdout.write("\n\u2699\uFE0F GitLab \u9879\u76EE\u914D\u7F6E\u63D0\u793A:\n");
43968
- process.stdout.write(" \u8BF7\u5728\u5F53\u524D\u6269\u5C55\u5305\u4ED3\u5E93\u7684\u3010Settings -> CI/CD -> Variables\u3011\u4E2D\u914D\u7F6E\u4EE5\u4E0B\u73AF\u5883\u53D8\u91CF\uFF1A\n");
43969
- process.stdout.write(" - REGISTRY_TRIGGER_TOKEN: Registry \u4ED3\u5E93\u751F\u6210\u7684 Pipeline Trigger Token\n");
43970
- process.stdout.write(" - REGISTRY_PROJECT_ID: Registry \u4ED3\u5E93\u5728 GitLab \u4E0A\u7684\u9879\u76EE ID\n");
43971
- process.stdout.write("\n\u{1F680} \u65E5\u5E38\u53D1\u7248\u5DE5\u4F5C\u6D41:\n");
43972
- process.stdout.write(' 1. \u63D0\u4EA4\u4EE3\u7801: git add . && git commit -m "feat: xxx"\n');
43973
- process.stdout.write(" 2. \u4E00\u952E\u63D0\u5347\u7248\u672C\u5E76\u6253 Tag: npm run release\n");
43974
- process.stdout.write(" 3. \u63A8\u9001\u5230\u8FDC\u7A0B\u89E6\u53D1\u81EA\u52A8\u5408\u5E76: git push --follow-tags origin main\n\n");
44069
+ process.stdout.write(t("extension.pipeline.gitlabNotice"));
43975
44070
  }
43976
44071
  return ExitCode.Success;
43977
44072
  }
@@ -43988,18 +44083,18 @@ var init_extension_pipeline = __esm({
43988
44083
  });
43989
44084
 
43990
44085
  // packages/cli/src/commands/extension-create.ts
43991
- import { mkdir as mkdir17, writeFile as writeFile10, readdir as readdir9 } from "node:fs/promises";
44086
+ import { mkdir as mkdir17, writeFile as writeFile10, readdir as readdir10 } from "node:fs/promises";
43992
44087
  import { basename as basename4, resolve as resolve15 } from "node:path";
43993
44088
  function createExtensionCreateCommand() {
43994
44089
  const cmd = new Command("create");
43995
- cmd.description(t("extension.create.description")).argument("<directory>", t("extension.create.argDirectory")).option("--name <package-id>", t("extension.create.optionName")).option("--template-name <name>", "\u6A21\u677F\u663E\u793A\u540D\u79F0 (name)").option("--description <description>", "\u6A21\u677F\u63CF\u8FF0").option("--with-tasks", "\u662F\u5426\u751F\u6210\u521D\u59CB\u5316\u4EFB\u52A1\u793A\u4F8B").option("--with-pipeline", t("extension.create.optionWithPipeline")).option("--category <category>", t("extension.create.optionCategory")).option("--with-project", t("extension.create.optionWithProject")).option("--with-capability <type>", t("extension.create.optionWithCapability"), collectCapability, []).option("--yes", t("extension.create.optionYes")).option("--json", t("global.json")).option("--no-color", t("global.noColor")).option("--verbose", t("global.verbose")).action(async (directory, opts) => {
44090
+ cmd.description(t("extension.create.description")).argument("<directory>", t("extension.create.argDirectory")).option("--name <package-id>", t("extension.create.optionName")).option("--template-name <name>", t("extension.create.optionTemplateName")).option("--description <description>", t("extension.create.optionDescription")).option("--with-tasks", t("extension.create.optionWithTasks")).option("--with-pipeline", t("extension.create.optionWithPipeline")).option("--category <category>", t("extension.create.optionCategory")).option("--with-project", t("extension.create.optionWithProject")).option("--with-capability <type>", t("extension.create.optionWithCapability"), collectCapability, []).option("--yes", t("extension.create.optionYes")).option("--json", t("global.json")).option("--no-color", t("global.noColor")).option("--verbose", t("global.verbose")).action(async (directory, opts) => {
43996
44091
  const options = {
43997
44092
  name: opts.name,
43998
44093
  templateName: opts.templateName,
43999
44094
  description: opts.description,
44000
44095
  category: opts.category,
44001
- withProject: Boolean(opts.withProject),
44002
- withTasks: Boolean(opts.withTasks),
44096
+ withProject: opts.withProject !== void 0 ? Boolean(opts.withProject) : void 0,
44097
+ withTasks: opts.withTasks !== void 0 ? Boolean(opts.withTasks) : void 0,
44003
44098
  withPipeline: opts.withPipeline !== void 0 ? Boolean(opts.withPipeline) : void 0,
44004
44099
  withCapability: Array.isArray(opts.withCapability) ? opts.withCapability : [],
44005
44100
  yes: Boolean(opts.yes),
@@ -44037,7 +44132,7 @@ async function executeExtensionCreate(directory, options) {
44037
44132
  const dirBase = basename4(targetDir);
44038
44133
  const isInteractive = !options.yes && !options.json && Boolean(process.stdin.isTTY);
44039
44134
  try {
44040
- const entries = await readdir9(targetDir);
44135
+ const entries = await readdir10(targetDir);
44041
44136
  if (entries.length > 0) {
44042
44137
  if (output.json) {
44043
44138
  emitFailureJson(
@@ -44058,7 +44153,7 @@ async function executeExtensionCreate(directory, options) {
44058
44153
  if (!packageId) {
44059
44154
  if (isInteractive) {
44060
44155
  packageId = await dist_default6({
44061
- message: "\u8BF7\u8F93\u5165\u6A21\u677F\u5305\u540D (Package ID):",
44156
+ message: t("extension.create.promptName"),
44062
44157
  default: sanitizePackageId(dirBase) || "my-template"
44063
44158
  });
44064
44159
  } else {
@@ -44069,7 +44164,7 @@ async function executeExtensionCreate(directory, options) {
44069
44164
  if (!templateName) {
44070
44165
  if (isInteractive) {
44071
44166
  templateName = await dist_default6({
44072
- message: "\u8BF7\u8F93\u5165\u6A21\u677F\u540D\u79F0 (Name):",
44167
+ message: t("extension.create.promptTemplateName"),
44073
44168
  default: packageId.replace(/^@[^/]+\//, "")
44074
44169
  });
44075
44170
  } else {
@@ -44080,24 +44175,31 @@ async function executeExtensionCreate(directory, options) {
44080
44175
  if (!description) {
44081
44176
  if (isInteractive) {
44082
44177
  description = await dist_default6({
44083
- message: "\u8BF7\u8F93\u5165\u6A21\u677F\u7B80\u8981\u63CF\u8FF0 (Description):",
44178
+ message: t("extension.create.promptDescription"),
44084
44179
  default: `${templateName} template for Mano Coding`
44085
44180
  });
44086
44181
  } else {
44087
44182
  description = `${templateName} template for Mano Coding`;
44088
44183
  }
44089
44184
  }
44185
+ let withProject = options.withProject;
44186
+ if (withProject === void 0 && isInteractive) {
44187
+ withProject = await dist_default5({
44188
+ message: t("extension.create.promptWithProject"),
44189
+ default: false
44190
+ });
44191
+ }
44090
44192
  let withTasks = options.withTasks;
44091
44193
  if (withTasks === void 0 && isInteractive) {
44092
44194
  withTasks = await dist_default5({
44093
- message: "\u662F\u5426\u5305\u542B\u9879\u76EE\u811A\u624B\u67B6\u521D\u59CB\u5316\u4EFB\u52A1 (Tasks) \u793A\u4F8B\uFF1F",
44195
+ message: t("extension.create.promptWithTasks"),
44094
44196
  default: true
44095
44197
  });
44096
44198
  }
44097
44199
  let withPipeline = options.withPipeline;
44098
44200
  if (withPipeline === void 0 && isInteractive) {
44099
44201
  withPipeline = await dist_default5({
44100
- message: "\u662F\u5426\u751F\u6210 GitLab CI/CD \u81EA\u52A8\u540C\u6B65\u6D41\u6C34\u7EBF\u914D\u7F6E (.gitlab-ci.yml)\uFF1F",
44202
+ message: t("extension.create.promptWithPipeline"),
44101
44203
  default: true
44102
44204
  });
44103
44205
  }
@@ -44108,6 +44210,17 @@ async function executeExtensionCreate(directory, options) {
44108
44210
  if (withPipeline) {
44109
44211
  scripts.release = "npm version patch";
44110
44212
  }
44213
+ const pkgFiles = [
44214
+ "manifest.yaml",
44215
+ "AGENTS.md",
44216
+ "skills",
44217
+ "rules",
44218
+ "mcp",
44219
+ "README.md"
44220
+ ];
44221
+ if (withProject) {
44222
+ pkgFiles.push("project");
44223
+ }
44111
44224
  const pkgJson = {
44112
44225
  name: packageId,
44113
44226
  version: "0.1.0",
@@ -44115,14 +44228,7 @@ async function executeExtensionCreate(directory, options) {
44115
44228
  type: "module",
44116
44229
  engines: { node: ">=22.0.0" },
44117
44230
  scripts,
44118
- files: [
44119
- "manifest.yaml",
44120
- "AGENTS.md",
44121
- "skills",
44122
- "rules",
44123
- "mcp",
44124
- "README.md"
44125
- ],
44231
+ files: pkgFiles,
44126
44232
  devDependencies: {
44127
44233
  vitest: "^3.0.5"
44128
44234
  }
@@ -44239,6 +44345,50 @@ describe('${packageId} template manifest', () => {
44239
44345
  "package.json",
44240
44346
  "test/manifest.test.ts"
44241
44347
  ];
44348
+ if (withProject) {
44349
+ const projectDir = resolve15(targetDir, "project");
44350
+ const projectSrcDir = resolve15(projectDir, "src");
44351
+ await mkdir17(projectSrcDir, { recursive: true });
44352
+ const starterPkgName = `${packageId.replace(/^@[^/]+\//, "")}-starter`;
44353
+ const projectPkgJson = {
44354
+ name: starterPkgName,
44355
+ version: "0.1.0",
44356
+ private: true,
44357
+ type: "module",
44358
+ scripts: {
44359
+ dev: "vite",
44360
+ build: "vite build"
44361
+ }
44362
+ };
44363
+ await writeFile10(
44364
+ resolve15(projectDir, "package.json"),
44365
+ JSON.stringify(projectPkgJson, null, 2) + "\n",
44366
+ "utf-8"
44367
+ );
44368
+ const projectReadme = `# ${starterPkgName}
44369
+
44370
+ \u8FD9\u662F\u4E00\u4E2A\u7531 ${packageId} \u6A21\u677F\u63D0\u4F9B\u7684\u521D\u59CB\u5DE5\u7A0B\u811A\u624B\u67B6\uFF08\u9879\u76EE\u9AA8\u67B6\u79CD\u5B50\uFF09\u3002
44371
+
44372
+ \u5728\u6267\u884C \`mano-coding create\` \u65F6\uFF0C\u6B64\u76EE\u5F55\u4E2D\u7684\u6587\u4EF6\u5C06\u81EA\u52A8\u91CA\u653E\u5230\u76EE\u6807\u5DE5\u7A0B\u6839\u76EE\u5F55\u3002
44373
+ \u6CE8\u610F\uFF1A\u672C\u76EE\u5F55\u4E2D\u7684\u9759\u6001\u5DE5\u7A0B\u811A\u624B\u67B6\u6587\u4EF6\u4E3A bootstrap \u8D44\u6E90\uFF0C\u4E0D\u7EB3\u5165 \`.ai-coding.lock\` \u53D7\u7BA1\u8D44\u4EA7\u8DDF\u8E2A\u3002
44374
+ `;
44375
+ await writeFile10(resolve15(projectDir, "README.md"), projectReadme, "utf-8");
44376
+ const projectIndexTs = `/**
44377
+ * ${starterPkgName} \u5165\u53E3\u6587\u4EF6
44378
+ */
44379
+ export function main(): void {
44380
+ console.log('Hello from ${starterPkgName}!');
44381
+ }
44382
+
44383
+ main();
44384
+ `;
44385
+ await writeFile10(resolve15(projectSrcDir, "index.ts"), projectIndexTs, "utf-8");
44386
+ createdFiles.push(
44387
+ "project/package.json",
44388
+ "project/README.md",
44389
+ "project/src/index.ts"
44390
+ );
44391
+ }
44242
44392
  if (withPipeline) {
44243
44393
  await writeFile10(
44244
44394
  resolve15(targetDir, ".gitlab-ci.yml"),
@@ -44252,7 +44402,8 @@ describe('${packageId} template manifest', () => {
44252
44402
  templateName,
44253
44403
  description,
44254
44404
  withTasks: Boolean(withTasks),
44255
- withPipeline: Boolean(withPipeline)
44405
+ withPipeline: Boolean(withPipeline),
44406
+ withProject: Boolean(withProject)
44256
44407
  });
44257
44408
  await writeFile10(resolve15(targetDir, "README.md"), readmeContent, "utf-8");
44258
44409
  if (output.json) {
@@ -44262,9 +44413,9 @@ describe('${packageId} template manifest', () => {
44262
44413
  files: createdFiles
44263
44414
  });
44264
44415
  } else {
44265
- process.stdout.write(`\u2713 \u6210\u529F\u521D\u59CB\u5316\u6A21\u677F\u5DE5\u7A0B: ${targetDir}
44416
+ process.stdout.write(`${t("extension.create.success", targetDir)}
44266
44417
  `);
44267
- process.stdout.write(`\u5DF2\u751F\u6210\u6587\u4EF6\u6E05\u5355:
44418
+ process.stdout.write(`${t("extension.create.generatedFiles")}
44268
44419
  - ${createdFiles.join("\n - ")}
44269
44420
  `);
44270
44421
  }
@@ -44299,6 +44450,21 @@ git push --follow-tags origin main
44299
44450
  mano-coding extension pipeline .
44300
44451
  \`\`\`
44301
44452
  `;
44453
+ const projectSection = options.withProject ? `
44454
+ ---
44455
+
44456
+ ## \u9759\u6001\u5DE5\u7A0B\u811A\u624B\u67B6 (project/ \u76EE\u5F55)
44457
+
44458
+ \u672C\u6A21\u677F\u5305\u542B\u9759\u6001\u5DE5\u7A0B\u811A\u624B\u67B6\u76EE\u5F55 \`project/\`\uFF1A
44459
+ - \u6267\u884C \`mano-coding create <\u9879\u76EE\u540D> --template <\u672C\u6A21\u677F>\` \u65F6\uFF0C\`project/\` \u4E0B\u7684\u6587\u4EF6\u5C06\u81EA\u52A8\u590D\u5236\u5230\u65B0\u5EFA\u5DE5\u7A0B\u6839\u76EE\u5F55\uFF0C\u4F5C\u4E3A\u521D\u59CB\u6E90\u4EE3\u7801\u9AA8\u67B6\u3002
44460
+ - \u9759\u6001\u5DE5\u7A0B\u6587\u4EF6\u4F5C\u4E3A bootstrap \u79CD\u5B50\u8D44\u6E90\uFF0C\u4E0D\u4F1A\u8BA1\u5165 \`.ai-coding.lock\` \u53D7\u7BA1\u6E05\u5355\uFF0C\u540E\u7EED\u6267\u884C \`apply\` \u6216 \`sync\` \u65F6\u4E0D\u4F1A\u8986\u76D6\u7528\u6237\u5BF9\u5DE5\u7A0B\u6587\u4EF6\u7684\u4FEE\u6539\u3002
44461
+ ` : "";
44462
+ const projectTree = options.withProject ? `\u251C\u2500\u2500 project/ # [\u53EF\u9009] \u9759\u6001\u5DE5\u7A0B\u811A\u624B\u67B6\u79CD\u5B50\u76EE\u5F55\uFF08\u5728 create \u65F6\u91CA\u653E\u5230\u9879\u76EE\u6839\u76EE\u5F55\uFF0C\u4F5C\u4E3A\u521D\u59CB\u6E90\u7801\u6846\u67B6\uFF09
44463
+ \u2502 \u251C\u2500\u2500 package.json
44464
+ \u2502 \u251C\u2500\u2500 README.md
44465
+ \u2502 \u2514\u2500\u2500 src/
44466
+ \u2502 \u2514\u2500\u2500 index.ts
44467
+ ` : "";
44302
44468
  return `# ${options.templateName} (\`${options.packageId}\`)
44303
44469
 
44304
44470
  ${options.description}
@@ -44314,7 +44480,7 @@ ${options.description}
44314
44480
  \`\`\`text
44315
44481
  \u251C\u2500\u2500 manifest.yaml # \u6A21\u677F\u58F0\u660E\u6E05\u5355\uFF08\u5143\u6570\u636E\u4E0E\u53EF\u9009\u7684\u4EFB\u52A1\uFF09
44316
44482
  \u251C\u2500\u2500 AGENTS.md # \u9879\u76EE\u7EA7\u901A\u7528 AI \u7F16\u7801\u6307\u5BFC\uFF0C\u5B89\u88C5\u65F6\u81EA\u52A8\u590D\u5236\u5230\u9879\u76EE\u6839\u76EE\u5F55
44317
- \u251C\u2500\u2500 skills/ # \u8DE8 IDE \u53EF\u590D\u7528\u7684 Agent Skills\uFF08\u4E00\u9879 Skill \u4E00\u4E2A\u5B50\u76EE\u5F55\uFF09
44483
+ ${projectTree}\u251C\u2500\u2500 skills/ # \u8DE8 IDE \u53EF\u590D\u7528\u7684 Agent Skills\uFF08\u4E00\u9879 Skill \u4E00\u4E2A\u5B50\u76EE\u5F55\uFF09
44318
44484
  \u2502 \u2514\u2500\u2500 example-skill/
44319
44485
  \u2502 \u2514\u2500\u2500 SKILL.md
44320
44486
  \u251C\u2500\u2500 rules/ # IDE \u539F\u751F\u89C4\u5219\u76EE\u5F55
@@ -44325,7 +44491,7 @@ ${options.description}
44325
44491
  \u2502 \u2514\u2500\u2500 mcp.json # \u8FDC\u7AEF Streamable HTTP MCP \u670D\u52A1\u5668\u914D\u7F6E
44326
44492
  \u251C\u2500\u2500 README.md # \u6A21\u677F\u4F7F\u7528\u4E0E\u5F00\u53D1\u6587\u6863
44327
44493
  \u2514\u2500\u2500 package.json # \u6A21\u677F\u5305\u914D\u7F6E
44328
- \`\`\`
44494
+ \`\`\`${projectSection}
44329
44495
 
44330
44496
  ---
44331
44497
 
@@ -44635,7 +44801,7 @@ async function executeExtensionDev(packageDirectory, options) {
44635
44801
  argv.push("--source-type", "local");
44636
44802
  argv.push("--source-path", sourcePath);
44637
44803
  }
44638
- if (options.operation === "remove" && packageId) argv.push("--package", packageId);
44804
+ if (options.operation === "remove" && packageId) argv.push("--template", packageId);
44639
44805
  for (const target of options.target) {
44640
44806
  argv.push("--target", target);
44641
44807
  }
@@ -45989,7 +46155,7 @@ var init_service_locator = __esm({
45989
46155
  });
45990
46156
 
45991
46157
  // packages/cli/src/commands/plan-execution.ts
45992
- import { readFile as readFile30, readdir as readdir10, stat as stat7 } from "node:fs/promises";
46158
+ import { readFile as readFile30, readdir as readdir11, stat as stat7 } from "node:fs/promises";
45993
46159
  import { join as join23, resolve as resolve21 } from "node:path";
45994
46160
  import { createHash as createHash15 } from "node:crypto";
45995
46161
  async function buildIntentsFromPlan(_plan, resolutions, service, projectTargets, _userInstallationKeys, options) {
@@ -46004,9 +46170,15 @@ async function buildIntentsFromPlan(_plan, resolutions, service, projectTargets,
46004
46170
  templateDir: packageRoot,
46005
46171
  projectRoot: service.projectRoot,
46006
46172
  targets: projectTargets.map((t2) => t2.id),
46007
- filter: options?.filter
46173
+ filter: {
46174
+ ...options?.filter,
46175
+ skipProjectDir: options?.skipProjectDir ?? options?.filter?.skipProjectDir
46176
+ }
46008
46177
  });
46009
- intents.push(...contractIntents);
46178
+ intents.push(...contractIntents.map((intent) => ({
46179
+ ...intent,
46180
+ packageId: manifest.id
46181
+ })));
46010
46182
  for (const asset of manifest.assets ?? []) {
46011
46183
  if (options?.skipProjectDir && (asset.source === "project" || asset.source.startsWith("project/"))) {
46012
46184
  options.onDiscloseSkipped?.(`\u8DF3\u8FC7\u8D44\u4EA7 '${asset.source}' (\u7531\u4E8E\u547D\u4EE4\u8BED\u4E49\u4E0D\u4EA4\u4ED8 project \u76EE\u5F55)`);
@@ -46105,7 +46277,7 @@ async function collectAssetIntents(packageRoot, source, destination, metadata) {
46105
46277
  }
46106
46278
  if (!sourceStat.isDirectory()) throw new Error(`Asset '${source}' \u65E2\u4E0D\u662F\u6587\u4EF6\u4E5F\u4E0D\u662F\u76EE\u5F55`);
46107
46279
  const intents = [];
46108
- for (const entry of await readdir10(sourcePath, { withFileTypes: true })) {
46280
+ for (const entry of await readdir11(sourcePath, { withFileTypes: true })) {
46109
46281
  intents.push(...await collectAssetIntents(packageRoot, join23(source, entry.name), join23(destination, entry.name).replaceAll("\\", "/"), metadata));
46110
46282
  }
46111
46283
  return intents;
@@ -46263,6 +46435,7 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46263
46435
  }
46264
46436
  const desiredPackages = [];
46265
46437
  const resolvedPackages = [];
46438
+ const currentPackageIds = new Set(allResolutions.map((r) => r.packageId));
46266
46439
  for (const res of allResolutions) {
46267
46440
  const packageRoot = service?.getPackageRoot(res) ?? process.cwd();
46268
46441
  const contentDigest = await computePackageDigest(packageRoot);
@@ -46285,6 +46458,20 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46285
46458
  ...res.integrity ? { integrity: res.integrity } : {}
46286
46459
  });
46287
46460
  }
46461
+ if (existingLock) {
46462
+ const existingDesired = existingLock.desired?.packages ?? [];
46463
+ const existingResolved = existingLock.resolved?.packages ?? [];
46464
+ for (const ep of existingDesired) {
46465
+ if (!currentPackageIds.has(ep.id)) {
46466
+ desiredPackages.push(ep);
46467
+ }
46468
+ }
46469
+ for (const ep of existingResolved) {
46470
+ if (!currentPackageIds.has(ep.id)) {
46471
+ resolvedPackages.push(ep);
46472
+ }
46473
+ }
46474
+ }
46288
46475
  const resources = /* @__PURE__ */ new Map();
46289
46476
  if (existingLock?.resources) {
46290
46477
  for (const res of existingLock.resources) {
@@ -46293,6 +46480,7 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46293
46480
  }
46294
46481
  }
46295
46482
  for (const intent of intents) {
46483
+ if (intent.assetType === "project-seed") continue;
46296
46484
  if (!intent.target) continue;
46297
46485
  const targetId = typeof intent.target === "string" ? intent.target : intent.target.id;
46298
46486
  const selector = (intent.type === "config-entry" ? intent.selector : intent.type === "managed-section" ? intent.sectionId : null) ?? null;
@@ -46364,6 +46552,15 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46364
46552
  });
46365
46553
  }
46366
46554
  }
46555
+ const mergedTargets = [...targetStrings];
46556
+ if (existingLock?.desired?.targets) {
46557
+ for (const t2 of existingLock.desired.targets) {
46558
+ const tid = typeof t2 === "string" ? t2 : t2.id;
46559
+ if (!mergedTargets.includes(tid)) {
46560
+ mergedTargets.push(tid);
46561
+ }
46562
+ }
46563
+ }
46367
46564
  return {
46368
46565
  apiVersion: "mano-coding/v1",
46369
46566
  kind: "ProjectLock",
@@ -46373,7 +46570,7 @@ async function buildLock(_operation, templateResolution, addonResolutions, proje
46373
46570
  },
46374
46571
  desired: {
46375
46572
  packages: desiredPackages,
46376
- targets: targetStrings
46573
+ targets: mergedTargets
46377
46574
  },
46378
46575
  resolved: {
46379
46576
  packages: resolvedPackages
@@ -46438,7 +46635,8 @@ function toInquirerChoices(choices) {
46438
46635
  return choices.map((choice) => ({
46439
46636
  value: choice,
46440
46637
  name: choice.label ?? choice.id,
46441
- description: choice.description
46638
+ description: choice.description,
46639
+ checked: choice.checked
46442
46640
  }));
46443
46641
  }
46444
46642
  function toContext(options) {
@@ -46743,24 +46941,29 @@ async function confirmPlanInteractive(opts) {
46743
46941
  `);
46744
46942
  }
46745
46943
  }
46746
- process.stderr.write(`
46747
- \u786E\u8BA4\u540E\u5C06\u6267\u884C\u4EE5\u4E0A\u64CD\u4F5C\u3002
46748
- `);
46749
- const confirmed = await readConfirm();
46944
+ process.stderr.write(t("tty.confirmPrompt"));
46945
+ const confirmed = await readConfirm({
46946
+ input: opts.input,
46947
+ output: opts.interactiveOutput
46948
+ });
46750
46949
  if (!confirmed) {
46751
46950
  return { confirmed: false, granted: [], denied: toConfirm };
46752
46951
  }
46753
46952
  return { confirmed: true, granted: requested, denied: [] };
46754
46953
  }
46755
- async function readConfirm() {
46954
+ async function readConfirm(streams) {
46756
46955
  try {
46757
46956
  return await dist_default5(
46758
46957
  {
46759
46958
  message: t("tty.proceedPrompt"),
46760
- default: false
46959
+ default: true
46761
46960
  },
46762
46961
  // 1 分钟无响应超时视为拒绝
46763
- { signal: AbortSignal.timeout(6e4) }
46962
+ {
46963
+ signal: AbortSignal.timeout(6e4),
46964
+ ...streams?.input ? { input: streams.input } : {},
46965
+ ...streams?.output ? { output: streams.output } : {}
46966
+ }
46764
46967
  );
46765
46968
  } catch {
46766
46969
  return false;
@@ -46824,10 +47027,11 @@ import { randomUUID as randomUUID6 } from "node:crypto";
46824
47027
  import { unlink as unlink9 } from "node:fs/promises";
46825
47028
  function createCreateCommand(cliVersion) {
46826
47029
  const cmd = new Command("create");
46827
- cmd.description(t("create.description")).argument("[package-spec]", t("create.argPackageSpec")).argument("[directory]", t("create.argDirectory")).option("--package <package-spec>", t("create.optionPackage"), collectPackage, []).option("--template <package-spec>", t("create.optionTemplate")).option("--addon <package-spec>", t("create.optionAddon"), collectPackage, []).action(async (packageSpec, directory, opts) => {
47030
+ cmd.description(t("create.description")).argument("[template-spec]", t("create.argTemplateSpec")).argument("[directory]", t("create.argDirectory")).option("--template <template-spec>", t("create.optionTemplate"), collectTemplate, []).action(async (templateSpec, directory, opts) => {
47031
+ const templateOptions = Array.isArray(opts.template) ? opts.template : [];
46828
47032
  const options = {
46829
47033
  ...extractMutationOptions(opts),
46830
- packages: Array.isArray(opts.package) ? opts.package : []
47034
+ templates: templateOptions
46831
47035
  };
46832
47036
  const output = {
46833
47037
  json: options.json,
@@ -46837,7 +47041,7 @@ function createCreateCommand(cliVersion) {
46837
47041
  if (options.only || options.skip) {
46838
47042
  reportCliError(
46839
47043
  new CliError(
46840
- "create \u547D\u4EE4\u4E0D\u652F\u6301 --only / --skip \u8D44\u4EA7\u8FC7\u6EE4\uFF0C\u4EE5\u4FDD\u8BC1\u6A21\u677F\u5B8C\u6574\u4EA4\u4ED8\u3002\u5982\u9700\u5B9A\u5236\u53D7\u7BA1\u8D44\u4EA7\u8BF7\u4F7F\u7528 apply \u547D\u4EE4\u3002",
47044
+ t("create.filterUnsupported"),
46841
47045
  ExitCode.SchemaInvalid,
46842
47046
  "UNSUPPORTED_OPTION"
46843
47047
  ),
@@ -46847,27 +47051,21 @@ function createCreateCommand(cliVersion) {
46847
47051
  process.exitCode = ExitCode.SchemaInvalid;
46848
47052
  return;
46849
47053
  }
46850
- const rawPackages = [
46851
- ...Array.isArray(opts.package) ? opts.package : [],
46852
- ...Array.isArray(opts.addon) ? opts.addon : []
46853
- ];
46854
- if (typeof opts.template === "string" && opts.template.trim().length > 0) {
46855
- rawPackages.push(opts.template.trim());
46856
- }
46857
- let effectivePackages = [...rawPackages];
47054
+ const rawTemplates = [...templateOptions];
47055
+ let effectiveTemplates = [...rawTemplates];
46858
47056
  let effectiveDirectory = directory;
46859
- if (rawPackages.length > 0) {
46860
- if (packageSpec && !directory) {
46861
- effectiveDirectory = packageSpec;
47057
+ if (rawTemplates.length > 0) {
47058
+ if (templateSpec && !directory) {
47059
+ effectiveDirectory = templateSpec;
46862
47060
  }
46863
47061
  } else {
46864
- if (packageSpec) {
46865
- effectivePackages.push(packageSpec);
47062
+ if (templateSpec) {
47063
+ effectiveTemplates.push(templateSpec);
46866
47064
  }
46867
47065
  }
46868
47066
  const events = createEventEmitter("create", output);
46869
47067
  const exitCode = await executeCreate(
46870
- effectivePackages,
47068
+ effectiveTemplates,
46871
47069
  effectiveDirectory,
46872
47070
  options,
46873
47071
  cliVersion,
@@ -46885,7 +47083,7 @@ function createCreateCommand(cliVersion) {
46885
47083
  addMutationOptions(cmd);
46886
47084
  return cmd;
46887
47085
  }
46888
- function collectPackage(value, previous = []) {
47086
+ function collectTemplate(value, previous = []) {
46889
47087
  return previous.concat(value);
46890
47088
  }
46891
47089
  async function executeCreate(packageSpecs, directory, options, cliVersion, events) {
@@ -46926,7 +47124,7 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46926
47124
  const allResolutions = [];
46927
47125
  for (const spec of packageSpecs) {
46928
47126
  const resolution = await events.measure("resolve", () => withSpinner(
46929
- `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6269\u5C55\u5305 (${spec})...`,
47127
+ t("template.resolving", spec),
46930
47128
  () => resolvePackageWith(
46931
47129
  service,
46932
47130
  spec,
@@ -46935,8 +47133,8 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46935
47133
  ),
46936
47134
  {
46937
47135
  enabled: spinnerEnabled,
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"})`,
46939
- failText: `\u2716 \u6269\u5C55\u5305\u89E3\u6790\u5931\u8D25: ${spec}`
47136
+ successText: (res) => t("template.resolved", res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? spec, res.manifest.version ?? "0.0.0"),
47137
+ failText: t("template.resolveFailed", spec)
46940
47138
  }
46941
47139
  ), { packageId: spec });
46942
47140
  allResolutions.push(resolution);
@@ -46974,7 +47172,7 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46974
47172
  for (const res of allResolutions) {
46975
47173
  if (existingPkgIds.has(res.manifest.id)) {
46976
47174
  throw new CliError(
46977
- `\u5305 '${res.manifest.id}' \u5DF2\u7ECF\u5B89\u88C5\u5728\u5F53\u524D\u5DE5\u7A0B\u4E2D\u3002\u4E0D\u80FD\u901A\u8FC7 create \u91CD\u65B0\u5B89\u88C5\u3002\u5982\u9700\u66F4\u65B0\u914D\u7F6E\u6216\u540C\u6B65\u8D44\u4EA7\u8BF7\u4F7F\u7528 'apply'\u3001'sync' \u6216 'upgrade' \u547D\u4EE4\u3002`,
47175
+ t("create.templateAlreadyInstalled", res.manifest.id),
46978
47176
  ExitCode.ConflictOrDrift,
46979
47177
  "PACKAGE_ALREADY_INSTALLED"
46980
47178
  );
@@ -46995,20 +47193,19 @@ async function executeCreate(packageSpecs, directory, options, cliVersion, event
46995
47193
  if (options.noInput || options.json || !process.stdin.isTTY) {
46996
47194
  const missing = taskValidation.missingInputs.join(", ");
46997
47195
  throw new CliError(
46998
- `\u5305 '${pkgId}' \u7F3A\u5C11\u521D\u59CB\u5316\u53C2\u6570: ${missing}\uFF0C\u8BF7\u4F7F\u7528\uFF1A
46999
- ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).join("\n")}`,
47196
+ t("create.missingTaskInputs", pkgId, missing, taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).join("\n")),
47000
47197
  ExitCode.NeedsInputOrDenied,
47001
47198
  "INPUT_REQUIRED",
47002
47199
  { inputs: taskValidation.missingInputs }
47003
47200
  );
47004
47201
  }
47005
47202
  for (const missingKey of taskValidation.missingInputs) {
47006
- const val = await dist_default6({ message: `[${pkgId}] \u8BF7\u8F93\u5165\u521D\u59CB\u5316\u53C2\u6570 '${missingKey}':` });
47203
+ const val = await dist_default6({ message: t("create.promptTaskInput", pkgId, missingKey) });
47007
47204
  inputValues[missingKey] = val;
47008
47205
  }
47009
47206
  } else {
47010
47207
  throw new CliError(
47011
- taskValidation.error ?? "\u53C2\u6570\u6821\u9A8C\u5931\u8D25",
47208
+ taskValidation.error ?? t("create.taskValidationFailed"),
47012
47209
  ExitCode.SchemaInvalid,
47013
47210
  "INVALID_OPTIONS"
47014
47211
  );
@@ -47018,7 +47215,9 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47018
47215
  await recoverIncompleteJournals(service, output);
47019
47216
  let cliTargets = options.target;
47020
47217
  if (cliTargets.length === 0) {
47021
- if (isInteractive) {
47218
+ if (existingLock?.desired?.targets && existingLock.desired.targets.length > 0) {
47219
+ cliTargets = existingLock.desired.targets.map((t2) => typeof t2 === "string" ? t2 : t2.id);
47220
+ } else if (isInteractive) {
47022
47221
  try {
47023
47222
  const selected = await selectSearchableMulti({
47024
47223
  message: t("create.chooseTargets"),
@@ -47068,12 +47267,12 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47068
47267
  );
47069
47268
  const userInstallationKeys = /* @__PURE__ */ new Set();
47070
47269
  let staticIntents = await withSpinner(
47071
- "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
47270
+ t("create.computingPlan"),
47072
47271
  () => buildIntentsFromPlan(planResult.plan, allResolutions, service, projectTargets, userInstallationKeys),
47073
47272
  {
47074
47273
  enabled: spinnerEnabled,
47075
- successText: (res) => `\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 ${res.length} \u9879\u8D44\u6E90\u53D8\u66F4)`,
47076
- failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
47274
+ successText: (res) => t("create.planReady", res.length),
47275
+ failText: t("create.planFailed")
47077
47276
  }
47078
47277
  );
47079
47278
  planResult = materializePlan(planResult.plan, staticIntents);
@@ -47172,7 +47371,7 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47172
47371
  operation: "create",
47173
47372
  version: resolution.manifest.version
47174
47373
  };
47175
- const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u521B\u5EFA\u4EFB\u52A1 (before:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47374
+ const title = t("task.runningBeforeCreate", pkgIdx + 1, allResolutions.length, resolution.manifest.id);
47176
47375
  try {
47177
47376
  await runTasksWithDynamicUI(pkgTasks, taskContext, {
47178
47377
  title,
@@ -47273,7 +47472,7 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47273
47472
  );
47274
47473
  if (!output.json && userInstallationKeys.size > 0) writeHumanOutput(t("create.userToolsInstalled", formatElapsed(userInstallationStartedAt)));
47275
47474
  addRollback(userLifecycle.rollback);
47276
- const lock = await buildLock("create", templateResolution, addonResolutions, projectTargets, planResult.plan, service.cliVersion, inputValues, service, intents, userInstallationKeys);
47475
+ const lock = await buildLock("create", templateResolution, addonResolutions, projectTargets, planResult.plan, service.cliVersion, inputValues, service, intents, userInstallationKeys, void 0, existingLock);
47277
47476
  await lockRepo.write(lock);
47278
47477
  addRollback(async () => previousLock ? lockRepo.write(previousLock) : unlink9(lockRepo.path).catch(() => void 0));
47279
47478
  await userLifecycle.addReferences(lock);
@@ -47296,7 +47495,7 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47296
47495
  operation: "create",
47297
47496
  version: resolution.manifest.version
47298
47497
  };
47299
- const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u521D\u59CB\u5316\u4EFB\u52A1 (after:create) [${pkgIdx + 1}/${allResolutions.length}] (${resolution.manifest.id}):`;
47498
+ const title = t("task.runningAfterCreate", pkgIdx + 1, allResolutions.length, resolution.manifest.id);
47300
47499
  try {
47301
47500
  await runTasksWithDynamicUI(pkgTasks, taskContext, {
47302
47501
  title,
@@ -47327,18 +47526,14 @@ ${taskValidation.missingInputs.map((k2) => `--input ${pkgId}:${k2}=<value>`).joi
47327
47526
  });
47328
47527
  }
47329
47528
  function formatElapsed(startedAt) {
47330
- return `${((Date.now() - startedAt) / 1e3).toFixed(1)} \u79D2`;
47529
+ return t("common.seconds", ((Date.now() - startedAt) / 1e3).toFixed(1));
47331
47530
  }
47332
47531
  function writeUserInstallationProgress(progress) {
47333
47532
  const name = progress.displayName ?? `${progress.packageId}/${progress.capabilityId}`;
47334
- if (progress.status === "installing") writeHumanOutput(`\u6B63\u5728\u5B89\u88C5\uFF1A${name}
47335
- `);
47336
- else if (progress.status === "installed") writeHumanOutput(`\u2713 \u5DF2\u5B89\u88C5\uFF1A${name}
47337
- `);
47338
- else if (progress.status === "reused") writeHumanOutput(`\u2713 \u5DF2\u590D\u7528\uFF1A${name}
47339
- `);
47340
- else writeHumanOutput(`- \u65E0\u9700\u5B89\u88C5\uFF1A${name}
47341
- `);
47533
+ if (progress.status === "installing") writeHumanOutput(t("create.installing", name));
47534
+ else if (progress.status === "installed") writeHumanOutput(t("create.installed", name));
47535
+ else if (progress.status === "reused") writeHumanOutput(t("create.reused", name));
47536
+ else writeHumanOutput(t("create.skipped", name));
47342
47537
  }
47343
47538
  async function resolvePackageWith(service, spec, options, cliVersion) {
47344
47539
  const req = {
@@ -47391,7 +47586,7 @@ import { unlink as unlink10 } from "node:fs/promises";
47391
47586
  import { randomUUID as randomUUID7 } from "node:crypto";
47392
47587
  function createApplyCommand(cliVersion) {
47393
47588
  const cmd = new Command("apply");
47394
- cmd.description("Apply a template to an existing project").argument("[package-spec]", "Template spec (required if no project lock)").action(async (packageSpec, opts) => {
47589
+ cmd.description(t("apply.description")).argument("[template-spec]", t("apply.argTemplateSpec")).option("--template <template-spec>", t("apply.optionTemplate")).action(async (templateSpecArg, opts) => {
47395
47590
  const options = extractMutationOptions(opts);
47396
47591
  const output = {
47397
47592
  json: options.json,
@@ -47399,7 +47594,8 @@ function createApplyCommand(cliVersion) {
47399
47594
  noColor: options.noColor
47400
47595
  };
47401
47596
  const events = createEventEmitter("apply", output);
47402
- const exitCode = await executeApply(packageSpec, options, cliVersion, events).catch(
47597
+ const templateSpec = (typeof opts.template === "string" ? opts.template : void 0) ?? (typeof templateSpecArg === "string" ? templateSpecArg : void 0);
47598
+ const exitCode = await executeApply(templateSpec, options, cliVersion, events).catch(
47403
47599
  (err) => reportCliError(err, "apply", output, options.json && options.verbose ? getRedactedEvents(events) : void 0)
47404
47600
  );
47405
47601
  if (exitCode !== 0) {
@@ -47409,7 +47605,7 @@ function createApplyCommand(cliVersion) {
47409
47605
  addMutationOptions(cmd);
47410
47606
  return cmd;
47411
47607
  }
47412
- async function executeApply(packageSpec, options, cliVersion, events) {
47608
+ async function executeApply(templateSpec, options, cliVersion, events) {
47413
47609
  const output = {
47414
47610
  json: options.json,
47415
47611
  verbose: options.verbose,
@@ -47417,13 +47613,6 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47417
47613
  };
47418
47614
  const jsonEvents = () => options.json && options.verbose ? getRedactedEvents(events) : void 0;
47419
47615
  const isInteractive = !options.noInput && !options.json && Boolean(process.stdin.isTTY);
47420
- if (!packageSpec) {
47421
- throw new CliError(
47422
- t("apply.packageRequired"),
47423
- ExitCode.SchemaInvalid,
47424
- "PACKAGE_SPEC_REQUIRED"
47425
- );
47426
- }
47427
47616
  if (options.only && options.skip) {
47428
47617
  throw new CliError(
47429
47618
  t("apply.onlySkipExclusive"),
@@ -47485,28 +47674,72 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47485
47674
  const spinnerEnabled = !output.json && Boolean(process.stdout.isTTY) && process.env.NODE_ENV !== "test";
47486
47675
  if (existingLock) {
47487
47676
  const existing = await withSpinner(
47488
- "\u6B63\u5728\u4ECE\u9501\u5B9A\u6587\u4EF6\u89E3\u6790\u5DF2\u5B89\u88C5\u5305...",
47677
+ t("template.resolving", "lock"),
47489
47678
  () => resolveLockedPackages(existingLock, service),
47490
47679
  {
47491
47680
  enabled: spinnerEnabled,
47492
- successText: "\u2714 \u5DF2\u52A0\u8F7D\u9501\u5B9A\u914D\u7F6E"
47681
+ successText: t("apply.lockedConfigLoaded")
47493
47682
  }
47494
47683
  );
47495
47684
  templateResolution = existing.template;
47496
47685
  addonResolutions = existing.addons;
47497
47686
  }
47687
+ let effectiveTemplateSpec = templateSpec;
47688
+ if (!effectiveTemplateSpec) {
47689
+ if (!isInteractive) {
47690
+ throw new CliError(
47691
+ t("apply.templateRequired"),
47692
+ ExitCode.SchemaInvalid,
47693
+ "PACKAGE_SPEC_REQUIRED"
47694
+ );
47695
+ }
47696
+ const client = service.getRegistryClient();
47697
+ if (!client.getIndex) {
47698
+ throw new CliError(t("create.registryIndexUnsupported"), ExitCode.ResolveFailed, "REGISTRY_INDEX_UNSUPPORTED");
47699
+ }
47700
+ const indexResult = await client.getIndex({ offline: options.offline });
47701
+ const installedIds = /* @__PURE__ */ new Set();
47702
+ if (existingLock) {
47703
+ for (const p2 of existingLock.desired?.packages ?? []) installedIds.add(p2.id);
47704
+ for (const p2 of existingLock.resolved?.packages ?? []) installedIds.add(p2.id);
47705
+ if (existingLock.desired?.template?.id) installedIds.add(existingLock.desired.template.id);
47706
+ for (const t2 of existingLock.desired?.templates ?? []) installedIds.add(t2.id);
47707
+ for (const a of existingLock.desired?.addons ?? []) installedIds.add(a.id);
47708
+ if (existingLock.resolved?.template?.id) installedIds.add(existingLock.resolved.template.id);
47709
+ for (const t2 of existingLock.resolved?.templates ?? []) installedIds.add(t2.id);
47710
+ for (const a of existingLock.resolved?.addons ?? []) installedIds.add(a.id);
47711
+ }
47712
+ const availableChoices = indexResult.packages.filter((entry) => !installedIds.has(entry.id)).map((entry) => ({
47713
+ id: entry.id,
47714
+ label: entry.name ?? entry.displayName ?? entry.id,
47715
+ description: entry.description ?? "",
47716
+ tags: entry.tags ?? []
47717
+ }));
47718
+ if (availableChoices.length === 0) {
47719
+ throw new CliError(t("apply.noAvailableTemplates"), ExitCode.NeedsInputOrDenied, "NO_TEMPLATES_AVAILABLE");
47720
+ }
47721
+ try {
47722
+ const chosen = await selectSearchable({ message: t("apply.chooseTemplate"), choices: availableChoices });
47723
+ effectiveTemplateSpec = chosen.id;
47724
+ } catch (error) {
47725
+ if (error instanceof SearchableSelectCancelled) {
47726
+ throw new CliError(t("apply.templateSelectionCancelled"), ExitCode.NeedsInputOrDenied, "PERMISSION_DENIED");
47727
+ }
47728
+ throw error;
47729
+ }
47730
+ }
47498
47731
  const newAddonResolution = await withSpinner(
47499
- `\u6B63\u5728\u62C9\u53D6\u5E76\u89E3\u6790\u6A21\u677F (${packageSpec})...`,
47732
+ t("template.resolving", effectiveTemplateSpec),
47500
47733
  () => resolvePackageWith2(
47501
47734
  service,
47502
- packageSpec,
47735
+ effectiveTemplateSpec,
47503
47736
  options,
47504
47737
  cliVersion
47505
47738
  ),
47506
47739
  {
47507
47740
  enabled: spinnerEnabled,
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}`
47741
+ successText: (res) => t("template.resolved", res.manifest.displayName ?? res.manifest.name ?? res.manifest.id ?? effectiveTemplateSpec, res.manifest.version ?? "0.0.0"),
47742
+ failText: t("template.resolveFailed", effectiveTemplateSpec)
47510
47743
  }
47511
47744
  );
47512
47745
  addonResolutions = [...addonResolutions.filter((resolution) => resolution.packageId !== newAddonResolution.packageId), newAddonResolution];
@@ -47536,24 +47769,31 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47536
47769
  }
47537
47770
  let cliTargets = options.target;
47538
47771
  if (cliTargets.length === 0) {
47539
- if (existingLock?.desired.targets && existingLock.desired.targets.length > 0) {
47540
- cliTargets = existingLock.desired.targets.map((t2) => typeof t2 === "string" ? t2 : t2.id);
47541
- } else if (isInteractive) {
47772
+ if (isInteractive) {
47773
+ const existingTargetIds = new Set(
47774
+ (existingLock?.desired.targets ?? []).map((t2) => typeof t2 === "string" ? t2 : t2.id)
47775
+ );
47776
+ const choices = OFFICIAL_TARGET_CHOICES.map((choice) => ({
47777
+ ...choice,
47778
+ checked: existingTargetIds.size > 0 ? existingTargetIds.has(choice.id) : void 0
47779
+ }));
47542
47780
  try {
47543
47781
  const selected = await selectSearchableMulti({
47544
- message: t("create.chooseTargets"),
47545
- choices: OFFICIAL_TARGET_CHOICES
47782
+ message: t("apply.chooseTargets"),
47783
+ choices
47546
47784
  });
47547
47785
  if (selected.length === 0) {
47548
- throw new CliError(t("create.targetSelectionCancelled"), ExitCode.NeedsInputOrDenied, "PERMISSION_DENIED");
47786
+ throw new CliError(t("apply.targetSelectionCancelled"), ExitCode.NeedsInputOrDenied, "PERMISSION_DENIED");
47549
47787
  }
47550
47788
  cliTargets = selected.map((choice) => choice.id);
47551
47789
  } catch (error) {
47552
47790
  if (error instanceof SearchableSelectCancelled) {
47553
- throw new CliError(t("create.targetSelectionCancelled"), ExitCode.NeedsInputOrDenied, "PERMISSION_DENIED");
47791
+ throw new CliError(t("apply.targetSelectionCancelled"), ExitCode.NeedsInputOrDenied, "PERMISSION_DENIED");
47554
47792
  }
47555
47793
  throw error;
47556
47794
  }
47795
+ } else if (existingLock?.desired.targets && existingLock.desired.targets.length > 0) {
47796
+ cliTargets = existingLock.desired.targets.map((t2) => typeof t2 === "string" ? t2 : t2.id);
47557
47797
  } else {
47558
47798
  cliTargets = ["codebuddy"];
47559
47799
  }
@@ -47573,7 +47813,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47573
47813
  );
47574
47814
  const userInstallationKeys = /* @__PURE__ */ new Set();
47575
47815
  const intents = await withSpinner(
47576
- "\u6B63\u5728\u8BA1\u7B97\u53D7\u7BA1\u8D44\u6E90\u5E76\u751F\u6210\u6267\u884C\u8BA1\u5212...",
47816
+ t("apply.computingPlan"),
47577
47817
  () => buildIntentsFromPlan(
47578
47818
  planResult.plan,
47579
47819
  packagesToApply,
@@ -47581,7 +47821,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47581
47821
  projectTargets,
47582
47822
  userInstallationKeys,
47583
47823
  {
47584
- filter: { only: onlyTypes, skip: skipTypes },
47824
+ filter: { only: onlyTypes, skip: skipTypes, skipProjectDir: true },
47585
47825
  skipProjectDir: true,
47586
47826
  onDiscloseSkipped: (msg) => {
47587
47827
  if (!output.json) writeHumanOutput(`- ${msg}
@@ -47591,8 +47831,8 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47591
47831
  ),
47592
47832
  {
47593
47833
  enabled: spinnerEnabled,
47594
- successText: (res) => `\u2714 \u6267\u884C\u8BA1\u5212\u5DF2\u5C31\u7EEA (\u5171 ${res.length} \u9879\u8D44\u6E90\u53D8\u66F4)`,
47595
- failText: "\u2716 \u6267\u884C\u8BA1\u5212\u751F\u6210\u5931\u8D25"
47834
+ successText: (res) => t("apply.planReady", res.length),
47835
+ failText: t("apply.planFailed")
47596
47836
  }
47597
47837
  );
47598
47838
  if (existingLock?.resources) {
@@ -47609,7 +47849,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47609
47849
  }
47610
47850
  if (newDigest && matched.hash && newDigest !== matched.hash) {
47611
47851
  throw new CliError(
47612
- `\u8D44\u6E90 '${intent.path}' \u4E0E\u5DF2\u6709\u6A21\u677F\u8D44\u6E90\u5B58\u5728\u51B2\u7A81`,
47852
+ t("apply.resourceConflict", intent.path),
47613
47853
  ExitCode.ConflictOrDrift,
47614
47854
  "PLAN_CONFLICT"
47615
47855
  );
@@ -47623,8 +47863,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47623
47863
  ...filterTasksByHook2(newAddonResolution.manifest.tasks ?? [], "after:create")
47624
47864
  ];
47625
47865
  if (skippedCreateTasks.length > 0 && !output.json) {
47626
- writeHumanOutput(`- \u5DF2\u8DF3\u8FC7 ${skippedCreateTasks.length} \u4E2A create \u751F\u547D\u5468\u671F\u94A9\u5B50\u4EFB\u52A1\uFF08apply \u8BED\u4E49\u4E0D\u6267\u884C before:create / after:create \u94A9\u5B50\uFF09
47627
- `);
47866
+ writeHumanOutput(t("apply.skippedCreateTasks", skippedCreateTasks.length));
47628
47867
  }
47629
47868
  const beforeApplyTasksForCheck = filterTasksByHook2(newAddonResolution.manifest.tasks ?? [], "before:apply");
47630
47869
  const afterApplyTasksForCheck = filterTasksByHook2(newAddonResolution.manifest.tasks ?? [], "after:apply");
@@ -47642,7 +47881,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47642
47881
  if (existingResolved.version === newAddonResolution.resolvedVersion && existingResolved.integrity && newAddonResolution.integrity) {
47643
47882
  if (existingResolved.integrity !== newAddonResolution.integrity) {
47644
47883
  throw new CliError(
47645
- `\u5305 '${newAddonResolution.packageId}' \u7248\u672C\u76F8\u540C\u4F46\u5185\u5BB9\u5DF2\u66F4\u65B0\uFF0C\u8BF7\u4F7F\u7528 upgrade \u547D\u4EE4\u8FDB\u884C\u66F4\u65B0`,
47884
+ t("apply.templateUpdatedNeedsUpgrade", newAddonResolution.packageId),
47646
47885
  ExitCode.ConflictOrDrift,
47647
47886
  "PACKAGE_UPDATE_REQUIRES_UPGRADE"
47648
47887
  );
@@ -47651,9 +47890,9 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47651
47890
  const hasChanges = planResult.plan.files.length > 0 || planResult.plan.configEntries.length > 0 || planResult.plan.managedSections.length > 0 || planResult.plan.plugins.length > 0 || planResult.plan.userInstallations.length > 0;
47652
47891
  if (sameAssetTypes && !hasChanges) {
47653
47892
  if (output.json) {
47654
- emitSuccessJson("apply", { dryRun: false, message: "\u5DF2\u5E94\u7528\uFF0C\u65E0\u53D8\u5316", lockPath: lockRepo.path }, [], [], jsonEvents());
47893
+ emitSuccessJson("apply", { dryRun: false, message: t("apply.alreadyUpToDate"), lockPath: lockRepo.path }, [], [], jsonEvents());
47655
47894
  } else {
47656
- writeHumanOutput("\u5DF2\u5E94\u7528\uFF0C\u65E0\u53D8\u5316\n");
47895
+ writeHumanOutput(t("apply.alreadyUpToDate") + "\n");
47657
47896
  }
47658
47897
  return ExitCode.Success;
47659
47898
  }
@@ -47758,7 +47997,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47758
47997
  };
47759
47998
  try {
47760
47999
  await runTasksWithDynamicUI([task], taskContext, {
47761
- title: i === 0 ? "\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5E94\u7528\u4EFB\u52A1 (before:apply):" : void 0,
48000
+ title: i === 0 ? t("task.runningBeforeApply", 1, 1, newAddonResolution.packageId) : void 0,
47762
48001
  verbose: options.verbose,
47763
48002
  json: options.json
47764
48003
  });
@@ -47836,7 +48075,7 @@ async function executeApply(packageSpec, options, cliVersion, events) {
47836
48075
  };
47837
48076
  try {
47838
48077
  await runTasksWithDynamicUI([task], taskContext, {
47839
- title: i === 0 ? "\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5E94\u7528\u4EFB\u52A1 (after:apply):" : void 0,
48078
+ title: i === 0 ? t("task.runningAfterApply", 1, 1, newAddonResolution.packageId) : void 0,
47840
48079
  verbose: options.verbose,
47841
48080
  json: options.json
47842
48081
  });
@@ -47910,10 +48149,10 @@ import { randomUUID as randomUUID8 } from "node:crypto";
47910
48149
  import { basename as basename5, dirname as dirname17, resolve as resolve22 } from "node:path";
47911
48150
  function createSyncCommand(cliVersion) {
47912
48151
  const cmd = new Command("sync");
47913
- cmd.description(t("sync.description")).option("--package <packageId>", "\u4EC5\u540C\u6B65\u6307\u5B9A\u7684\u5DF2\u5B89\u88C5\u5305").action(async (opts) => {
48152
+ cmd.description(t("sync.description")).option("--template <templateId>", t("sync.optionTemplate")).action(async (opts) => {
47914
48153
  const options = extractMutationOptions(opts);
47915
- if (typeof opts.package === "string") {
47916
- options.package = opts.package;
48154
+ if (typeof opts.template === "string") {
48155
+ options.template = opts.template;
47917
48156
  }
47918
48157
  const output = {
47919
48158
  json: options.json,
@@ -47958,11 +48197,11 @@ async function executeSync(options, cliVersion, silent = false, events = new Lif
47958
48197
  }
47959
48198
  const locked = await events.measure("resolve", () => resolveLockedPackages(lock, service));
47960
48199
  let allResolutions = [...locked.template ? [locked.template] : [], ...locked.addons];
47961
- if (options.package) {
47962
- allResolutions = allResolutions.filter((r) => r.packageId === options.package);
48200
+ if (options.template) {
48201
+ allResolutions = allResolutions.filter((r) => r.packageId === options.template);
47963
48202
  if (allResolutions.length === 0) {
47964
48203
  throw new CliError(
47965
- `\u672A\u5728 Lock \u6587\u4EF6\u4E2D\u627E\u5230\u5305 '${options.package}'\u3002\u8BE5\u5305\u672A\u5B89\u88C5\u6216\u65E0\u6CD5\u540C\u6B65\u3002`,
48204
+ t("sync.templateNotFound", options.template),
47966
48205
  ExitCode.SchemaInvalid,
47967
48206
  "PACKAGE_NOT_FOUND"
47968
48207
  );
@@ -48311,7 +48550,7 @@ import { unlink as unlink11, readFile as readFile31 } from "node:fs/promises";
48311
48550
  import { basename as basename6, dirname as dirname18, join as join24, resolve as resolve23 } from "node:path";
48312
48551
  function createRemoveCommand(cliVersion) {
48313
48552
  const cmd = new Command("remove");
48314
- cmd.description(t("remove.description")).option("--package <package-id>", t("remove.optionPackage")).action(async (opts) => {
48553
+ cmd.description(t("remove.description")).argument("[template-id]", t("remove.argTemplate")).option("--template <template-id>", t("remove.optionTemplate")).action(async (templateArg, opts) => {
48315
48554
  const options = extractMutationOptions(opts);
48316
48555
  const output = {
48317
48556
  json: options.json,
@@ -48319,8 +48558,8 @@ function createRemoveCommand(cliVersion) {
48319
48558
  noColor: options.noColor
48320
48559
  };
48321
48560
  const events = createEventEmitter("remove", output);
48322
- const packageId = typeof opts.package === "string" ? opts.package : void 0;
48323
- const exitCode = await executeRemove(packageId, options, cliVersion, events).catch(
48561
+ const templateId = (typeof opts.template === "string" ? opts.template : void 0) ?? (typeof templateArg === "string" ? templateArg : void 0);
48562
+ const exitCode = await executeRemove(templateId, options, cliVersion, events).catch(
48324
48563
  (err) => reportCliError(err, "remove", output, options.json && options.verbose ? getRedactedEvents(events) : void 0)
48325
48564
  );
48326
48565
  if (exitCode !== 0) {
@@ -48330,7 +48569,7 @@ function createRemoveCommand(cliVersion) {
48330
48569
  addMutationOptions(cmd);
48331
48570
  return cmd;
48332
48571
  }
48333
- async function executeRemove(packageId, options, cliVersion, events) {
48572
+ async function executeRemove(templateId, options, cliVersion, events) {
48334
48573
  const output = {
48335
48574
  json: options.json,
48336
48575
  verbose: options.verbose,
@@ -48356,47 +48595,56 @@ async function executeRemove(packageId, options, cliVersion, events) {
48356
48595
  "LOCK_NOT_FOUND"
48357
48596
  );
48358
48597
  }
48359
- if (packageId) {
48360
- const allPackages = [
48598
+ if (templateId) {
48599
+ const allTemplates = [
48361
48600
  ...lock.desired?.packages ? lock.desired.packages.map((p2) => p2.id) : [],
48362
48601
  ...lock.resolved?.packages ? lock.resolved.packages.map((p2) => p2.id) : [],
48363
48602
  ...lock.resolved.template ? [lock.resolved.template.id] : [],
48364
48603
  ...lock.resolved.templates ? lock.resolved.templates.map((t2) => t2.id) : [],
48365
48604
  ...lock.resolved.addons ? lock.resolved.addons.map((a) => a.id) : []
48366
48605
  ];
48367
- if (!allPackages.includes(packageId)) {
48368
- if (lock.createdWith?.packages?.some((p2) => p2.packageId === packageId)) {
48606
+ if (!allTemplates.includes(templateId)) {
48607
+ if (lock.createdWith?.packages?.some((p2) => p2.packageId === templateId)) {
48369
48608
  throw new CliError(
48370
- `\u5305 '${packageId}' \u662F\u9879\u76EE\u7684\u521D\u59CB\u5DE5\u7A0B\u6A21\u677F (bootstrap-only)\uFF0C\u4E0D\u5305\u542B\u53D7\u7BA1\u77E5\u8BC6\u8D44\u4EA7\uFF0C\u65E0\u6CD5\u88AB remove\u3002\u82E5\u9700\u5220\u9664\u6574\u4E2A\u9879\u76EE\uFF0C\u8BF7\u76F4\u63A5\u5220\u9664\u9879\u76EE\u76EE\u5F55\u3002`,
48609
+ t("remove.bootstrapTemplateCannotBeRemoved", templateId),
48371
48610
  ExitCode.SchemaInvalid,
48372
48611
  "BOOTSTRAP_PACKAGE_CANNOT_BE_REMOVED"
48373
48612
  );
48374
48613
  }
48375
48614
  throw new CliError(
48376
- t("remove.packageNotInLock", packageId, allPackages.join(", ") || "none"),
48615
+ t("remove.templateNotInLock", templateId, allTemplates.join(", ") || "none"),
48377
48616
  ExitCode.SchemaInvalid,
48378
48617
  "PACKAGE_NOT_IN_LOCK",
48379
- { packageId, available: allPackages }
48618
+ { templateId, available: allTemplates }
48380
48619
  );
48381
48620
  }
48382
48621
  }
48383
48622
  events.report("resolve", "success", Date.now() - resolveStartedAt, {
48384
48623
  details: { packageCount: (lock.resolved.template ? 1 : 0) + (lock.resolved.addons?.length ?? 0) }
48385
48624
  });
48625
+ const ownerMatches = (owner) => !templateId || owner.packageId === templateId;
48626
+ const intents = lock.resources.filter((resource) => resource.owners.every(ownerMatches)).map((resource) => {
48627
+ const targetId = typeof resource.target === "string" ? resource.target : resource.target?.id;
48628
+ const metadata = { target: targetId, packageId: resource.owners[0]?.packageId };
48629
+ if (resource.type === "file" || !resource.type) return { action: "remove", type: "file", path: resource.path, ...metadata };
48630
+ if (resource.type === "managed-section") return { action: "remove", type: "managed-section", path: resource.path, sectionId: resource.sectionId ?? resource.selector ?? "", ...metadata };
48631
+ return { action: "remove", type: "config-entry", path: resource.path, selector: resource.selector ?? "", format: resource.format ?? "json", ...metadata };
48632
+ });
48386
48633
  const planStartedAt = Date.now();
48387
48634
  const planBuilder = service.getPlanBuilder();
48388
48635
  const projectTargets = lock.desired.targets.map((t2) => typeof t2 === "string" ? { id: t2, scope: "project" } : t2);
48389
- const planResult = planBuilder.build(
48636
+ let planResult = planBuilder.build(
48390
48637
  "remove",
48391
48638
  service.projectRoot,
48392
48639
  [],
48393
48640
  projectTargets
48394
48641
  );
48642
+ planResult = materializePlan(planResult.plan, intents);
48395
48643
  events.report("plan", "success", Date.now() - planStartedAt, { planDigest: planResult.plan.planDigest });
48396
48644
  const driftDetector = new DriftDetector({ projectRoot: service.projectRoot, driftMode: options.drift });
48397
48645
  const drift = await driftDetector.detect(lock);
48398
48646
  if (driftDetector.shouldAbort(drift)) {
48399
- throw new CliError(`\u68C0\u6D4B\u5230 ${drift.length} \u9879\u8D44\u6E90\u6F02\u79FB\uFF1B\u5982\u786E\u8BA4\u5220\u9664\u5DF2\u4FEE\u6539\u5185\u5BB9\uFF0C\u8BF7\u4F7F\u7528 --drift accept`, ExitCode.ConflictOrDrift, "RESOURCE_DRIFT", { drift });
48647
+ throw new CliError(t("remove.driftDetected", drift.length), ExitCode.ConflictOrDrift, "RESOURCE_DRIFT", { drift });
48400
48648
  }
48401
48649
  if (!options.dryRun && !options.yes) {
48402
48650
  if (options.noInput || !process.stdin.isTTY) {
@@ -48455,23 +48703,15 @@ async function executeRemove(packageId, options, cliVersion, events) {
48455
48703
  }
48456
48704
  return ExitCode.Success;
48457
48705
  }
48458
- const ownerMatches = (owner) => !packageId || owner.packageId === packageId;
48459
- const intents = lock.resources.filter((resource) => resource.owners.every(ownerMatches)).map((resource) => {
48460
- const targetId = typeof resource.target === "string" ? resource.target : resource.target?.id;
48461
- const metadata = { target: targetId, packageId: resource.owners[0]?.packageId };
48462
- if (resource.type === "file" || !resource.type) return { action: "remove", type: "file", path: resource.path, ...metadata };
48463
- if (resource.type === "managed-section") return { action: "remove", type: "managed-section", path: resource.path, sectionId: resource.sectionId ?? resource.selector ?? "", ...metadata };
48464
- return { action: "remove", type: "config-entry", path: resource.path, selector: resource.selector ?? "", format: resource.format ?? "json", ...metadata };
48465
- });
48466
- const packagesToRemove = packageId ? [packageId] : [
48706
+ const templatesToRemove = templateId ? [templateId] : [
48467
48707
  ...lock.desired?.packages ? lock.desired.packages.map((p2) => p2.id) : [],
48468
48708
  ...lock.resolved?.packages ? lock.resolved.packages.map((p2) => p2.id) : [],
48469
48709
  ...lock.resolved.template ? [lock.resolved.template.id] : [],
48470
48710
  ...lock.resolved.addons ? lock.resolved.addons.map((a) => a.id) : []
48471
48711
  ];
48472
- const uniquePackagesToRemove = [...new Set(packagesToRemove)];
48473
- const packageManifests = [];
48474
- for (const pkg of uniquePackagesToRemove) {
48712
+ const uniqueTemplatesToRemove = [...new Set(templatesToRemove)];
48713
+ const templateManifests = [];
48714
+ for (const pkg of uniqueTemplatesToRemove) {
48475
48715
  const resolved = lock.resolved?.packages?.find((p2) => p2.id === pkg) ?? (lock.resolved?.template?.id === pkg ? lock.resolved.template : void 0);
48476
48716
  const desired = lock.desired?.packages?.find((p2) => p2.id === pkg) ?? (lock.desired?.template?.id === pkg ? lock.desired.template : void 0);
48477
48717
  let templateDir;
@@ -48488,8 +48728,8 @@ async function executeRemove(packageId, options, cliVersion, events) {
48488
48728
  const manifestContent = await readFile31(join24(templateDir, "manifest.yaml"), "utf-8");
48489
48729
  const parsed = parseManifest(manifestContent);
48490
48730
  if (parsed.manifest) {
48491
- packageManifests.push({
48492
- packageId: pkg,
48731
+ templateManifests.push({
48732
+ templateId: pkg,
48493
48733
  manifest: parsed.manifest,
48494
48734
  templateDir,
48495
48735
  inputs: Object.fromEntries(Object.entries(desired?.inputs ?? {}).map(([k2, v2]) => [k2, String(v2)]))
@@ -48498,8 +48738,8 @@ async function executeRemove(packageId, options, cliVersion, events) {
48498
48738
  } catch {
48499
48739
  }
48500
48740
  }
48501
- for (let pkgIdx = 0; pkgIdx < packageManifests.length; pkgIdx++) {
48502
- const item = packageManifests[pkgIdx];
48741
+ for (let pkgIdx = 0; pkgIdx < templateManifests.length; pkgIdx++) {
48742
+ const item = templateManifests[pkgIdx];
48503
48743
  const pkgTasks = filterTasksByHook(item.manifest.tasks ?? [], "before:remove");
48504
48744
  if (pkgTasks.length > 0) {
48505
48745
  const taskContext = {
@@ -48513,7 +48753,7 @@ async function executeRemove(packageId, options, cliVersion, events) {
48513
48753
  operation: "remove",
48514
48754
  version: item.manifest.version
48515
48755
  };
48516
- const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u79FB\u9664\u4EFB\u52A1 (before:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):`;
48756
+ const title = t("task.runningBeforeRemove", pkgIdx + 1, templateManifests.length, item.templateId);
48517
48757
  try {
48518
48758
  await runTasksWithDynamicUI(pkgTasks, taskContext, {
48519
48759
  title,
@@ -48544,36 +48784,36 @@ async function executeRemove(packageId, options, cliVersion, events) {
48544
48784
  }
48545
48785
  events.report("execute", "success", Date.now() - executeStartedAt, { planDigest: planResult.plan.planDigest, details: { intentCount: intents.length } });
48546
48786
  const remainingLock = structuredClone(lock);
48547
- if (packageId) {
48548
- if (remainingLock.desired.packages) remainingLock.desired.packages = remainingLock.desired.packages.filter((item) => item.id !== packageId);
48549
- if (remainingLock.resolved.packages) remainingLock.resolved.packages = remainingLock.resolved.packages.filter((item) => item.id !== packageId);
48550
- if (remainingLock.desired.template?.id === packageId) delete remainingLock.desired.template;
48551
- if (remainingLock.resolved.template?.id === packageId) delete remainingLock.resolved.template;
48552
- if (remainingLock.desired.templates) remainingLock.desired.templates = remainingLock.desired.templates.filter((item) => item.id !== packageId);
48553
- if (remainingLock.resolved.templates) remainingLock.resolved.templates = remainingLock.resolved.templates.filter((item) => item.id !== packageId);
48554
- if (remainingLock.desired.addons) remainingLock.desired.addons = remainingLock.desired.addons.filter((item) => item.id !== packageId);
48555
- if (remainingLock.resolved.addons) remainingLock.resolved.addons = remainingLock.resolved.addons.filter((item) => item.id !== packageId);
48556
- if (remainingLock.desired.capabilities) remainingLock.desired.capabilities = remainingLock.desired.capabilities.filter((item) => item.packageId !== packageId);
48557
- if (remainingLock.resolved.projects) remainingLock.resolved.projects = remainingLock.resolved.projects.filter((item) => item.packageId !== packageId);
48558
- if (remainingLock.resolved.capabilities) remainingLock.resolved.capabilities = remainingLock.resolved.capabilities.filter((item) => item.packageId !== packageId);
48559
- if (remainingLock.resolved.plugins) remainingLock.resolved.plugins = remainingLock.resolved.plugins.filter((item) => item.packageId !== packageId);
48560
- remainingLock.resources = remainingLock.resources.map((resource) => ({ ...resource, owners: resource.owners.filter((owner) => owner.packageId !== packageId) })).filter((resource) => resource.owners.length > 0);
48787
+ if (templateId) {
48788
+ if (remainingLock.desired.packages) remainingLock.desired.packages = remainingLock.desired.packages.filter((item) => item.id !== templateId);
48789
+ if (remainingLock.resolved.packages) remainingLock.resolved.packages = remainingLock.resolved.packages.filter((item) => item.id !== templateId);
48790
+ if (remainingLock.desired.template?.id === templateId) delete remainingLock.desired.template;
48791
+ if (remainingLock.resolved.template?.id === templateId) delete remainingLock.resolved.template;
48792
+ if (remainingLock.desired.templates) remainingLock.desired.templates = remainingLock.desired.templates.filter((item) => item.id !== templateId);
48793
+ if (remainingLock.resolved.templates) remainingLock.resolved.templates = remainingLock.resolved.templates.filter((item) => item.id !== templateId);
48794
+ if (remainingLock.desired.addons) remainingLock.desired.addons = remainingLock.desired.addons.filter((item) => item.id !== templateId);
48795
+ if (remainingLock.resolved.addons) remainingLock.resolved.addons = remainingLock.resolved.addons.filter((item) => item.id !== templateId);
48796
+ if (remainingLock.desired.capabilities) remainingLock.desired.capabilities = remainingLock.desired.capabilities.filter((item) => item.packageId !== templateId);
48797
+ if (remainingLock.resolved.projects) remainingLock.resolved.projects = remainingLock.resolved.projects.filter((item) => item.packageId !== templateId);
48798
+ if (remainingLock.resolved.capabilities) remainingLock.resolved.capabilities = remainingLock.resolved.capabilities.filter((item) => item.packageId !== templateId);
48799
+ if (remainingLock.resolved.plugins) remainingLock.resolved.plugins = remainingLock.resolved.plugins.filter((item) => item.packageId !== templateId);
48800
+ remainingLock.resources = remainingLock.resources.map((resource) => ({ ...resource, owners: resource.owners.filter((owner) => owner.packageId !== templateId) })).filter((resource) => resource.owners.length > 0);
48561
48801
  }
48562
48802
  const hasPackages = (remainingLock.resolved.packages?.length ?? 0) > 0 || Boolean(remainingLock.resolved.template) || (remainingLock.resolved.templates?.length ?? 0) > 0 || (remainingLock.resolved.addons?.length ?? 0) > 0;
48563
48803
  const recordStartedAt = Date.now();
48564
48804
  await commitExecution(executor, executeResult, async (addRollback) => {
48565
- if (packageId && hasPackages) await lockRepo.write(remainingLock);
48805
+ if (templateId && hasPackages) await lockRepo.write(remainingLock);
48566
48806
  else await unlink11(lockRepo.path).catch((error) => {
48567
48807
  if (error.code !== "ENOENT") throw error;
48568
48808
  });
48569
48809
  addRollback(() => lockRepo.write(lock));
48570
48810
  await prepareUserDataRecovery(journal, service.getUserDataDir(), ["installations.json"]);
48571
- await removeUserReferences(lock, packageId, service, output);
48811
+ await removeUserReferences(lock, templateId, service, output);
48572
48812
  await finishJournal(journal);
48573
48813
  });
48574
48814
  events.report("record", "success", Date.now() - recordStartedAt, { planDigest: planResult.plan.planDigest });
48575
- for (let pkgIdx = 0; pkgIdx < packageManifests.length; pkgIdx++) {
48576
- const item = packageManifests[pkgIdx];
48815
+ for (let pkgIdx = 0; pkgIdx < templateManifests.length; pkgIdx++) {
48816
+ const item = templateManifests[pkgIdx];
48577
48817
  const pkgTasks = filterTasksByHook(item.manifest.tasks ?? [], "after:remove");
48578
48818
  if (pkgTasks.length > 0) {
48579
48819
  const taskContext = {
@@ -48587,7 +48827,7 @@ async function executeRemove(packageId, options, cliVersion, events) {
48587
48827
  operation: "remove",
48588
48828
  version: item.manifest.version
48589
48829
  };
48590
- const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u79FB\u9664\u4EFB\u52A1 (after:remove) [${pkgIdx + 1}/${packageManifests.length}] (${item.packageId}):`;
48830
+ const title = t("task.runningAfterRemove", pkgIdx + 1, templateManifests.length, item.templateId);
48591
48831
  try {
48592
48832
  await runTasksWithDynamicUI(pkgTasks, taskContext, {
48593
48833
  title,
@@ -48607,18 +48847,18 @@ async function executeRemove(packageId, options, cliVersion, events) {
48607
48847
  emitSuccessJson("remove", {
48608
48848
  dryRun: false,
48609
48849
  ...summary,
48610
- removedLock: !packageId || !hasPackages,
48611
- packageId: packageId ?? "*"
48850
+ removedLock: !templateId || !hasPackages,
48851
+ templateId: templateId ?? "*"
48612
48852
  }, [], [], jsonEvents());
48613
48853
  } else {
48614
48854
  printPlanSummary(summary);
48615
- writeHumanOutput(t("remove.removed", packageId ?? t("remove.allPackages"), service.projectRoot) + "\n");
48616
- writeHumanOutput(t(!packageId || !hasPackages ? "remove.lockRemoved" : "remove.lockUpdated") + "\n");
48855
+ writeHumanOutput(t("remove.removed", templateId ?? t("remove.allTemplates"), service.projectRoot) + "\n");
48856
+ writeHumanOutput(t(!templateId || !hasPackages ? "remove.lockRemoved" : "remove.lockUpdated") + "\n");
48617
48857
  }
48618
48858
  return ExitCode.Success;
48619
48859
  });
48620
48860
  }
48621
- async function removeUserReferences(originalLock, packageId, service, output) {
48861
+ async function removeUserReferences(originalLock, templateId, service, output) {
48622
48862
  const installationsRepo = service.getInstallationsRepository();
48623
48863
  const lockRec = originalLock;
48624
48864
  const resolved = lockRec["resolved"];
@@ -48637,10 +48877,10 @@ async function removeUserReferences(originalLock, packageId, service, output) {
48637
48877
  }
48638
48878
  }
48639
48879
  }
48640
- if (packageId) {
48880
+ if (templateId) {
48641
48881
  capabilities = capabilities.filter((cap) => {
48642
48882
  const capPkgId = cap["packageId"];
48643
- return capPkgId === packageId;
48883
+ return capPkgId === templateId;
48644
48884
  });
48645
48885
  }
48646
48886
  const warnings = [];
@@ -49609,7 +49849,7 @@ import { createHash as createHash17, randomUUID as randomUUID10 } from "node:cry
49609
49849
  import { basename as basename7, dirname as dirname19 } from "node:path";
49610
49850
  function createUpgradeCommand(cliVersion) {
49611
49851
  const cmd = new Command("upgrade");
49612
- cmd.description(t("upgrade.description")).option("--project <path>", t("upgrade.optionProject"), process.cwd()).option("--package <package-id>", t("upgrade.optionPackage")).option("--capability <id>", t("upgrade.optionCapability")).option("--version <version>", t("upgrade.optionVersion")).option("--dry-run", t("upgrade.optionDryRun")).option("--yes, -y", t("upgrade.optionYes")).option("--allow <permission>", t("upgrade.optionAllow"), collectPermission, []).action(async (opts) => {
49852
+ cmd.description(t("upgrade.description")).option("--project <path>", t("upgrade.optionProject"), process.cwd()).option("--template <template-id>", t("upgrade.optionTemplate")).option("--capability <id>", t("upgrade.optionCapability")).option("--version <version>", t("upgrade.optionVersion")).option("--dry-run", t("upgrade.optionDryRun")).option("--yes, -y", t("upgrade.optionYes")).option("--allow <permission>", t("upgrade.optionAllow"), collectPermission, []).action(async (opts) => {
49613
49853
  const globalOpts = extractGlobalOptions(opts);
49614
49854
  const output = {
49615
49855
  json: globalOpts.json,
@@ -49628,7 +49868,7 @@ function createUpgradeCommand(cliVersion) {
49628
49868
  }
49629
49869
  async function executeUpgrade(opts, cliVersion) {
49630
49870
  const projectRoot = typeof opts.project === "string" ? opts.project : process.cwd();
49631
- const packageId = typeof opts.package === "string" ? opts.package : void 0;
49871
+ const templateId = typeof opts.template === "string" ? opts.template : void 0;
49632
49872
  const targetVersion = typeof opts.version === "string" ? opts.version : void 0;
49633
49873
  const dryRun = Boolean(opts.dryRun);
49634
49874
  const yes = Boolean(opts.yes);
@@ -49657,7 +49897,7 @@ async function executeUpgrade(opts, cliVersion) {
49657
49897
  { resources: drift.map((item) => ({ type: item.type, path: item.path })) }
49658
49898
  );
49659
49899
  }
49660
- let targetPackageId = packageId;
49900
+ let targetPackageId = templateId;
49661
49901
  const desiredPackages = lock.desired?.packages ?? [];
49662
49902
  if (!targetPackageId) {
49663
49903
  if (desiredPackages.length === 1) {
@@ -49666,9 +49906,9 @@ async function executeUpgrade(opts, cliVersion) {
49666
49906
  targetPackageId = lock.desired.template.id;
49667
49907
  } else {
49668
49908
  throw new CliError(
49669
- "\u8BF7\u901A\u8FC7 --package <package-id> \u6307\u5B9A\u9700\u8981\u5347\u7EA7\u7684\u5305\u3002",
49909
+ t("upgrade.missingTemplate"),
49670
49910
  ExitCode.SchemaInvalid,
49671
- "MISSING_OPTIONS"
49911
+ "PACKAGE_SPEC_REQUIRED"
49672
49912
  );
49673
49913
  }
49674
49914
  }
@@ -49753,12 +49993,7 @@ async function executeUpgrade(opts, cliVersion) {
49753
49993
  if (json) {
49754
49994
  emitSuccessJson("upgrade", { dryRun: true, ...plan });
49755
49995
  } else {
49756
- writeHumanOutput(`\u5347\u7EA7\u8BA1\u5212\uFF1A
49757
- \u5305\uFF1A${targetPackageId}
49758
- \u5F53\u524D\uFF1A${oldVersion}
49759
- \u76EE\u6807\uFF1A${templateResolution.resolvedVersion}
49760
- \u9879\u76EE\uFF1A${projectRoot}
49761
- `);
49996
+ writeHumanOutput(t("upgrade.planSummary", targetPackageId, oldVersion, templateResolution.resolvedVersion, projectRoot));
49762
49997
  }
49763
49998
  return ExitCode.Success;
49764
49999
  }
@@ -49798,7 +50033,7 @@ async function executeUpgrade(opts, cliVersion) {
49798
50033
  previousVersion: oldVersion,
49799
50034
  version: templateResolution.resolvedVersion
49800
50035
  };
49801
- const title = `\u6B63\u5728\u6267\u884C\u524D\u7F6E\u5347\u7EA7\u4EFB\u52A1 (before:upgrade) (${targetPackageId}):`;
50036
+ const title = t("task.runningBeforeUpgrade", targetPackageId);
49802
50037
  try {
49803
50038
  await runTasksWithDynamicUI(beforeTasks, taskContext, {
49804
50039
  title,
@@ -49854,7 +50089,7 @@ async function executeUpgrade(opts, cliVersion) {
49854
50089
  previousVersion: oldVersion,
49855
50090
  version: templateResolution.resolvedVersion
49856
50091
  };
49857
- const title = `\u6B63\u5728\u6267\u884C\u540E\u7F6E\u5347\u7EA7\u4EFB\u52A1 (after:upgrade) (${targetPackageId}):`;
50092
+ const title = t("task.runningAfterUpgrade", targetPackageId);
49858
50093
  try {
49859
50094
  await runTasksWithDynamicUI(afterTasks, taskContext, {
49860
50095
  title,
@@ -50267,11 +50502,12 @@ import { homedir as homedir4 } from "node:os";
50267
50502
  import { join as join26 } from "node:path";
50268
50503
  function createLaunchCommand() {
50269
50504
  const cmd = new Command("_launch");
50270
- 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) => {
50505
+ cmd.description(t("launch.description")).option("--kind <kind>", t("launch.optionKind")).option("--template <template-id>", t("launch.optionTemplate")).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) => {
50271
50506
  const opts = command.opts();
50272
50507
  const launcherArgs = [];
50273
50508
  if (opts.kind) launcherArgs.push("--kind", opts.kind);
50274
- if (opts.package) launcherArgs.push("--package", opts.package);
50509
+ const pkgOrTemplate = opts.template ?? opts.package;
50510
+ if (pkgOrTemplate) launcherArgs.push("--package", pkgOrTemplate);
50275
50511
  if (opts.id) launcherArgs.push("--id", opts.id);
50276
50512
  if (opts.version) launcherArgs.push("--version", opts.version);
50277
50513
  if (opts.command) launcherArgs.push("--command", opts.command);
@@ -50708,7 +50944,7 @@ import { createRequire as createRequire2 } from "node:module";
50708
50944
  import { readFileSync as readFileSync4 } from "node:fs";
50709
50945
  import { fileURLToPath as fileURLToPath5 } from "node:url";
50710
50946
  function resolveVersion() {
50711
- if (true) return "0.1.33";
50947
+ if (true) return "0.1.35";
50712
50948
  const candidates = [
50713
50949
  new URL("../package.json", import.meta.url),
50714
50950
  new URL("../../package.json", import.meta.url),