@lark-apaas/miaoda-cli 0.1.5-alpha.156c7a1 → 0.1.5-beta.27ede41

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 (41) hide show
  1. package/dist/cli/commands/app/index.js +6 -66
  2. package/dist/cli/commands/index.js +1 -36
  3. package/dist/cli/handlers/app/index.js +1 -4
  4. package/dist/cli/handlers/app/init.js +9 -53
  5. package/dist/cli/handlers/skills/sync.js +4 -11
  6. package/dist/services/app/init/install.js +13 -20
  7. package/dist/services/app/init/template.js +6 -27
  8. package/dist/utils/coding-steering.js +19 -28
  9. package/package.json +3 -5
  10. package/dist/cli/handlers/app/sync.js +0 -215
  11. package/dist/config/fullstack-cli-pin.js +0 -17
  12. package/dist/config/sync-configs/design-stack.js +0 -98
  13. package/dist/config/sync-configs/index.js +0 -62
  14. package/dist/config/sync-configs/nestjs-react-fullstack.js +0 -176
  15. package/dist/config/sync.js +0 -14
  16. package/dist/utils/file-ops.js +0 -45
  17. package/dist/utils/githooks.js +0 -55
  18. package/dist/utils/merge-json.js +0 -63
  19. package/dist/utils/platform-sync.js +0 -160
  20. package/dist/utils/sync-rule.js +0 -295
  21. package/upgrade/templates/README.md +0 -34
  22. package/upgrade/templates/design-stack/templates/.githooks/pre-commit +0 -4
  23. package/upgrade/templates/design-stack/templates/scripts/dev-local.sh +0 -53
  24. package/upgrade/templates/design-stack/templates/scripts/dev.sh +0 -28
  25. package/upgrade/templates/design-stack/templates/scripts/hooks/run-precommit.js +0 -37
  26. package/upgrade/templates/nestjs-react-fullstack/templates/.githooks/pre-commit +0 -4
  27. package/upgrade/templates/nestjs-react-fullstack/templates/.gitignore.append +0 -8
  28. package/upgrade/templates/nestjs-react-fullstack/templates/.spark_project +0 -16
  29. package/upgrade/templates/nestjs-react-fullstack/templates/drizzle.config.ts +0 -55
  30. package/upgrade/templates/nestjs-react-fullstack/templates/helper/gen-openapi.ts +0 -34
  31. package/upgrade/templates/nestjs-react-fullstack/templates/nest-cli.json +0 -25
  32. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/build.sh +0 -207
  33. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev-local.sh +0 -61
  34. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.js +0 -295
  35. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/dev.sh +0 -28
  36. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/hooks/run-precommit.js +0 -37
  37. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/lint.js +0 -150
  38. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/prune-smart.js +0 -330
  39. package/upgrade/templates/nestjs-react-fullstack/templates/scripts/run.sh +0 -8
  40. package/upgrade/templates/nestjs-react-fullstack/templates/server/global.d.ts +0 -19
  41. package/upgrade/templates/nestjs-react-fullstack/templates/tsconfig.node.json +0 -5
@@ -6,7 +6,7 @@ const index_1 = require("../../../cli/handlers/app/index");
6
6
  const error_1 = require("../../../utils/error");
