@lark-apaas/miaoda-cli 0.1.38 → 0.1.39-alpha.ba612c9

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 四字段')
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,24 @@ 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 / 非对象 / 字段值非字符串会报错。
52
69
 
53
70
  JSON 输出(stdout)
54
71
  {"data": {"appId": "...", "version": <n>, "url": "...", "releaseID": "...", "preReleaseID": "..."}}
@@ -60,6 +77,8 @@ JSON 输出(stdout)
60
77
  $ miaoda deploy --skip-build
61
78
  $ miaoda deploy --skip-release
62
79
  $ miaoda deploy --conf '{"checkPointVersion":"v3","commitID":"a1b2c3d"}'
80
+ $ miaoda deploy --conf '{"commitID":"a1b2c3d","sessionID":"<uuid>","marker":"编辑保存:修改 index.html"}'
81
+ $ miaoda deploy --update index.html --create assets/new.js --delete old.html
63
82
  `);
64
83
  deployCmd.action((0, shared_1.withHelp)(deployCmd, async (rawOpts) => {
65
84
  await (0, modern_1.handleDeployModern)({
@@ -68,17 +87,18 @@ JSON 输出(stdout)
68
87
  skipBuild: rawOpts.skipBuild,
69
88
  skipRelease: rawOpts.skipRelease,
70
89
  conf: rawOpts.conf,
90
+ creates: rawOpts.create,
91
+ updates: rawOpts.update,
92
+ deletes: rawOpts.delete,
71
93
  });
72
94
  }));
73
95
  const patchCmd = deployCmd
74
96
  .command('patch')
75
97
  .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
98
  .option('--session-id <id>', '会话 ID,发布时透传给下游(可选)')
80
99
  .addHelpText('after', `
81
- --dir 为项目目录(与 deploy 同名参数,默认当前目录)。
100
+ --dir / --create / --update / --delete 声明在父命令 deploy 上,本命令共用,用法不变。
101
+ --dir 为项目目录,默认当前目录。
82
102
  仅支持 design-html(design_local_deploy)。路径为工程根相对路径(= 服务端 latest 下 key),
83
103
  禁绝对路径与 ".."。--create/--update 的本地文件必须存在。改动里含任意 .html(增 / 改 / 删)
84
104
  时自动重算并随包更新 routes.json;纯非 .html 改动不动 routes.json。
@@ -98,9 +118,9 @@ JSON 输出
98
118
  await (0, index_1.handleDeployPatch)({
99
119
  appId: (0, shared_1.resolveAppId)({}),
100
120
  dir: deployCmd.opts().dir ?? '.',
101
- creates: rawOpts.create,
102
- updates: rawOpts.update,
103
- deletes: rawOpts.delete,
121
+ creates: deployCmd.opts().create,
122
+ updates: deployCmd.opts().update,
123
+ deletes: deployCmd.opts().delete,
104
124
  sessionID: rawOpts.sessionId,
105
125
  });
106
126
  }));
@@ -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":"..."} 的 JSON 对象';
13
16
  /**
14
- * 解析 `--conf` JSON string,只取 checkPointVersion / commitID 两个白名单字段。
17
+ * 解析 `--conf` JSON string,只取 checkPointVersion / commitID / sessionID / marker 四个白名单字段。
15
18
  * - 未传 → 返回 {}(行为不变)。
16
19
  * - 非法 JSON / 非 object / 字段值非 string → 抛 DEPLOY_CONF_INVALID。
17
20
  * - 空串字段视为未提供(不进 body,保持可选语义);未知 key 忽略。
@@ -31,7 +34,7 @@ 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 ['checkPointVersion', 'commitID', 'sessionID', 'marker']) {
35
38
  const value = source[key];
36
39
  if (value === undefined)
37
40
  continue;
@@ -43,6 +46,29 @@ function parseDeployConf(raw) {
43
46
  }
44
47
  return conf;
45
48
  }
49
+ /**
50
+ * 解析 `--create` / `--update` / `--delete`,校验路径后组成 PatchChangeSet。
51
+ *
52
+ * 复用 deploy patch 的 normalizeRel(同一套校验:禁绝对路径、禁 ".."、统一为 posix 相对路径),
53
+ * 保证两条链路对「变更文件」的接受范围完全一致,调用方从 patch 迁移不会遇到收紧或放宽。
54
+ *
55
+ * 当前是预留口子:deploy 仍然全量上传,这里只校验并记一行日志,不参与上传决策。
56
+ * 三个参数都没传 → 返回 undefined(与不传时行为完全一致,不产生日志)。
57
+ */
58
+ function parseChangedFiles(opts) {
59
+ const cs = {
60
+ creates: (opts.creates ?? []).map((rel) => (0, index_2.normalizeRel)(rel)),
61
+ updates: (opts.updates ?? []).map((rel) => (0, index_2.normalizeRel)(rel)),
62
+ deletes: (opts.deletes ?? []).map((rel) => (0, index_2.normalizeRel)(rel)),
63
+ };
64
+ const total = cs.creates.length + cs.updates.length + cs.deletes.length;
65
+ if (total === 0)
66
+ return undefined;
67
+ (0, logger_1.log)('deploy', `收到变更文件提示 ${String(total)} 个(create=${String(cs.creates.length)} ` +
68
+ `update=${String(cs.updates.length)} delete=${String(cs.deletes.length)}):` +
69
+ '当前仍为全量上传,未启用增量');
70
+ return cs;
71
+ }
46
72
  /**
47
73
  * miaoda deploy(modern scene 专用,CLI 表面对齐 openclaw-cli)
48
74
  *
@@ -58,6 +84,9 @@ async function handleDeployModern(opts) {
58
84
  skipRelease: opts.skipRelease ?? false,
59
85
  checkPointVersion: conf.checkPointVersion,
60
86
  commitID: conf.commitID,
87
+ sessionID: conf.sessionID,
88
+ marker: conf.marker,
89
+ changedFiles: parseChangedFiles(opts),
61
90
  });
62
91
  (0, output_1.emit)({
63
92
  data: {
@@ -16,6 +16,8 @@ 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,
19
21
  });
20
22
  }
21
23
  /**
@@ -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,12 @@ 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
+ },
32
37
  });
33
38
  try {
34
39
  await (0, index_1.uploadDesignArtifacts)({ projectDir: ctx.projectDir, data });
@@ -45,7 +45,12 @@ 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
+ },
49
54
  });
50
55
  try {
51
56
  (0, logger_1.log)('deploy', 'Uploading artifacts...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lark-apaas/miaoda-cli",
3
- "version": "0.1.38",
3
+ "version": "0.1.39-alpha.ba612c9",
4
4
  "description": "Miaoda 平台命令行工具,面向 Agent 调用",
5
5
  "type": "commonjs",
6
6
  "bin": {
@@ -11,15 +11,6 @@
11
11
  "outDir": "dist/server",
12
12
  "watchAssets": true
13
13
  }
14
- ],
15
- "plugins": [
16
- {
17
- "name": "@nestjs/swagger",
18
- "options": {
19
- "introspectComments": true,
20
- "classValidatorShim": true
21
- }
22
- }
23
14
  ]
24
15
  }
25
- }
16
+ }