@lark-apaas/miaoda-cli 0.1.41 → 0.1.43

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.
@@ -18,7 +18,14 @@ function registerDeployCommandsModern(program) {
18
18
  .option('--dir <path>', '项目目录', '.')
19
19
  .option('--skip-build', '跳过 build 步骤(已构建好时使用)', false)
20
20
  .option('--skip-release', '不创建/更新本地发布单,发布单状态由外部托管', false)
21
- .option('--conf <json>', '关联元信息 JSON,仅识别 checkPointVersion / commitID 两字段')
21
+ .option('--conf <json>', '关联元信息 JSON,仅识别 checkPointVersion / commitID / sessionID / marker / versionLevel 五字段')
22
+ // 这三个 flag 只在父命令声明一份,deploy 与 deploy patch 共用。
23
+ // 不能在 patch 上再声明一遍:commander 遇到父子同名 option 会把值判给父命令,
24
+ // 子命令拿到空数组,`deploy patch --create x` 会静默失效(deploy-patch-wiring 测试可复现)。
25
+ // patch 从 deployCmd.opts() 读,与它今天读 --dir 的方式一致。
26
+ .option('--create <relpath>', '新增文件(可重复)', shared_1.collectRepeatedOption, [])
27
+ .option('--update <relpath>', '修改文件(可重复)', shared_1.collectRepeatedOption, [])
28
+ .option('--delete <relpath>', '删除文件(可重复)', shared_1.collectRepeatedOption, [])
22
29
  .addHelpText('after', `
23
30
  不要用异步模式或后台模式调用 deploy,否则调用可能提前结束,Agent 会误判发布已完成。
24
31
 
@@ -41,14 +48,27 @@ function registerDeployCommandsModern(program) {
41
48
  外部据 stdout 返回的 version / preReleaseID 自行建单,并据本命令的
42
49
  退出码决定把发布单翻成 Finished 还是 Failed —— 失败态由外部负责,CLI 不再兜底。
43
50
  该模式下 releaseID / url 输出为 null(CLI 未建单,无从得知)。
44
- 注意:--conf checkPointVersion / commitID 唯一消费者是 createLocalRelease,
51
+ 注意:--conf 的四个字段唯一消费者是 createLocalRelease,
45
52
  本模式下不生效(静默忽略,不报错),需要关联请在外部建单时自行传递。
46
53
 
54
+ --create / --update / --delete(变更文件清单)
55
+ 可重复,值为工程根相对路径(禁绝对路径与 "..")。deploy patch 消费它做增量发布;
56
+ 在 deploy 下当前是预留口子——只校验路径并记一行日志,不改变上传行为:
57
+ deploy 仍然全量上传产物,latest 每次被重建为工作区的精确镜像(prune 清理远端多余对象),
58
+ 以此保证 git 仓库与 TOS 资源不会不一致。
59
+ 后续若实现增量上传,从这里取「要 PUT 哪些文件」即可,调用方无需改动;
60
+ 删除仍交给 prune,因为 prune 比对的是完整本地清单,与上传了哪些文件无关。
61
+
47
62
  --conf(关联元信息透传)
48
- 值为 JSON string,只识别两个字段,其余 key 忽略:
63
+ 值为 JSON string,只识别四个字段,其余 key 忽略:
49
64
  checkPointVersion 关联的 checkpoint 版本
50
65
  commitID 关联的代码 commit ID
51
- 两字段均可选;非法 JSON / 非对象 / 字段值非字符串会报错。
66
+ sessionID 发起本次发布的页面会话 ID,原样透传不做净化
67
+ marker 本次发布的变更说明,落发布单 description
68
+ 四字段均可选;非法 JSON / 非对象 / 字段值非字符串会报错。
69
+ versionLevel:本次发布的版本档位。"major" 声明这是一个大版本,历史记录里强制开新组;
70
+ "minor" 声明是小版本,即使距上次发布超过聚合阈值也不提升。不传则由服务端按
71
+ 时间间隔自动判定,与改造前行为一致——只有会主动声明档位的链路需要传。
52
72
 
53
73
  JSON 输出(stdout)
54
74
  {"data": {"appId": "...", "version": <n>, "url": "...", "releaseID": "...", "preReleaseID": "..."}}
@@ -60,6 +80,8 @@ JSON 输出(stdout)
60
80
  $ miaoda deploy --skip-build
61
81
  $ miaoda deploy --skip-release
62
82
  $ miaoda deploy --conf '{"checkPointVersion":"v3","commitID":"a1b2c3d"}'
83
+ $ miaoda deploy --conf '{"commitID":"a1b2c3d","sessionID":"<uuid>","marker":"编辑保存:修改 index.html"}'
84
+ $ miaoda deploy --update index.html --create assets/new.js --delete old.html
63
85
  `);
64
86
  deployCmd.action((0, shared_1.withHelp)(deployCmd, async (rawOpts) => {
65
87
  await (0, modern_1.handleDeployModern)({
@@ -68,17 +90,18 @@ JSON 输出(stdout)
68
90
  skipBuild: rawOpts.skipBuild,
69
91
  skipRelease: rawOpts.skipRelease,
70
92
  conf: rawOpts.conf,
93
+ creates: rawOpts.create,
94
+ updates: rawOpts.update,
95
+ deletes: rawOpts.delete,
71
96
  });
72
97
  }));
73
98
  const patchCmd = deployCmd
74
99
  .command('patch')
75
100
  .description('design-html 增量发布:按文件 create/update/delete,.html 变动时同步 routes.json')
76
- .option('--create <relpath>', '新增文件(可重复)', shared_1.collectRepeatedOption, [])
77
- .option('--update <relpath>', '覆盖已有文件(可重复)', shared_1.collectRepeatedOption, [])
78
- .option('--delete <relpath>', '删除文件(可重复)', shared_1.collectRepeatedOption, [])
79
101
  .option('--session-id <id>', '会话 ID,发布时透传给下游(可选)')
80
102
  .addHelpText('after', `
81
- --dir 为项目目录(与 deploy 同名参数,默认当前目录)。
103
+ --dir / --create / --update / --delete 声明在父命令 deploy 上,本命令共用,用法不变。
104
+ --dir 为项目目录,默认当前目录。
82
105
  仅支持 design-html(design_local_deploy)。路径为工程根相对路径(= 服务端 latest 下 key),
83
106
  禁绝对路径与 ".."。--create/--update 的本地文件必须存在。改动里含任意 .html(增 / 改 / 删)
84
107
  时自动重算并随包更新 routes.json;纯非 .html 改动不动 routes.json。
@@ -98,9 +121,9 @@ JSON 输出
98
121
  await (0, index_1.handleDeployPatch)({
99
122
  appId: (0, shared_1.resolveAppId)({}),
100
123
  dir: deployCmd.opts().dir ?? '.',
101
- creates: rawOpts.create,
102
- updates: rawOpts.update,
103
- deletes: rawOpts.delete,
124
+ creates: deployCmd.opts().create,
125
+ updates: deployCmd.opts().update,
126
+ deletes: deployCmd.opts().delete,
104
127
  sessionID: rawOpts.sessionId,
105
128
  });
106
129
  }));
@@ -4,14 +4,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.parseDeployConf = parseDeployConf;
7
+ exports.parseChangedFiles = parseChangedFiles;
7
8
  exports.handleDeployModern = handleDeployModern;
8
9
  const node_path_1 = __importDefault(require("node:path"));
9
10
  const output_1 = require("../../../utils/output");
10
11
  const error_1 = require("../../../utils/error");
11
12
  const index_1 = require("../../../services/deploy/modern/index");
12
- const CONF_EXPECTED = '期望形如 {"checkPointVersion":"...","commitID":"..."} 的 JSON 对象';
13
+ const index_2 = require("../../../services/deploy/modern/patch/index");
14
+ const logger_1 = require("../../../utils/logger");
15
+ const CONF_EXPECTED = '期望形如 {"checkPointVersion":"...","commitID":"...","sessionID":"...","marker":"...","versionLevel":"major"} 的 JSON 对象';
13
16
  /**
14
- * 解析 `--conf` JSON string,只取 checkPointVersion / commitID 两个白名单字段。
17
+ * 解析 `--conf` JSON string,只取 checkPointVersion / commitID / sessionID / marker / versionLevel 五个白名单字段。
15
18
  * - 未传 → 返回 {}(行为不变)。
16
19
  * - 非法 JSON / 非 object / 字段值非 string → 抛 DEPLOY_CONF_INVALID。
17
20
  * - 空串字段视为未提供(不进 body,保持可选语义);未知 key 忽略。
@@ -31,7 +34,13 @@ function parseDeployConf(raw) {
31
34
  }
32
35
  const source = parsed;
33
36
  const conf = {};
34
- for (const key of ['checkPointVersion', 'commitID']) {
37
+ for (const key of [
38
+ 'checkPointVersion',
39
+ 'commitID',
40
+ 'sessionID',
41
+ 'marker',
42
+ 'versionLevel',
43
+ ]) {
35
44
  const value = source[key];
36
45
  if (value === undefined)
37
46
  continue;
@@ -43,6 +52,29 @@ function parseDeployConf(raw) {
43
52
  }
44
53
  return conf;
45
54
  }
55
+ /**
56
+ * 解析 `--create` / `--update` / `--delete`,校验路径后组成 PatchChangeSet。
57
+ *
58
+ * 复用 deploy patch 的 normalizeRel(同一套校验:禁绝对路径、禁 ".."、统一为 posix 相对路径),
59
+ * 保证两条链路对「变更文件」的接受范围完全一致,调用方从 patch 迁移不会遇到收紧或放宽。
60
+ *
61
+ * 当前是预留口子:deploy 仍然全量上传,这里只校验并记一行日志,不参与上传决策。
62
+ * 三个参数都没传 → 返回 undefined(与不传时行为完全一致,不产生日志)。
63
+ */
64
+ function parseChangedFiles(opts) {
65
+ const cs = {
66
+ creates: (opts.creates ?? []).map((rel) => (0, index_2.normalizeRel)(rel)),
67
+ updates: (opts.updates ?? []).map((rel) => (0, index_2.normalizeRel)(rel)),
68
+ deletes: (opts.deletes ?? []).map((rel) => (0, index_2.normalizeRel)(rel)),
69
+ };
70
+ const total = cs.creates.length + cs.updates.length + cs.deletes.length;
71
+ if (total === 0)
72
+ return undefined;
73
+ (0, logger_1.log)('deploy', `收到变更文件提示 ${String(total)} 个(create=${String(cs.creates.length)} ` +
74
+ `update=${String(cs.updates.length)} delete=${String(cs.deletes.length)}):` +
75
+ '当前仍为全量上传,未启用增量');
76
+ return cs;
77
+ }
46
78
  /**
47
79
  * miaoda deploy(modern scene 专用,CLI 表面对齐 openclaw-cli)
48
80
  *
@@ -58,6 +90,10 @@ async function handleDeployModern(opts) {
58
90
  skipRelease: opts.skipRelease ?? false,
59
91
  checkPointVersion: conf.checkPointVersion,
60
92
  commitID: conf.commitID,
93
+ sessionID: conf.sessionID,
94
+ marker: conf.marker,
95
+ versionLevel: conf.versionLevel,
96
+ changedFiles: parseChangedFiles(opts),
61
97
  });
62
98
  (0, output_1.emit)({
63
99
  data: {
@@ -16,6 +16,9 @@ async function createLocalRelease(appId, version, extra) {
16
16
  version,
17
17
  checkPointVersion: extra?.checkPointVersion,
18
18
  commitID: extra?.commitID,
19
+ sessionID: extra?.sessionID,
20
+ description: extra?.marker,
21
+ versionLevel: extra?.versionLevel,
19
22
  });
20
23
  }
21
24
  /**
@@ -3,6 +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.normalizeRel = normalizeRel;
6
7
  exports.buildTosActions = buildTosActions;
7
8
  const node_fs_1 = __importDefault(require("node:fs"));
8
9
  const node_path_1 = __importDefault(require("node:path"));
@@ -10,7 +11,12 @@ const error_1 = require("../../../../utils/error");
10
11
  const index_1 = require("../../../../api/deploy/index");
11
12
  const content_1 = require("./content");
12
13
  const routes_1 = require("./routes");
13
- /** 校验相对路径:禁绝对路径、禁含 ".." 段;normalize 成 posix 相对。 */
14
+ /**
15
+ * 校验相对路径:禁绝对路径、禁含 ".." 段;normalize 成 posix 相对。
16
+ *
17
+ * 导出供 `deploy` 的 `--create` / `--update` / `--delete` 复用同一套校验,
18
+ * 让两条链路对「变更文件」的接受范围一致,避免两处实现漂移。
19
+ */
14
20
  function normalizeRel(rel) {
15
21
  if (node_path_1.default.isAbsolute(rel) || rel.startsWith('/')) {
16
22
  throw new error_1.AppError('ARGS_INVALID', `文件路径不能是绝对路径:${rel}`);
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildTosActions = void 0;
3
+ exports.normalizeRel = exports.buildTosActions = void 0;
4
4
  exports.patchDesignDeploy = patchDesignDeploy;
5
5
  const spark_meta_1 = require("../../../../utils/spark-meta");
6
6
  const error_1 = require("../../../../utils/error");
@@ -10,6 +10,7 @@ const template_key_map_1 = require("../template-key-map");
10
10
  const actions_1 = require("./actions");
11
11
  var actions_2 = require("./actions");
12
12
  Object.defineProperty(exports, "buildTosActions", { enumerable: true, get: function () { return actions_2.buildTosActions; } });
13
+ Object.defineProperty(exports, "normalizeRel", { enumerable: true, get: function () { return actions_2.normalizeRel; } });
13
14
  /**
14
15
  * design-html 增量发布:读本地文件组 TosFileAction(改动含 .html 时带重算的
15
16
  * routes.json),调后端 applyTosDiff 应用到 latest。scope 限 design_local_deploy。
@@ -28,7 +28,13 @@ async function designLocalPublishPipeline(opts) {
28
28
  skipRelease: opts.skipRelease ?? false,
29
29
  appId: ctx.appId,
30
30
  version: pre.version,
31
- extra: { checkPointVersion: opts.checkPointVersion, commitID: opts.commitID },
31
+ extra: {
32
+ checkPointVersion: opts.checkPointVersion,
33
+ commitID: opts.commitID,
34
+ sessionID: opts.sessionID,
35
+ marker: opts.marker,
36
+ versionLevel: opts.versionLevel,
37
+ },
32
38
  });
33
39
  try {
34
40
  await (0, index_1.uploadDesignArtifacts)({ projectDir: ctx.projectDir, data });
@@ -45,7 +45,13 @@ async function localBuildLocalPublishPipeline(opts) {
45
45
  skipRelease: opts.skipRelease ?? false,
46
46
  appId: ctx.appId,
47
47
  version: pre.version,
48
- extra: { checkPointVersion: opts.checkPointVersion, commitID: opts.commitID },
48
+ extra: {
49
+ checkPointVersion: opts.checkPointVersion,
50
+ commitID: opts.commitID,
51
+ sessionID: opts.sessionID,
52
+ marker: opts.marker,
53
+ versionLevel: opts.versionLevel,
54
+ },
49
55
  });
50
56
  try {
51
57
  (0, logger_1.log)('deploy', 'Uploading artifacts...');
@@ -64,13 +64,13 @@ function createClient(opts) {
64
64
  * 默认灰度泳道。当前 miaoda CLI 接入的新接口(modern deploy 等)只在该泳道生效,
65
65
  * 缺省走这个。MIAODA_CANARY_HEADER 可显式覆盖;设为空字符串则去掉头。
66
66
  *
67
- * ⚠️ TEMP(creative-upgrade 联调用):默认泳道临时指向开发泳道 boe_debug_detail_lookup,
68
- * 使 alpha 发版进沙箱镜像后,app export / code-archive 等新接口无需 wrapper 即可命中
69
- * 尚未合流的 studio_server 改动。
70
- * 上线前必须还原为 'boe_miaoda_ccm',或改为由 agent_tool 按请求 x-tt-env 注入
71
- * MIAODA_CANARY_HEADER(详见 http.ts 的 applyCanaryHeader 与 agent_tool ExecShellCmd)。
67
+ * 联调未合流的服务端改动时,不要改这个默认值 —— MIAODA_CANARY_HEADER 覆盖,
68
+ * 或由 agent_tool 按请求 x-tt-env 注入(详见 applyCanaryHeader agent_tool
69
+ * ExecShellCmd)。改默认值意味着所有沙箱都被带去开发泳道,且历史上多次忘记还原
70
+ * (boe_miaoda_doubao ppe_miaoda_ccm boe_miaoda_ccm → boe_debug_detail_lookup
71
+ * boe_creative_history)。
72
72
  */
73
- const DEFAULT_CANARY_HEADER = 'boe_debug_detail_lookup';
73
+ const DEFAULT_CANARY_HEADER = 'prod';
74
74
  /**
75
75
  * 注入 x-tt-env 小流量头:env 显式设值 > DEFAULT_CANARY_HEADER。
76
76
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/miaoda-cli",
3
- "version": "0.1.41",
3
+ "version": "0.1.43",
4
4
  "description": "Miaoda 平台命令行工具,面向 Agent 调用",
5
5
  "type": "commonjs",
6
6
  "bin": {