@lark-apaas/miaoda-cli 0.1.4-alpha.abaa17f → 0.1.4-alpha.e76a6d6

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.
@@ -8,6 +8,7 @@ const index_3 = require("../../cli/commands/observability/index");
8
8
  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
+ const index_6 = require("../../cli/commands/skills/index");
11
12
  function resolveScene(appType, _archType) {
12
13
  if (appType === '7')
13
14
  return 'modern';
@@ -24,6 +25,7 @@ const SCENE_REGISTRARS = {
24
25
  modern: (p) => {
25
26
  (0, index_4.registerAppCommands)(p, { includeInit: true });
26
27
  (0, modern_1.registerDeployCommandsModern)(p);
28
+ (0, index_6.registerSkillsCommands)(p);
27
29
  },
28
30
  };
29
31
  function readEnv(name) {
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSkillsCommands = registerSkillsCommands;
4
+ const shared_1 = require("../../../cli/commands/shared");
5
+ const index_1 = require("../../../cli/handlers/skills/index");
6
+ /**
7
+ * miaoda skills:本地 agent skills 维护。
8
+ *
9
+ * 当前仅 steering 一类子集(coding-steering 包内的 _common/skills + <stack>/skills + tech.md);
10
+ * 后续如有更多 skill 类型再加 --type。`app init` 会一次性同步装上,独立 `skills sync` 用于
11
+ * 后续单独升级 / pin 版本,不必走完整 init。
12
+ */
13
+ function registerSkillsCommands(program) {
14
+ const skillsCmd = program.command('skills').description('本地 agent skills(含 steering)维护');
15
+ skillsCmd.action(() => {
16
+ skillsCmd.outputHelp();
17
+ });
18
+ registerSkillsSync(skillsCmd);
19
+ registerSkillsStatus(skillsCmd);
20
+ }
21
+ function registerSkillsSync(parent) {
22
+ const cmd = parent
23
+ .command('sync')
24
+ .description('同步 coding-steering(latest 或指定版本)到 .agent/steering/')
25
+ .argument('[version]', 'coding-steering 包版本或 dist-tag,缺省 latest')
26
+ .option('--dir <path>', '项目目录,默认当前目录', '.')
27
+ .addHelpText('after', `
28
+ 前置要求
29
+ 当前目录(或 --dir)已走过 'miaoda app init'(.spark/meta.json 含 stack)
30
+
31
+ JSON 输出
32
+ {"data": {"stack": "...", "version": "...", "syncedSkills": [...], "techSynced": true|false}}
33
+
34
+ 示例
35
+ $ miaoda skills sync
36
+ $ miaoda skills sync 0.2.0
37
+ $ miaoda skills sync --dir ./my-app
38
+ `);
39
+ cmd.action((0, shared_1.withHelp)(cmd, async (version, rawOpts) => {
40
+ await (0, index_1.handleSkillsSync)({
41
+ dir: rawOpts.dir,
42
+ version,
43
+ });
44
+ }));
45
+ }
46
+ function registerSkillsStatus(parent) {
47
+ const cmd = parent
48
+ .command('status')
49
+ .description('查看本地 .agent/steering/ 的当前状态(不联网)')
50
+ .option('--dir <path>', '项目目录,默认当前目录', '.')
51
+ .addHelpText('after', `
52
+ JSON 输出
53
+ {"data": {"present": true|false, "skills": [...], "techSynced": true|false}}
54
+
55
+ 示例
56
+ $ miaoda skills status
57
+ `);
58
+ cmd.action((0, shared_1.withHelp)(cmd, async (rawOpts) => {
59
+ await (0, index_1.handleSkillsStatus)({
60
+ dir: rawOpts.dir,
61
+ });
62
+ }));
63
+ }
@@ -7,6 +7,7 @@ exports.handleAppInit = handleAppInit;
7
7
  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
+ const coding_steering_1 = require("../../../utils/coding-steering");
10
11
  const error_1 = require("../../../utils/error");
11
12
  const output_1 = require("../../../utils/output");
12
13
  /** miaoda app init [--template <stack>] [--conf <json>] */
@@ -43,10 +44,11 @@ async function handleAppInit(opts) {
43
44
  const version = opts.conf?.version;
44
45
  const projectName = node_path_1.default.basename(targetDir);
45
46
  const tplResult = (0, index_1.renderTemplate)({ stack, version, targetDir, projectName });
46
- const steeringResult = (0, index_1.syncSteering)({
47
+ const steeringResult = (0, coding_steering_1.syncCodingSteering)({
47
48
  stack,
48
49
  targetDir,
49
50
  version: opts.conf?.steeringVersion,
51
+ logPrefix: 'init',
50
52
  });
51
53
  const installResult = (0, index_1.installDependencies)({
52
54
  targetDir,
@@ -55,13 +57,9 @@ async function handleAppInit(opts) {
55
57
  });
56
58
  (0, index_1.writeSparkMeta)(targetDir, {
57
59
  appId: opts.appId,
58
- template: stack,
59
- templatePackage: tplResult.packageName,
60
- templateVersion: tplResult.version,
61
- steeringVersion: steeringResult.version,
60
+ stack,
61
+ version: tplResult.version,
62
62
  archType: tplResult.archType,
63
- installSource: installResult.source,
64
- installHash: installResult.hash,
65
63
  });
66
64
  if (!(0, output_1.isJsonMode)()) {
67
65
  process.stdout.write(`✓ Initialized ${stack} (template ${tplResult.version}, steering ${steeringResult.version}, install ${installResult.source}) in ${targetDir}\n`);
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleSkillsStatus = exports.handleSkillsSync = void 0;
4
+ var sync_1 = require("./sync");
5
+ Object.defineProperty(exports, "handleSkillsSync", { enumerable: true, get: function () { return sync_1.handleSkillsSync; } });
6
+ var status_1 = require("./status");
7
+ Object.defineProperty(exports, "handleSkillsStatus", { enumerable: true, get: function () { return status_1.handleSkillsStatus; } });
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleSkillsStatus = handleSkillsStatus;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const index_1 = require("../../../services/skills/index");
9
+ const spark_meta_1 = require("../../../utils/spark-meta");
10
+ const output_1 = require("../../../utils/output");
11
+ /**
12
+ * miaoda skills status [--dir <path>]
13
+ *
14
+ * 从 .spark/meta.json 读 stack,扫描 <dir>/.agent/steering/<stack>/,
15
+ * 给出当前装了哪些 skills、tech.md 是否在。纯本地操作,不联网。
16
+ * meta 缺 stack 时返回 present=false(不抛错,方便和 init 的引导分开)。
17
+ */
18
+ async function handleSkillsStatus(opts) {
19
+ await Promise.resolve();
20
+ const targetDir = node_path_1.default.resolve(opts.dir ?? process.cwd());
21
+ const meta = (0, spark_meta_1.readSparkMeta)(targetDir);
22
+ const status = (0, index_1.readSkillsStatus)({ targetDir, stack: meta.stack });
23
+ (0, output_1.emit)({
24
+ data: {
25
+ stack: meta.stack ?? null,
26
+ present: status.present,
27
+ skills: status.skills,
28
+ techSynced: status.techSynced,
29
+ },
30
+ });
31
+ }
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleSkillsSync = handleSkillsSync;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const coding_steering_1 = require("../../../utils/coding-steering");
9
+ const spark_meta_1 = require("../../../utils/spark-meta");
10
+ const error_1 = require("../../../utils/error");
11
+ const output_1 = require("../../../utils/output");
12
+ /**
13
+ * miaoda skills sync [--dir <path>] [--version <ver>]
14
+ *
15
+ * 从 .spark/meta.json 读 stack,把 coding-steering 包内对应 stack 的 skills + tech.md
16
+ * 同步到 <dir>/.agent/steering/。需要先跑过 `miaoda app init`。
17
+ */
18
+ async function handleSkillsSync(opts) {
19
+ await Promise.resolve();
20
+ const targetDir = node_path_1.default.resolve(opts.dir ?? process.cwd());
21
+ const meta = (0, spark_meta_1.readSparkMeta)(targetDir);
22
+ if (meta.stack === undefined || meta.stack === '') {
23
+ throw new error_1.AppError('SKILLS_META_INCOMPLETE', '.spark/meta.json missing stack — run `miaoda app init` first');
24
+ }
25
+ const result = (0, coding_steering_1.syncCodingSteering)({
26
+ stack: meta.stack,
27
+ targetDir,
28
+ version: opts.version,
29
+ });
30
+ (0, output_1.emit)({
31
+ data: {
32
+ stack: meta.stack,
33
+ version: result.version,
34
+ syncedSkills: result.syncedSkills,
35
+ techSynced: result.techSynced,
36
+ },
37
+ });
38
+ }
@@ -1,12 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.installDependencies = exports.writeSparkMeta = exports.readSparkMeta = exports.syncSteering = exports.TEMPLATE_PACKAGE_BY_STACK = exports.SUPPORTED_STACKS = exports.renderTemplate = void 0;
3
+ exports.installDependencies = exports.writeSparkMeta = exports.readSparkMeta = exports.TEMPLATE_PACKAGE_BY_STACK = exports.SUPPORTED_STACKS = exports.renderTemplate = void 0;
4
4
  var template_1 = require("./template");
5
5
  Object.defineProperty(exports, "renderTemplate", { enumerable: true, get: function () { return template_1.renderTemplate; } });
6
6
  Object.defineProperty(exports, "SUPPORTED_STACKS", { enumerable: true, get: function () { return template_1.SUPPORTED_STACKS; } });
7
7
  Object.defineProperty(exports, "TEMPLATE_PACKAGE_BY_STACK", { enumerable: true, get: function () { return template_1.TEMPLATE_PACKAGE_BY_STACK; } });
8
- var steering_1 = require("./steering");
9
- Object.defineProperty(exports, "syncSteering", { enumerable: true, get: function () { return steering_1.syncSteering; } });
10
8
  var spark_meta_1 = require("../../../utils/spark-meta");
11
9
  Object.defineProperty(exports, "readSparkMeta", { enumerable: true, get: function () { return spark_meta_1.readSparkMeta; } });
12
10
  Object.defineProperty(exports, "writeSparkMeta", { enumerable: true, get: function () { return spark_meta_1.writeSparkMeta; } });
@@ -10,7 +10,7 @@ const node_path_1 = __importDefault(require("node:path"));
10
10
  const npm_pack_1 = require("../../../utils/npm-pack");
11
11
  const error_1 = require("../../../utils/error");
12
12
  const logger_1 = require("../../../utils/logger");
13
- /** 短名 → 包名映射。新增 stack 时改这里。 */
13
+ /** 短名 → 包名映射。新增 stack 时改这里。archType 由 template 包自报,CLI 不维护。 */
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',
@@ -37,12 +37,13 @@ function renderTemplate(opts) {
37
37
  throw new error_1.AppError('TEMPLATE_INVALID', `包 ${packageName}@${fetched.version} 缺少 template/ 目录`);
38
38
  }
39
39
  const pkgJsonPath = node_path_1.default.join(fetched.extractDir, 'package.json');
40
- let archType = '';
40
+ let archType;
41
41
  if (node_fs_1.default.existsSync(pkgJsonPath)) {
42
42
  const pkgJson = JSON.parse(node_fs_1.default.readFileSync(pkgJsonPath, 'utf-8'));
43
- archType = pkgJson.miaodaTemplate?.archType ?? '';
43
+ archType = pkgJson.miaodaTemplate?.archType;
44
44
  }
45
- if (!archType) {
45
+ // 用显式 null/undefined/'' 判,避免把合法值 0 / false 当成"缺失"误抛
46
+ if (archType === undefined || archType === null || archType === '') {
46
47
  throw new error_1.AppError('TEMPLATE_INVALID', `包 ${packageName}@${fetched.version} 缺少 package.json.miaodaTemplate.archType`);
47
48
  }
48
49
  (0, logger_1.log)('init', `Rendering template to ${opts.targetDir}...`);
@@ -6,7 +6,7 @@ const spark_meta_1 = require("../../../../utils/spark-meta");
6
6
  const check_1 = require("../check");
7
7
  const template_key_map_1 = require("../template-key-map");
8
8
  /**
9
- * 准备 deploy 上下文:跑前置检查、读 .spark/meta.json、抽出 appId / template
9
+ * 准备 deploy 上下文:跑前置检查、读 .spark/meta.json、抽出 appId / stack
10
10
  * 并把 stack 短名映射成后端 templateKey。
11
11
  *
12
12
  * 任何前置失败统一抛 AppError。返回值是后续 atom 唯一信任的入参源。
@@ -17,14 +17,14 @@ function prepareDeployContext(projectDir) {
17
17
  if (meta.appId === undefined || meta.appId === '') {
18
18
  throw new error_1.AppError('DEPLOY_META_INCOMPLETE', '.spark/meta.json missing appId — run `miaoda app init` first');
19
19
  }
20
- if (meta.template === undefined || meta.template === '') {
21
- throw new error_1.AppError('DEPLOY_META_INCOMPLETE', '.spark/meta.json missing template — run `miaoda app init` first');
20
+ if (meta.stack === undefined || meta.stack === '') {
21
+ throw new error_1.AppError('DEPLOY_META_INCOMPLETE', '.spark/meta.json missing stack — run `miaoda app init` first');
22
22
  }
23
23
  return {
24
24
  projectDir,
25
25
  appId: meta.appId,
26
- template: meta.template,
27
- templateKey: (0, template_key_map_1.resolveTemplateKey)(meta.template),
26
+ stack: meta.stack,
27
+ templateKey: (0, template_key_map_1.resolveTemplateKey)(meta.stack),
28
28
  meta,
29
29
  };
30
30
  }
@@ -88,6 +88,16 @@ function writeTosutilConfig(tosutilPath, cred, label) {
88
88
  ], { stdio: 'pipe' });
89
89
  return confPath;
90
90
  }
91
+ /** 把 tosutil 进程的输出按行回放到 stderr,便于线上排查(沙箱里无法 attach 进程)。 */
92
+ function streamTosutilOutput(output) {
93
+ if (!output)
94
+ return;
95
+ for (const line of output.split('\n')) {
96
+ if (line.length === 0)
97
+ continue;
98
+ process.stderr.write(`[tosutil] ${line}\n`);
99
+ }
100
+ }
91
101
  function normalizeTosDest(bucket, prefix) {
92
102
  const bucketPart = bucket.startsWith('tos://') ? bucket : `tos://${bucket}`;
93
103
  const normalized = prefix.replace(/^\/+/, '');
@@ -123,11 +133,14 @@ function uploadDirWithCredential(tosutilPath, sourceDir, cred, label) {
123
133
  '-conf',
124
134
  confPath,
125
135
  ], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
136
+ streamTosutilOutput(output);
126
137
  }
127
138
  catch (err) {
128
139
  const e = err;
129
140
  const stderr = (e.stderr ?? '').trim();
130
141
  const stdout = (e.stdout ?? '').trim();
142
+ streamTosutilOutput(stdout);
143
+ streamTosutilOutput(stderr);
131
144
  throw new error_1.AppError('DEPLOY_UPLOAD_FAILED', `tosutil cp exited with status ${String(e.status ?? -1)} for ${sourceDir}\n` +
132
145
  ` stderr: ${stderr || '(empty)'}\n` +
133
146
  ` stdout: ${stdout.slice(0, 500) || '(empty)'}`);
@@ -27,8 +27,8 @@ function runDeployChecks(projectDir) {
27
27
  const missing = [];
28
28
  if (!meta.appId)
29
29
  missing.push('appId');
30
- if (!meta.template)
31
- missing.push('template');
30
+ if (!meta.stack)
31
+ missing.push('stack');
32
32
  if (missing.length > 0) {
33
33
  issues.push(`.spark/meta.json missing fields: ${missing.join(', ')}`);
34
34
  }
@@ -61,14 +61,14 @@ async function localBuildLocalPublishPipeline(opts) {
61
61
  await (0, index_1.finalizeLocalRelease)(ctx.appId, release.releaseID, index_1.LocalReleaseStatus.Failed);
62
62
  throw err;
63
63
  }
64
- if (release.onlineURL !== undefined && release.onlineURL !== '') {
65
- (0, spark_meta_1.writeSparkMeta)(ctx.projectDir, { ...ctx.meta, appUrl: release.onlineURL });
64
+ if (release.onlineUrl !== undefined && release.onlineUrl !== '') {
65
+ (0, spark_meta_1.writeSparkMeta)(ctx.projectDir, { ...ctx.meta, appUrl: release.onlineUrl });
66
66
  }
67
67
  (0, logger_1.log)('deploy', 'Deployed successfully');
68
68
  return {
69
69
  appId: ctx.appId,
70
70
  version: pre.version,
71
- url: release.onlineURL ?? '',
71
+ url: release.onlineUrl ?? '',
72
72
  releaseID: release.releaseID,
73
73
  preReleaseID: pre.preReleaseID,
74
74
  };
@@ -1,29 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.resolveTemplateKey = resolveTemplateKey;
4
- const error_1 = require("../../../utils/error");
5
4
  /**
6
5
  * 本地 stack 短名 → 后端发布模板 key 的映射。
7
6
  *
8
- * .spark/meta.json.template 存的是脚手架模板短名(vite-react / vue-react / html ...),
7
+ * .spark/meta.json.stack 存的是脚手架模板短名(vite-react / html ...),
9
8
  * 而服务端 preRelease 接受的 templateKey 是"部署类别"维度,由后端 tcc 注册。
10
- * 同一类别的多个脚手架共享一个部署 key(典型:所有纯前端 stack client_local_deploy)。
11
- *
12
- * 加新 stack:在表里加一行;新增类别同步跟后端 tcc 配置对齐。
9
+ * 当前所有支持的 stack 都属于纯前端类别,默认映射到 client_local_deploy
10
+ * 未来出现需要走别的 templateKey 的 stack,再在表里加一行覆盖默认。
13
11
  */
12
+ const DEFAULT_TEMPLATE_KEY = 'client_local_deploy';
14
13
  const TEMPLATE_KEY_MAP = {
15
- 'vite-react': 'client_local_deploy',
16
- 'vue-react': 'client_local_deploy',
14
+ 'vite-react': DEFAULT_TEMPLATE_KEY,
15
+ html: DEFAULT_TEMPLATE_KEY,
17
16
  };
18
17
  /**
19
- * 把本地 stack 短名映射到后端 templateKey。未配置的 stack AppError,
20
- * 避免拿原始短名直接打过去导致后端报"empty"或"出错了"等含糊错误。
18
+ * 把本地 stack 短名映射到后端 templateKey;未配置的 stack 走默认 client_local_deploy。
21
19
  */
22
20
  function resolveTemplateKey(template) {
23
- const key = TEMPLATE_KEY_MAP[template];
24
- if (key === undefined) {
25
- throw new error_1.AppError('DEPLOY_TEMPLATE_KEY_UNMAPPED', `Template "${template}" has no mapping to backend templateKey. ` +
26
- `Known: ${Object.keys(TEMPLATE_KEY_MAP).join(', ')}`);
27
- }
28
- return key;
21
+ return TEMPLATE_KEY_MAP[template] ?? DEFAULT_TEMPLATE_KEY;
29
22
  }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readSkillsStatus = void 0;
4
+ var status_1 = require("./status");
5
+ Object.defineProperty(exports, "readSkillsStatus", { enumerable: true, get: function () { return status_1.readSkillsStatus; } });
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.readSkillsStatus = readSkillsStatus;
7
+ const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ /**
10
+ * 扫描 <targetDir>/.agent/skills/steering/<stack>/,给出"当前装了什么"的快照。
11
+ * 不联网、不解析任何 SKILL.md 内容;只列目录名 + tech.md 是否在。
12
+ *
13
+ * stack 缺省(meta.json 缺 stack)时直接返回 present=false,
14
+ * 让 handler 把"先 init"的引导留给用户。
15
+ */
16
+ function readSkillsStatus(opts) {
17
+ if (opts.stack === undefined || opts.stack === '') {
18
+ return { present: false, skills: [], techSynced: false };
19
+ }
20
+ const root = node_path_1.default.join(opts.targetDir, '.agent', 'skills', 'steering', opts.stack);
21
+ if (!node_fs_1.default.existsSync(root)) {
22
+ return { present: false, skills: [], techSynced: false };
23
+ }
24
+ const skillsDir = node_path_1.default.join(root, 'skills');
25
+ const skills = node_fs_1.default.existsSync(skillsDir)
26
+ ? node_fs_1.default
27
+ .readdirSync(skillsDir, { withFileTypes: true })
28
+ .filter((e) => e.isDirectory())
29
+ .map((e) => e.name)
30
+ .sort()
31
+ : [];
32
+ return {
33
+ present: true,
34
+ skills,
35
+ techSynced: node_fs_1.default.existsSync(node_path_1.default.join(root, 'tech.md')),
36
+ };
37
+ }
@@ -3,14 +3,22 @@ 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.syncSteering = syncSteering;
6
+ exports.syncCodingSteering = syncCodingSteering;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
- const npm_pack_1 = require("../../../utils/npm-pack");
10
- const logger_1 = require("../../../utils/logger");
9
+ const npm_pack_1 = require("../utils/npm-pack");
10
+ const logger_1 = require("../utils/logger");
11
11
  const STEERING_PACKAGE = '@lark-apaas/coding-steering';
12
- function syncSteering(opts) {
13
- (0, logger_1.log)('init', `Fetching ${STEERING_PACKAGE}@${opts.version ?? 'latest'}...`);
12
+ /**
13
+ * coding-steering 包内 _common/skills + <stack>/skills 同步到 <targetDir>/.agent/steering/skills/,
14
+ * 同名 stack 子目录覆盖 _common。tech.md 存在时也同步到 .agent/steering/tech.md。
15
+ *
16
+ * 纯本地 atom(pull npm package + 拷贝文件),不属于任何 cli 域;放在 utils 让
17
+ * app init handler 与独立 skills sync handler 都能复用。
18
+ */
19
+ function syncCodingSteering(opts) {
20
+ const logPrefix = opts.logPrefix ?? 'skills';
21
+ (0, logger_1.log)(logPrefix, `Fetching ${STEERING_PACKAGE}@${opts.version ?? 'latest'}...`);
14
22
  const fetched = (0, npm_pack_1.fetchNpmPackage)({
15
23
  packageName: STEERING_PACKAGE,
16
24
  version: opts.version,
@@ -19,7 +27,10 @@ function syncSteering(opts) {
19
27
  const steeringRoot = node_path_1.default.join(fetched.extractDir, 'steering');
20
28
  const stackDir = node_path_1.default.join(steeringRoot, opts.stack);
21
29
  const commonSkillsDir = node_path_1.default.join(steeringRoot, '_common', 'skills');
22
- const dstRoot = node_path_1.default.join(opts.targetDir, '.agent', 'steering');
30
+ // steering 落到 .agent/skills/steering/<stack>/。.agent/skills/ agent skills 的
31
+ // 公共容器,steering 是其中一个 producer,<stack> 再做命名空间隔离。内部仍保留
32
+ // 包内 steering/<stack>/skills/ 的结构,便于按"包内子目录 → 本地子目录"一一对应排查。
33
+ const dstRoot = node_path_1.default.join(opts.targetDir, '.agent', 'skills', 'steering', opts.stack);
23
34
  const dstSkillsDir = node_path_1.default.join(dstRoot, 'skills');
24
35
  node_fs_1.default.mkdirSync(dstSkillsDir, { recursive: true });
25
36
  let techSynced = false;
@@ -29,7 +40,7 @@ function syncSteering(opts) {
29
40
  techSynced = true;
30
41
  }
31
42
  const synced = [];
32
- // 先拷 _common/skills/,再拷 <stack>/skills/。stack 同名覆盖 common(设计 §8.4)
43
+ // 先拷 _common/skills/,再拷 <stack>/skills/。stack 同名覆盖 common
33
44
  if (node_fs_1.default.existsSync(commonSkillsDir)) {
34
45
  for (const name of node_fs_1.default.readdirSync(commonSkillsDir)) {
35
46
  const src = node_path_1.default.join(commonSkillsDir, name);
@@ -52,7 +63,7 @@ function syncSteering(opts) {
52
63
  synced.push(`${opts.stack}/skills/${name}`);
53
64
  }
54
65
  }
55
- (0, logger_1.log)('init', `Steering synced: ${String(synced.length)} skill(s), tech.md ${techSynced ? 'yes' : 'no'}`);
66
+ (0, logger_1.log)(logPrefix, `Synced ${String(synced.length)} skill(s), tech.md ${techSynced ? 'yes' : 'no'}`);
56
67
  return { version: fetched.version, syncedSkills: synced, techSynced };
57
68
  }
58
69
  finally {
@@ -109,14 +109,14 @@ async function handleInnerEnvelope(response, url, opts) {
109
109
  throw new error_1.HttpError(response.status, url, `${opts.errPrefix}: ${String(response.status)} ${response.statusText}`);
110
110
  }
111
111
  const result = await response.json();
112
+ // verbose: 把完整响应体打到 stderr,便于排查(业务错误 / 字段缺失等)
113
+ if ((0, config_1.getConfig)().verbose) {
114
+ (0, logger_1.debug)(` resp: ${truncateForLog(safeStringify(result), 2000)}`);
115
+ }
112
116
  if (typeof result === 'object' && result !== null && 'status_code' in result) {
113
117
  const env = result;
114
118
  if (env.status_code !== undefined && env.status_code !== '0') {
115
119
  const msg = env.message ?? env.error_msg ?? 'unknown error';
116
- // verbose: 把完整业务错误信封打到 stderr,便于追溯
117
- if ((0, config_1.getConfig)().verbose) {
118
- (0, logger_1.debug)(` envelope: ${truncateForLog(safeStringify(env), 1000)}`);
119
- }
120
120
  const mapped = opts.mapErr?.(env.status_code, msg);
121
121
  if (mapped)
122
122
  throw mapped;
@@ -169,12 +169,8 @@ function logResponseFailure(method, url, err, startMs) {
169
169
  const msgPart = e.message ? ` (${e.message})` : '';
170
170
  (0, logger_1.debug)(`✗ ${method} ${url} ${statusPart} ${String(elapsedMs)}ms${logidPart}${msgPart}`);
171
171
  }
172
- /** BAM gateway 在不同 PSM/版本上 logid 落在不同 header;按命中顺序取第一个非空。 */
173
172
  function pickLogid(headers) {
174
- return (headers.get('x-tt-logid') ??
175
- headers.get('x-logid') ??
176
- headers.get('logid') ??
177
- headers.get('x-tt-trace-tag'));
173
+ return headers.get('x-tt-logid');
178
174
  }
179
175
  function safeStringify(v) {
180
176
  try {
@@ -21,7 +21,7 @@ function readSparkMeta(appDir) {
21
21
  }
22
22
  }
23
23
  /**
24
- * merge 写入:保留已有 createdAt,刷新 updatedAt;undefined 字段不覆盖已有值。
24
+ * merge 写入:已有字段保留,undefined 不覆盖;不再维护时间戳。
25
25
  */
26
26
  function writeSparkMeta(appDir, meta) {
27
27
  const sparkDir = node_path_1.default.join(appDir, SPARK_DIR);
@@ -37,12 +37,6 @@ function writeSparkMeta(appDir, meta) {
37
37
  }
38
38
  }
39
39
  const defined = Object.fromEntries(Object.entries(meta).filter(([, v]) => v !== undefined));
40
- const now = new Date().toISOString();
41
- const merged = {
42
- ...existing,
43
- ...defined,
44
- createdAt: existing.createdAt ?? now,
45
- updatedAt: now,
46
- };
40
+ const merged = { ...existing, ...defined };
47
41
  node_fs_1.default.writeFileSync(metaPath, JSON.stringify(merged, null, 2) + '\n', 'utf-8');
48
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/miaoda-cli",
3
- "version": "0.1.4-alpha.abaa17f",
3
+ "version": "0.1.4-alpha.e76a6d6",
4
4
  "description": "Miaoda 平台命令行工具,面向 Agent 调用",
5
5
  "type": "commonjs",
6
6
  "bin": {