7
7
  function registerAppCommands(program, opts = {}) {
8
8
  const description = opts.includeInit
9
- ? '应用元数据管理:查看 / 修改 / 初始化 / 升级平台资产'
9
+ ? '应用元数据管理:查看 / 修改 / 初始化'
10
10
  : '应用元数据管理:查看 / 修改';
11
11
  const appCmd = program.command('app').description(description);
12
12
  appCmd.action(() => {
@@ -21,57 +21,8 @@ function registerAppCommands(program, opts = {}) {
21
21
  registerAppUpdate(appCmd);
22
22
  if (opts.includeInit) {
23
23
  registerAppInit(appCmd);
24
- registerAppSync(appCmd);
25
24
  }
26
25
  }
27
- function registerAppSync(parent) {
28
- const cmd = parent
29
- .command('sync')
30
- .alias('upgrade')
31
- .description('一站式同步:按 stack 的 SyncRule 全套 apply + 按钉死版本表升 @lark-apaas/* deps + npm install')
32
- .option('--dir <path>', '项目目录,默认 cwd(需含 .spark/meta.json)')
33
- .addHelpText('after', `
34
- 别名
35
- miaoda app sync 与 miaoda app upgrade 等价(upgrade 是历史别名,新调用方请用 sync)。
36
-
37
- 流程
38
- 1. 按 stack 的 SyncRule[] 全套 apply(src/config/sync-configs/<stack>.ts 定义):
39
- directory → 整个目录拷贝(.sh 自动 +x)
40
- file → 单文件覆盖(可选 onlyIfExists / overwrite)
41
- merge-json → JSON deep merge(可选 arrayMerge by key 去重)
42
- add-script → npm script 不存在时添加(overwrite=false 默认不覆盖)
43
- patch-script → npm script 以指定前缀开头时改写(守护用户自定义)
44
- add-line → 行不存在时追加到文件
45
- remove-line → 行存在时移除
46
- delete-file/delete-directory → 删除
47
- 沙箱里跑的 fullstack-cli sync 走同一套 rule 类型,行为对齐;miaoda app sync 在此之上
48
- 补 dev:local 等本地开发独有规则。
49
- 2. 平台 deps 钉版本:按 handlers/app/sync.ts 里 PINNED_PLATFORM_VERSIONS 升 user app 已装的
50
- @lark-apaas/* 包;表外 / 未装的不动。
51
- 3. activateGitHooks:core.hooksPath 一次性指向 .githooks/。
52
- 4. npm install --no-audit --no-fund --ignore-scripts。--ignore-scripts 是为绕开
53
- action-plugin postinstall 在 npm install 时缺平台 env 的卡点(需要时再
54
- FORCE_AUTHN_INNERAPI_DOMAIN=... npm install 手动跑一次)。
55
-
56
- JSON 输出
57
- {"data": {"stack": "...",
58
- "appliedRules": [{"type": "...", "action": "...", "path": "...", "detail": "..."}],
59
- "syncedFiles": [...],
60
- "mergedJsonFiles": [{"path": "...", "keys": [...]}],
61
- "patchedScripts": [...],
62
- "upgradedPackages": [{"name": "...", "from": "...", "to": "...", "section": "..."}]}}
63
-
64
- 示例
65
- $ miaoda app sync
66
- $ miaoda app sync --dir /path/to/app
67
- $ miaoda app upgrade # 等价于 miaoda app sync
68
- `);
69
- cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
70
- await (0, index_1.handleAppSync)({
71
- dir: rawOpts.dir,
72
- });
73
- }));
74
- }
75
26
  function registerAppGet(parent) {
76
27
  const cmd = parent
77
28
  .command('get')
@@ -119,28 +70,20 @@ JSON 输出
119
70
  function registerAppInit(parent) {
120
71
  const cmd = parent
121
72
  .command('init')
122
- .description('初始化应用代码:抓 template 渲染、同步 upgrade/templates、装 .agent/steering/ skills、写 .spark/meta.json。.spark/meta.json 已存在则直接退出')
73
+ .description('初始化应用代码:抓 template 渲染、装 .agent/steering/ skills、写 .spark/meta.json。.spark/meta.json 已存在则直接退出')
123
74
  .option('--template <stack>', `技术栈短名(${index_1.SUPPORTED_STACKS.join(' / ')})`)
124
75
  .option('--conf <json>', 'init 配置 JSON。支持 {"version": "<template 版本>"} / {"steeringVersion": "<steering 版本>"},均默认 latest')
125
76
  .option('--skip-install', '跳过依赖安装', false)
126
- .addOption((0, shared_1.appIdOption)())
127
77
  .addHelpText('after', `
128
78
  幂等
129
79
  .spark/meta.json 已存在时直接退出(initialized=false, reason=already_initialized),
130
- 不再触发 template 渲染、不重新跑 upgrade/templates 同步、不重新拉 skills、不安装依赖。
80
+ 不再触发 template 渲染、不重新拉 skills、不安装依赖。
131
81
  meta.json 在 init 流程最后才写,写了 = 已完整成功一次;
132
82
  上一次失败留下半渲染状态时(package.json 在但 meta.json 没在)允许重跑。
133
83
 
134
- 应用身份(app_id
135
- --app-id <id>(或 MIAODA_APP_ID env)提供时写入 .spark/meta.json app_id 字段;
136
- 未提供则不写。运行端命令(deploy / file / plugin 等)仍优先读 MIAODA_APP_ID env,
137
- env 未设置时回退到 meta.json.app_id。
138
-
139
- 平台同步(upgrade/templates)
140
- init 内嵌一次 upgrade/templates 同步(跟 app upgrade 共用同一份 util):
141
- 从 miaoda-cli 自带的 upgrade/templates/<stack>/ 同步 files/(覆盖)+ patches/
142
- (JSON deep merge,含 scripts.dev:local 等)。目标 stack 未纳入 upgrade/templates/
143
- 时跳过(不报错)。后续要升 @lark-apaas/* 平台包到最新 alpha,跑 'miaoda app upgrade'。
84
+ 应用身份(appId
85
+ init 不再持久化 appId。运行端命令(deploy / file / plugin 等)始终从 MIAODA_APP_ID env 读,
86
+ init 阶段也无需感知 appId。
144
87
 
145
88
  依赖安装
146
89
  默认:npm install --no-audit --no-fund
@@ -154,12 +97,10 @@ function registerAppInit(parent) {
154
97
  JSON 输出
155
98
  已初始化:{"data": {"initialized": false, "reason": "already_initialized", "targetDir": "..."}}
156
99
  新初始化:{"data": {"initialized": true, "template": "...", "templateVersion": "...", "steeringVersion": "...",
157
- "appId": "...", "platformStackFound": true, "platformSyncedFiles": [...],
158
100
  "installed": true, "installSource": "cache|npm|skipped", "installHash": "...", ...}}
159
101
 
160
102
  示例
161
103
  $ miaoda app init --template vite-react
162
- $ miaoda app init --template nestjs-react-fullstack --app-id app_xxx
163
104
  $ miaoda app init --template vite-react --conf '{"version": "0.1.0-alpha.1"}'
164
105
  $ miaoda app init --template vite-react --conf '{"steeringVersion": "0.1.0"}'
165
106
  $ miaoda app init --template vite-react --skip-install
@@ -171,7 +112,6 @@ JSON 输出
171
112
  template: rawOpts.template,
172
113
  conf,
173
114
  skipInstall: rawOpts.skipInstall,
174
- appId: rawOpts.appId,
175
115
  });
176
116
  }));
177
117
  }
@@ -9,59 +9,24 @@ const index_4 = require("../../cli/commands/app/index");
9
9
  const index_5 = require("../../cli/commands/deploy/index");
10
10
  const modern_1 = require("../../cli/commands/deploy/modern");
11
11
  const index_6 = require("../../cli/commands/skills/index");
12
- // scene 跟 dispatcher(MIAODA_APP_TYPE)同语义层级 —— app 业务类型维度,
13
- // 对齐后端 devops app_common.AppType 枚举:
14
- // 3 = AppType_APPLICATION(全栈应用,当前仅 nestjs-react-fullstack 一个 stack)
15
- // 4 = AppType_DESIGN(design-stack,SSR 渲染、无业务逻辑、无数据库)
16
- // 7 = miaoda-cli 自定义 modern 占位(后端枚举无 7,沙箱目前不传)
17
- // 其它(0/1/2/5/6 / 未设)→ default(命令全开,本地 dev / CI / 兼容回退)
18
- // stack 维度(nestjs-react-fullstack / vite-react / ...)是正交的,
19
- // skills sync 内部按 .spark/meta.json.stack 拉对应 coding-steering/steering/<stack>/ 子目录。
20
12
  function resolveScene(appType, _archType) {
21
13
  if (appType === '7')
22
14
  return 'modern';
23
- if (appType === '3')
24
- return 'application';
25
- if (appType === '4')
26
- return 'design';
27
15
  return 'default';
28
16
  }
29
17
  const SCENE_REGISTRARS = {
30
18
  default: (p) => {
31
- // init / upgrade / skills 都挂出来:本地用户不需要 export MIAODA_APP_TYPE=3
32
- // 就能跑 `miaoda app init` / `miaoda app upgrade` / `miaoda skills sync`。
33
- // 其它 scene 的差异(design 裁 db/file,modern 拆 deploy)仍按 MIAODA_APP_TYPE 路由
34
- (0, index_4.registerAppCommands)(p, { includeInit: true });
19
+ (0, index_4.registerAppCommands)(p);
35
20
  (0, index_5.registerDeployCommands)(p);
36
21
  (0, index_2.registerDbCommands)(p);
37
22
  (0, index_1.registerFileCommands)(p);
38
23
  (0, index_3.registerObservabilityCommands)(p);
39
- (0, index_6.registerSkillsCommands)(p);
40
24
  },
41
25
  modern: (p) => {
42
26
  (0, index_4.registerAppCommands)(p, { includeInit: true });
43
27
  (0, modern_1.registerDeployCommandsModern)(p);
44
28
  (0, index_6.registerSkillsCommands)(p);
45
29
  },
46
- // application scene(AppType_APPLICATION=3):
47
- // 在 default 命令集基础上加 skills(按 meta.json.stack 拉对应 stack 技能)
48
- // + app init(新一代应用走 init 写 .spark/meta.json)
49
- application: (p) => {
50
- (0, index_4.registerAppCommands)(p, { includeInit: true });
51
- (0, index_5.registerDeployCommands)(p);
52
- (0, index_2.registerDbCommands)(p);
53
- (0, index_1.registerFileCommands)(p);
54
- (0, index_3.registerObservabilityCommands)(p);
55
- (0, index_6.registerSkillsCommands)(p);
56
- },
57
- // design scene(AppType_DESIGN=4):design-stack 仅 SSR 渲染、无后端业务逻辑、
58
- // 无数据库、无 UGC 文件。命令集裁掉 db / file,保留 deploy / observability / app(init) / skills。
59
- design: (p) => {
60
- (0, index_4.registerAppCommands)(p, { includeInit: true });
61
- (0, index_5.registerDeployCommands)(p);
62
- (0, index_3.registerObservabilityCommands)(p);
63
- (0, index_6.registerSkillsCommands)(p);
64
- },
65
30
  };
66
31
  function readEnv(name) {
67
32
  const v = process.env[name]?.trim();
@@ -1,15 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SUPPORTED_STACKS = exports.handleAppUpgrade = exports.handleAppSync = exports.handleAppInit = exports.handleAppUpdate = exports.handleAppGet = void 0;
3
+ exports.SUPPORTED_STACKS = exports.handleAppInit = exports.handleAppUpdate = exports.handleAppGet = void 0;
4
4
  var get_1 = require("./get");
5
5
  Object.defineProperty(exports, "handleAppGet", { enumerable: true, get: function () { return get_1.handleAppGet; } });
6
6
  var update_1 = require("./update");
7
7
  Object.defineProperty(exports, "handleAppUpdate", { enumerable: true, get: function () { return update_1.handleAppUpdate; } });
8
8
  var init_1 = require("./init");
9
9
  Object.defineProperty(exports, "handleAppInit", { enumerable: true, get: function () { return init_1.handleAppInit; } });
10
- var sync_1 = require("./sync");
11
- Object.defineProperty(exports, "handleAppSync", { enumerable: true, get: function () { return sync_1.handleAppSync; } });
12
- Object.defineProperty(exports, "handleAppUpgrade", { enumerable: true, get: function () { return sync_1.handleAppUpgrade; } });
13
10
  // commands 层渲染 help 时需要这份枚举;从 handler barrel 转发,避免 commands → services 越界
14
11
  var index_1 = require("../../../services/app/init/index");
15
12
  Object.defineProperty(exports, "SUPPORTED_STACKS", { enumerable: true, get: function () { return index_1.SUPPORTED_STACKS; } });
@@ -8,17 +8,13 @@ const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const index_1 = require("../../../services/app/init/index");
10
10
  const coding_steering_1 = require("../../../utils/coding-steering");
11
- const logger_1 = require("../../../utils/logger");
12
- const githooks_1 = require("../../../utils/githooks");
13
- const sync_1 = require("../../../cli/handlers/app/sync");
14
11
  const error_1 = require("../../../utils/error");
15
12
  const output_1 = require("../../../utils/output");
16
13
  /**
17
14
  * miaoda app init
18
15
  *
19
- * 一站式本地脚手架:render template → upgrade/templates sync skills sync install deps,把
20
- * {stack, version, archType, app_id?} 写入 .spark/meta.json。--app-id(或 MIAODA_APP_ID)提供时
21
- * 持久化 app_id;运行端命令仍优先读 env,未设置时回退到 meta.json。
16
+ * 只负责本地脚手架:render templatesync skills、install deps,把 {stack, version, archType}
17
+ * 写入 .spark/meta.json。appId 不在此处持久化——deploy 等运行端通过 MIAODA_APP_ID env 拿。
22
18
  *
23
19
  * 幂等:.spark/meta.json 存在即表示已完整成功一次,直接退出,不重跑任何子步骤。
24
20
  * 半渲染状态(package.json 在但 meta.json 不在)会重新跑完整流程。
@@ -54,52 +50,24 @@ async function handleAppInit(opts) {
54
50
  const version = opts.conf?.version;
55
51
  const projectName = node_path_1.default.basename(targetDir);
56
52
  const tplResult = (0, index_1.renderTemplate)({ stack, version, targetDir, projectName });
57
- // sync 紧跟 template 渲染之后,赶在 install 之前:
58
- // 这样 directory / merge-json / add-script 等 rule 都已落地,install 出来的 lockfile
59
- // 与最终态对齐;patches 还能覆盖 template 提供的同名文件。
60
- const syncRunResult = (0, sync_1.runStackSync)(stack, targetDir, 'init');
61
- const syncSummary = (0, sync_1.summarizeSyncResults)(syncRunResult);
62
- // template 渲染下来的 @lark-apaas/* 版本可能落后 PINNED 表,赶在 install 之前钉到表版本,
63
- // 这样一次 npm install 就直接装最终版本,不需要 install 完再补一遍。
64
- const upgradedPackages = (0, sync_1.upgradePlatformDeps)(targetDir, 'init');
65
- // skills 同步软失败:拉不到 coding-steering 包不该阻断 writeSparkMeta /
66
- // activateGitHooks(之前会让 .spark/meta.json 没写,下次 init 半渲染状态又得重跑全套)。
67
- let steeringResult;
68
- let steeringError;
69
- try {
70
- steeringResult = (0, coding_steering_1.syncCodingSteering)({
71
- stack,
72
- targetDir,
73
- version: opts.conf?.steeringVersion,
74
- logPrefix: 'init',
75
- });
76
- }
77
- catch (err) {
78
- steeringError = err instanceof Error ? err.message : String(err);
79
- (0, logger_1.log)('init', `⚠ skills sync failed (continuing init): ${steeringError}`);
80
- steeringResult = { version: 'unknown', syncedSkills: [], techSynced: false };
81
- }
53
+ const steeringResult = (0, coding_steering_1.syncCodingSteering)({
54
+ stack,
55
+ targetDir,
56
+ version: opts.conf?.steeringVersion,
57
+ logPrefix: 'init',
58
+ });
82
59
  const installResult = (0, index_1.installDependencies)({
83
60
  targetDir,
84
61
  skip: opts.skipInstall,
85
62
  quietStdout: (0, output_1.isJsonMode)(),
86
63
  });
87
- // template 自带 .githooks/pre-commit;如果用户项目已 git init,顺便设上 core.hooksPath。
88
- const hookActivation = (0, githooks_1.activateGitHooks)(targetDir);
89
64
  (0, index_1.writeSparkMeta)(targetDir, {
90
65
  stack,
91
66
  version: tplResult.version,
92
67
  archType: tplResult.archType,
93
- app_id: opts.appId,
94
- steeringVersion: steeringResult.version,
95
68
  });
96
- const syncedSummary = syncRunResult.stackFound
97
- ? syncRunResult.rulesApplied.length > 0
98
- ? `${syncRunResult.rulesApplied.length.toString()} rule(s)`
99
- : 'legacy'
100
- : 'skipped';
101
69
  if (!(0, output_1.isJsonMode)()) {
102
- process.stdout.write(`✓ Initialized ${stack} (template ${tplResult.version}, steering ${steeringResult.version}, sync ${syncedSummary}, install ${installResult.source}) in ${targetDir}\n`);
70
+ process.stdout.write(`✓ Initialized ${stack} (template ${tplResult.version}, steering ${steeringResult.version}, install ${installResult.source}) in ${targetDir}\n`);
103
71
  }
104
72
  (0, output_1.emit)({
105
73
  data: {
@@ -109,24 +77,12 @@ async function handleAppInit(opts) {
109
77
  templateVersion: tplResult.version,
110
78
  steeringVersion: steeringResult.version,
111
79
  archType: tplResult.archType,
112
- appId: opts.appId,
113
80
  syncedSkills: steeringResult.syncedSkills,
114
81
  techSynced: steeringResult.techSynced,
115
- steeringError,
116
- // sync 流程的产出:rule-driven 时 appliedRules + 一系列汇总字段;fallback 到旧 platform-sync
117
- // 时只填 platformSyncedFiles / platformMergedJsonFiles;stack 不识别时全空且 platformStackFound=false。
118
- platformStackFound: syncRunResult.stackFound,
119
- appliedRules: syncSummary.appliedRules,
120
- platformSyncedFiles: syncSummary.syncedFiles,
121
- platformMergedJsonFiles: syncSummary.mergedJsonFiles,
122
- patchedScripts: syncSummary.patchedScripts,
123
- upgradedPackages,
124
- gitHooks: hookActivation.action,
125
82
  installed: installResult.installed,
126
83
  installSource: installResult.source,
127
84
  installHash: installResult.hash,
128
85
  cacheZip: installResult.cacheZip,
129
- installError: installResult.error,
130
86
  },
131
87
  });
132
88
  }
@@ -10,10 +10,10 @@ const spark_meta_1 = require("../../../utils/spark-meta");
10
10
  const error_1 = require("../../../utils/error");
11
11
  const output_1 = require("../../../utils/output");
12
12
  /**
13
- * miaoda skills sync [version] [--dir <path>]
13
+ * miaoda skills sync [--dir <path>] [--version <ver>]
14
14
  *
15
- * 从 .spark/meta.json 读 stack(+ 默认 steeringVersion),把 coding-steering 包内对应 stack
16
- * 的 skills + tech.md 同步到 <dir>/.agent/steering/。需要先跑过 `miaoda app init`。
15
+ * 从 .spark/meta.json 读 stack,把 coding-steering 包内对应 stack 的 skills + tech.md
16
+ * 同步到 <dir>/.agent/steering/。需要先跑过 `miaoda app init`。
17
17
  */
18
18
  async function handleSkillsSync(opts) {
19
19
  await Promise.resolve();
@@ -22,22 +22,15 @@ async function handleSkillsSync(opts) {
22
22
  if (meta.stack === undefined || meta.stack === '') {
23
23
  throw new error_1.AppError('SKILLS_META_INCOMPLETE', '.spark/meta.json missing stack — run `miaoda app init` first');
24
24
  }
25
- const version = opts.version ?? meta.steeringVersion;
26
- const versionSource = opts.version
27
- ? 'cli-arg'
28
- : meta.steeringVersion
29
- ? 'meta.json'
30
- : 'default-latest';
31
25
  const result = (0, coding_steering_1.syncCodingSteering)({
32
26
  stack: meta.stack,
33
27
  targetDir,
34
- version,
28
+ version: opts.version,
35
29
  });
36
30
  (0, output_1.emit)({
37
31
  data: {
38
32
  stack: meta.stack,
39
33
  version: result.version,
40
- versionSource,
41
34
  syncedSkills: result.syncedSkills,
42
35
  techSynced: result.techSynced,
43
36
  },
@@ -44,31 +44,18 @@ function installDependencies(opts) {
44
44
  return { installed: true, source: 'cache', hash, cacheZip };
45
45
  }
46
46
  (0, logger_1.log)('init', 'Cache zip extracted but node_modules/ missing or empty; falling back to npm install');
47
- return runInstallSoft(opts.targetDir, childStdio, hash);
47
+ runNpmInstall(opts.targetDir, childStdio);
48
+ return { installed: true, source: 'npm', hash };
48
49
  }
49
50
  (0, logger_1.log)('init', `Cache miss for ${hash}.zip, falling back to npm install`);
50
- return runInstallSoft(opts.targetDir, childStdio, hash);
51
+ runNpmInstall(opts.targetDir, childStdio);
52
+ return { installed: true, source: 'npm', hash };
51
53
  }
52
54
  if (cacheDir && !hasPkg) {
53
55
  (0, logger_1.log)('init', `${DEP_CACHE_ENV} set but no package.json in target; running npm install`);
54
56
  }
55
- return runInstallSoft(opts.targetDir, childStdio);
56
- }
57
- /**
58
- * 跑 npm install;失败不抛错,返回 source='failed' 让上层 init handler 继续走 writeSparkMeta
59
- * 等后续步骤(避免 install 挂了 .spark/meta.json 没写出来,下次 init 看到半渲染状态又得重跑全套)。
60
- * 失败信息通过 stderr 直出 + emit data.installError 透传给用户。
61
- */
62
- function runInstallSoft(targetDir, stdio, hash) {
63
- try {
64
- runNpmInstall(targetDir, stdio);
65
- return { installed: true, source: 'npm', hash };
66
- }
67
- catch (err) {
68
- const msg = err instanceof Error ? err.message : String(err);
69
- (0, logger_1.log)('init', `⚠ npm install failed (continuing init): ${msg}`);
70
- return { installed: false, source: 'failed', hash, error: msg };
71
- }
57
+ runNpmInstall(opts.targetDir, childStdio);
58
+ return { installed: true, source: 'npm' };
72
59
  }
73
60
  function nodeModulesUsable(targetDir) {
74
61
  const nm = node_path_1.default.join(targetDir, 'node_modules');
@@ -104,5 +91,11 @@ function extractZip(zipPath, targetDir, stdio) {
104
91
  }
105
92
  function runNpmInstall(targetDir, stdio) {
106
93
  (0, logger_1.log)('init', `npm install in ${targetDir}...`);
107
- (0, node_child_process_1.execFileSync)('npm', ['install', '--no-audit', '--no-fund'], { cwd: targetDir, stdio });
94
+ try {
95
+ (0, node_child_process_1.execFileSync)('npm', ['install', '--no-audit', '--no-fund'], { cwd: targetDir, stdio });
96
+ }
97
+ catch (err) {
98
+ const msg = err instanceof Error ? err.message : String(err);
99
+ throw new error_1.AppError('NPM_INSTALL_FAILED', `npm install 失败: ${msg}`);
100
+ }
108
101
  }
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.SUPPORTED_STACKS = exports.TEMPLATE_PINNED_VERSION_BY_STACK = exports.TEMPLATE_PACKAGE_BY_STACK = void 0;
6
+ exports.SUPPORTED_STACKS = exports.TEMPLATE_PACKAGE_BY_STACK = void 0;
7
7
  exports.renderTemplate = renderTemplate;
8
8
  const node_fs_1 = __importDefault(require("node:fs"));
9
9
  const node_path_1 = __importDefault(require("node:path"));
@@ -14,28 +14,13 @@ const logger_1 = require("../../../utils/logger");
14
14
  exports.TEMPLATE_PACKAGE_BY_STACK = {
15
15
  'vite-react': '@lark-apaas/coding-template-vite-react',
16
16
  html: '@lark-apaas/coding-template-html',
17
- 'nestjs-react-fullstack': '@lark-apaas/coding-template-nestjs-react-fullstack',
18
- };
19
- /**
20
- * 短名 → template 包钉死版本。renderTemplate 默认按这张表取版本号,表外 stack 走 npm latest。
21
- *
22
- * 钉死稳定版本而非跟 alpha dist-tag —— alpha 通道被多团队共享,外部 prerelease 时常打过去,
23
- * 自动跟 alpha 会把回归版本拉进 user app。每次升基线人工 review 一次再改这里。
24
- * 用户显式传 `--conf '{"version": "..."}'` 仍 override 此默认值。
25
- */
26
- exports.TEMPLATE_PINNED_VERSION_BY_STACK = {
27
- 'nestjs-react-fullstack': '0.1.0-alpha.5',
28
- // vite-react / html 暂不钉版,跟 latest dist-tag(新版正常迭代后再纳入钉版)
29
17
  };
30
18
  exports.SUPPORTED_STACKS = Object.keys(exports.TEMPLATE_PACKAGE_BY_STACK);
31
- // template/ 内以下划线开头的占位文件名在渲染时改名。
32
- // 原因:
33
- // 1. npm pack 强制剥的:.npmrc(防 auth token 泄露)
34
- // 2. 沙箱平台特殊处理的:.gitignore(避免与平台仓库 .gitignore 冲突)
35
- // .env 通过 negation pattern 例外直接 ship;.env.local 完全由 lark-cli +env-pull
36
- // 运行时下发,模板里不再放占位文件。
19
+ // template/ 内以下划线开头的占位文件名在渲染时改名(npm publish 会把 .gitignore / .npmrc 吞掉,
20
+ // 模板里用 _gitignore / _npmrc 提交,渲染时再改回)。
37
21
  const RENAME_FILES = {
38
22
  _gitignore: '.gitignore',
23
+ '_env.local': '.env.local',
39
24
  _npmrc: '.npmrc',
40
25
  };
41
26
  function renderTemplate(opts) {
@@ -45,14 +30,8 @@ function renderTemplate(opts) {
45
30
  next_actions: [`可用 stack:${exports.SUPPORTED_STACKS.join(', ')}`],
46
31
  });
47
32
  }
48
- // 默认按 TEMPLATE_PINNED_VERSION_BY_STACK 取钉版(避免 npm latest 碰外部 prerelease 回归);
49
- // 表外 stack fallback 'latest';用户显式传 --conf.version 仍 override 钉版。
50
- const pinned = Object.prototype.hasOwnProperty.call(exports.TEMPLATE_PINNED_VERSION_BY_STACK, opts.stack)
51
- ? exports.TEMPLATE_PINNED_VERSION_BY_STACK[opts.stack]
52
- : undefined;
53
- const effectiveVersion = opts.version ?? pinned ?? 'latest';
54
- (0, logger_1.log)('init', `Fetching ${packageName}@${effectiveVersion}...`);
55
- const fetched = (0, npm_pack_1.fetchNpmPackage)({ packageName, version: effectiveVersion });
33
+ (0, logger_1.log)('init', `Fetching ${packageName}@${opts.version ?? 'latest'}...`);
34
+ const fetched = (0, npm_pack_1.fetchNpmPackage)({ packageName, version: opts.version });
56
35
  try {
57
36
  const templateDir = node_path_1.default.join(fetched.extractDir, 'template');
58
37
  if (!node_fs_1.default.existsSync(templateDir)) {
@@ -9,31 +9,19 @@ const node_path_1 = __importDefault(require("node:path"));
9
9
  const npm_pack_1 = require("../utils/npm-pack");
10
10
  const logger_1 = require("../utils/logger");
11
11
  const STEERING_PACKAGE = '@lark-apaas/coding-steering';
12
- // 钉死稳定 alpha 版本而非跟 `alpha` dist-tag —— alpha 通道被多个团队共享,外部 prerelease
13
- // 时常打过去,自动跟 alpha 会把回归版本拉进 user app。维护这个常量比维护 alpha 通道可控。
14
- // 用户显式传具体版本(如 `miaoda skills sync 0.2.0`)仍 override 这个默认值。
15
- // 升基线时:跑端到端 smoke(init → skills sync → 看 skills 内容)→ 改这个常量。
16
- const DEFAULT_PINNED_VERSION = '0.1.6-alpha.10';
17
12
  /**
18
- * 把 coding-steering 包内 _common/skills + <stack>/skills + <stack>/skills_local 同步到
19
- * <targetDir>/.agent/steering/skills/。同名优先级 _common < <stack>/skills < <stack>/skills_local
20
- * tech.md 存在时也同步到 .agent/steering/tech.md。
21
- *
22
- * skills_local 是 stack 的"本地变体"目录(方案 wiki WQ29w9d7pizhBmksWRIcEXzkndb):云端沙箱
23
- * 走另一条 update-skills.sh 链路只取 skills/,本地走 miaoda-cli 这条链路时叠加 skills_local
24
- * 覆盖同名 — 让 coding-guide / code-fix 这种"云端版含 ddl_sql / plugin_instance 等沙箱工具
25
- * 引用"的 skill 能在本地拿到去掉这些引用的本地变体。
13
+ * 把 coding-steering 包内 _common/skills + <stack>/skills 同步到 <targetDir>/.agent/steering/skills/,
14
+ * 同名 stack 子目录覆盖 _common。tech.md 存在时也同步到 .agent/steering/tech.md
26
15
  *
27
16
  * 纯本地 atom(pull npm package + 拷贝文件),不属于任何 cli 域;放在 utils 让
28
17
  * app init handler 与独立 skills sync handler 都能复用。
29
18
  */
30
19
  function syncCodingSteering(opts) {
31
20
  const logPrefix = opts.logPrefix ?? 'skills';
32
- const effectiveVersion = opts.version ?? DEFAULT_PINNED_VERSION;
33
- (0, logger_1.log)(logPrefix, `Fetching ${STEERING_PACKAGE}@${effectiveVersion}...`);
21
+ (0, logger_1.log)(logPrefix, `Fetching ${STEERING_PACKAGE}@${opts.version ?? 'latest'}...`);
34
22
  const fetched = (0, npm_pack_1.fetchNpmPackage)({
35
23
  packageName: STEERING_PACKAGE,
36
- version: effectiveVersion,
24
+ version: opts.version,
37
25
  });
38
26
  try {
39
27
  const steeringRoot = node_path_1.default.join(fetched.extractDir, 'steering');
@@ -52,24 +40,27 @@ function syncCodingSteering(opts) {
52
40
  techSynced = true;
53
41
  }
54
42
  const synced = [];
55
- // 顺序拷贝,后者覆盖前者:_common/skills <stack>/skills <stack>/skills_local
56
- const layers = [
57
- { dir: commonSkillsDir, label: '_common/skills' },
58
- { dir: node_path_1.default.join(stackDir, 'skills'), label: `${opts.stack}/skills` },
59
- { dir: node_path_1.default.join(stackDir, 'skills_local'), label: `${opts.stack}/skills_local` },
60
- ];
61
- for (const layer of layers) {
62
- if (!node_fs_1.default.existsSync(layer.dir))
63
- continue;
64
- for (const name of node_fs_1.default.readdirSync(layer.dir)) {
65
- const src = node_path_1.default.join(layer.dir, name);
43
+ // 先拷 _common/skills/,再拷 <stack>/skills/。stack 同名覆盖 common
44
+ if (node_fs_1.default.existsSync(commonSkillsDir)) {
45
+ for (const name of node_fs_1.default.readdirSync(commonSkillsDir)) {
46
+ const src = node_path_1.default.join(commonSkillsDir, name);
47
+ if (!node_fs_1.default.statSync(src).isDirectory())
48
+ continue;
49
+ copyDir(src, node_path_1.default.join(dstSkillsDir, name));
50
+ synced.push(`_common/skills/${name}`);
51
+ }
52
+ }
53
+ const stackSkillsDir = node_path_1.default.join(stackDir, 'skills');
54
+ if (node_fs_1.default.existsSync(stackSkillsDir)) {
55
+ for (const name of node_fs_1.default.readdirSync(stackSkillsDir)) {
56
+ const src = node_path_1.default.join(stackSkillsDir, name);
66
57
  if (!node_fs_1.default.statSync(src).isDirectory())
67
58
  continue;
68
59
  const dst = node_path_1.default.join(dstSkillsDir, name);
69
60
  if (node_fs_1.default.existsSync(dst))
70
61
  node_fs_1.default.rmSync(dst, { recursive: true, force: true });
71
62
  copyDir(src, dst);
72
- synced.push(`${layer.label}/${name}`);
63
+ synced.push(`${opts.stack}/skills/${name}`);
73
64
  }
74
65
  }
75
66
  (0, logger_1.log)(logPrefix, `Synced ${String(synced.length)} skill(s), tech.md ${techSynced ? 'yes' : 'no'}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/miaoda-cli",
3
- "version": "0.1.5-alpha.156c7a1",
3
+ "version": "0.1.5-beta.27ede41",
4
4
  "description": "Miaoda 平台命令行工具,面向 Agent 调用",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -10,11 +10,10 @@
10
10
  "access": "public"
11
11
  },
12
12
  "files": [
13
- "LICENSE",
14
- "README.md",
15
13
  "bin",
16
14
  "dist",
17
- "upgrade"
15
+ "README.md",
16
+ "LICENSE"
18
17
  ],
19
18
  "keywords": [
20
19
  "miaoda",
@@ -28,7 +27,6 @@
28
27
  "dependencies": {
29
28
  "@lark-apaas/http-client": "^0.1.5",
30
29
  "commander": "^13.1.0",
31
- "jsonc-parser": "^3.3.1",
32
30
  "ora": "^5.4.1",
33
31
  "picocolors": "^1.1.1"
34
32
  },