@clawos-dev/clawd 0.2.564 → 0.2.566

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.
@@ -21632,9 +21632,9 @@ var DeployReleasedSchema = external_exports.object({
21632
21632
  at: external_exports.number()
21633
21633
  }).strict();
21634
21634
  var DeployScanFileSchema = external_exports.object({
21635
- version: external_exports.literal(2),
21635
+ version: external_exports.literal(3),
21636
21636
  scans: external_exports.array(DeployScanSchema),
21637
- released: DeployReleasedSchema.optional()
21637
+ releases: external_exports.array(DeployReleasedSchema)
21638
21638
  }).strict();
21639
21639
  var DeployRepoSchema = external_exports.object({
21640
21640
  url: external_exports.string().min(1),
@@ -21643,10 +21643,11 @@ var DeployRepoSchema = external_exports.object({
21643
21643
  /**
21644
21644
  * persona 的**内容**有没有未提交的改动。
21645
21645
  *
21646
- * **`.clawd/deploy.json` 不算**(daemon 侧 `repoInfo` 把它排出了 pathspec):那个文件是
21647
- * 对 persona 的**断言**——扫描在写、页面上编辑清单也在写。算进来的话每扫一次就把自己
21648
- * 弄脏一次,`isScanFresh` 永远为假、发布再也点不亮。排除的只有这一个文件,
21649
- * `.clawd/` 下别的(persona.json 等)照旧算。
21646
+ * **两个文件不算**(daemon 侧 `repoInfo` 的 `DIRTY_IGNORED` 把它们排出了 pathspec):
21647
+ * - `.clawd/deploy.json`——发布产物,`deploy:release` 那一刻整份重写;算进来的话发布前后那几秒页面会闪「有未提交的改动」
21648
+ * - `.clawd/persona.json`——结构化配置(tool / model / size …),扫描不读它、流水线从发布 commit 读它,改了不需要重扫
21649
+ * (design 2026-09-21-deploy-page-polish §3.4)
21650
+ * `.clawd/` 下别的、以及 persona 的内容(CLAUDE.md / skills / .mcp.json)照旧算。
21650
21651
  */
21651
21652
  dirty: external_exports.boolean(),
21652
21653
  /** 本地领先远端几个提交 */
@@ -21686,13 +21687,13 @@ var DeployStateSchema = external_exports.object({
21686
21687
  repo: DeployRepoSchema.optional(),
21687
21688
  /** 扫描历史,升序,最后一条最新。没扫过就是空数组 */
21688
21689
  scans: external_exports.array(DeployScanSchema).default([]),
21689
- /** 线上正跑的是哪一版;从没发布过就缺席 */
21690
- released: DeployReleasedSchema.optional(),
21690
+ /** 发布历史,升序,最后一条 = 线上正跑的那版。从没发布过就是空数组 */
21691
+ releases: external_exports.array(DeployReleasedSchema).default([]),
21691
21692
  /** 没仓库时缺席(查不了) */
21692
21693
  secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
21693
21694
  /**
21694
- * 最新那次流水线走到哪了。**缺席是常态**:没推过、没授权 GitHub、GitHub 查不到、仓库还没有 run,
21695
- * 都不该让整页打不开——同 `secrets` 的处理。
21695
+ * 流水线走到哪了:不带 `releaseHead` 时是仓库最新那条 run(= 最后一次发布的),带了就是指名那次发布的。
21696
+ * **缺席是常态**:没推过、没授权 GitHub、GitHub 查不到、仓库还没有 run,都不该让整页打不开——同 `secrets` 的处理。
21696
21697
  */
21697
21698
  run: DeployRunSchema.optional(),
21698
21699
  /**
@@ -21708,6 +21709,9 @@ var DeployReleaseResultSchema = external_exports.object({
21708
21709
  var DeployPersonaArgsSchema = external_exports.object({
21709
21710
  personaId: external_exports.string().min(1)
21710
21711
  }).strict();
21712
+ var DeployGetArgsSchema = DeployPersonaArgsSchema.extend({
21713
+ releaseHead: external_exports.string().min(1).optional()
21714
+ }).strict();
21711
21715
  var DeployScanArgsSchema = DeployPersonaArgsSchema.extend({
21712
21716
  scanBase: ScanBaseKindSchema.optional()
21713
21717
  }).strict();
@@ -24194,8 +24198,8 @@ var METHOD_DOCS = {
24194
24198
  },
24195
24199
  // ---- deploy:*(persona 上云:persona 目录 = git 仓库工作树,发布 = 推送触发仓库流水线)----
24196
24200
  "deploy:get": {
24197
- summary: "\u4E0A\u4E91\u9875\u9762\u8981\u7684\u5168\u90E8\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\uFF08git \u73B0\u7B97\uFF09\u3001\u626B\u63CF\u5386\u53F2\uFF08\u6BCF\u6761\u5E26\u6E05\u5355\u5FEB\u7167\uFF09\u3001\u7EBF\u4E0A\u6B63\u8DD1\u7684\u662F\u54EA\u4E00\u7248\u3001\u4ED3\u5E93 Secrets \u91CC\u5404\u53D8\u91CF\u540D\u586B\u8FC7\u6CA1\u6709\uFF08**\u53EA\u6709\u540D\u5B57\u548C\u65F6\u95F4\uFF0C\u6CA1\u6709\u503C**\uFF09\uFF1Bowner-only",
24198
- args: DeployPersonaArgsSchema
24201
+ summary: "\u4E0A\u4E91\u9875\u9762\u8981\u7684\u5168\u90E8\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\uFF08git \u73B0\u7B97\uFF09\u3001\u626B\u63CF\u5386\u53F2\uFF08\u6BCF\u6761\u5E26\u6E05\u5355\u5FEB\u7167\uFF09\u3001\u53D1\u5E03\u5386\u53F2\uFF08\u6700\u540E\u4E00\u6761 = \u7EBF\u4E0A\u6B63\u8DD1\u7684\uFF09\u3001\u4ED3\u5E93 Secrets \u91CC\u5404\u53D8\u91CF\u540D\u586B\u8FC7\u6CA1\u6709\uFF08**\u53EA\u6709\u540D\u5B57\u548C\u65F6\u95F4\uFF0C\u6CA1\u6709\u503C**\uFF09\u3001\u4E00\u6761\u6D41\u6C34\u7EBF\u72B6\u6001\uFF08\u7F3A\u7701\u4ED3\u5E93\u6700\u65B0\u90A3\u6761\uFF1B`releaseHead` \u6307\u540D\u770B\u54EA\u6B21\u53D1\u5E03\u7684\uFF09\uFF1Bowner-only",
24202
+ args: DeployGetArgsSchema
24199
24203
  },
24200
24204
  "deploy:scan": {
24201
24205
  summary: "\u8D77\u4E00\u6B21\u626B\u63CF\u3002**\u6CA1\u4ED3\u5E93\u5148\u5EFA\u4ED3**\uFF08GitHub REST \u5EFA\u5728\u7EC4\u7EC7\u4E0B\u3001\u79C1\u6709\uFF0Cgit \u63A8\u9996\u4E2A\u63D0\u4EA4\uFF1Btoken \u6765\u81EA\u672C\u673A git \u7684\u8EAB\u4EFD\uFF0C\u6CA1\u6388\u6743\u5148\u62D2\uFF09\u3002\u628A persona \u76EE\u5F55\u63D0\u4EA4\u5230\u672C\u5730\uFF08\u4E0D\u63A8\uFF09\u3001\u5728\u626B\u63CF\u5386\u53F2\u91CC\u8FFD\u52A0\u4E00\u6761\u3001\u8D77 persona-butler \u7684\u626B\u63CF\u4F1A\u8BDD\uFF1B\u6B63\u5728\u626B\u7684\u8BDD\u539F\u6837\u8FD4\u56DE\u4E0D\u8D77\u7B2C\u4E8C\u4E2A\u4F1A\u8BDD\u3002\u5E26 scanBase\uFF08hard / soft\uFF09\u6309\u8BE5\u6863\u4F4D\u626B\uFF08soft \u4E0D\u6210\u7ACB\u81EA\u52A8\u9000 hard\uFF09\uFF0C\u7F3A\u5E2D daemon \u81EA\u52A8\u5B9A\uFF1Bowner-only",
@@ -24787,6 +24791,7 @@ var CliConnectorFindingSchema = external_exports.object({
24787
24791
  var DEPLOY_FILE = import_node_path3.default.join(".clawd", "deploy.json");
24788
24792
  var SCAN_FILE = import_node_path3.default.join(".clawd", "deploy-scan.json");
24789
24793
  var z1 = DeployScanSchema.omit({ id: true, manifest: true }).extend({ releasedHead: DeployScanSchema.shape.head }).strict();
24794
+ var z2 = external_exports.object({ version: external_exports.literal(2), scans: external_exports.array(DeployScanSchema), released: DeployReleasedSchema.optional() }).strict();
24790
24795
 
24791
24796
  // src/deploy/templates.ts
24792
24797
  var CLAWOS_REPO = "ottin4ttc/clawos";
package/dist/cli.cjs CHANGED
@@ -6116,7 +6116,7 @@ function cloudEngineOk(tool) {
6116
6116
  function repoSlug(url) {
6117
6117
  return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
6118
6118
  }
6119
- var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployStateSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6119
+ var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployStateSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6120
6120
  var init_deploy_schemas = __esm({
6121
6121
  "../protocol/src/deploy-schemas.ts"() {
6122
6122
  "use strict";
@@ -6176,9 +6176,9 @@ var init_deploy_schemas = __esm({
6176
6176
  at: external_exports.number()
6177
6177
  }).strict();
6178
6178
  DeployScanFileSchema = external_exports.object({
6179
- version: external_exports.literal(2),
6179
+ version: external_exports.literal(3),
6180
6180
  scans: external_exports.array(DeployScanSchema),
6181
- released: DeployReleasedSchema.optional()
6181
+ releases: external_exports.array(DeployReleasedSchema)
6182
6182
  }).strict();
6183
6183
  DeployRepoSchema = external_exports.object({
6184
6184
  url: external_exports.string().min(1),
@@ -6187,10 +6187,11 @@ var init_deploy_schemas = __esm({
6187
6187
  /**
6188
6188
  * persona 的**内容**有没有未提交的改动。
6189
6189
  *
6190
- * **`.clawd/deploy.json` 不算**(daemon 侧 `repoInfo` 把它排出了 pathspec):那个文件是
6191
- * 对 persona 的**断言**——扫描在写、页面上编辑清单也在写。算进来的话每扫一次就把自己
6192
- * 弄脏一次,`isScanFresh` 永远为假、发布再也点不亮。排除的只有这一个文件,
6193
- * `.clawd/` 下别的(persona.json 等)照旧算。
6190
+ * **两个文件不算**(daemon 侧 `repoInfo` 的 `DIRTY_IGNORED` 把它们排出了 pathspec):
6191
+ * - `.clawd/deploy.json`——发布产物,`deploy:release` 那一刻整份重写;算进来的话发布前后那几秒页面会闪「有未提交的改动」
6192
+ * - `.clawd/persona.json`——结构化配置(tool / model / size …),扫描不读它、流水线从发布 commit 读它,改了不需要重扫
6193
+ * (design 2026-09-21-deploy-page-polish §3.4)
6194
+ * `.clawd/` 下别的、以及 persona 的内容(CLAUDE.md / skills / .mcp.json)照旧算。
6194
6195
  */
6195
6196
  dirty: external_exports.boolean(),
6196
6197
  /** 本地领先远端几个提交 */
@@ -6231,13 +6232,13 @@ var init_deploy_schemas = __esm({
6231
6232
  repo: DeployRepoSchema.optional(),
6232
6233
  /** 扫描历史,升序,最后一条最新。没扫过就是空数组 */
6233
6234
  scans: external_exports.array(DeployScanSchema).default([]),
6234
- /** 线上正跑的是哪一版;从没发布过就缺席 */
6235
- released: DeployReleasedSchema.optional(),
6235
+ /** 发布历史,升序,最后一条 = 线上正跑的那版。从没发布过就是空数组 */
6236
+ releases: external_exports.array(DeployReleasedSchema).default([]),
6236
6237
  /** 没仓库时缺席(查不了) */
6237
6238
  secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
6238
6239
  /**
6239
- * 最新那次流水线走到哪了。**缺席是常态**:没推过、没授权 GitHub、GitHub 查不到、仓库还没有 run,
6240
- * 都不该让整页打不开——同 `secrets` 的处理。
6240
+ * 流水线走到哪了:不带 `releaseHead` 时是仓库最新那条 run(= 最后一次发布的),带了就是指名那次发布的。
6241
+ * **缺席是常态**:没推过、没授权 GitHub、GitHub 查不到、仓库还没有 run,都不该让整页打不开——同 `secrets` 的处理。
6241
6242
  */
6242
6243
  run: DeployRunSchema.optional(),
6243
6244
  /**
@@ -6253,6 +6254,9 @@ var init_deploy_schemas = __esm({
6253
6254
  DeployPersonaArgsSchema = external_exports.object({
6254
6255
  personaId: external_exports.string().min(1)
6255
6256
  }).strict();
6257
+ DeployGetArgsSchema = DeployPersonaArgsSchema.extend({
6258
+ releaseHead: external_exports.string().min(1).optional()
6259
+ }).strict();
6256
6260
  DeployScanArgsSchema = DeployPersonaArgsSchema.extend({
6257
6261
  scanBase: ScanBaseKindSchema.optional()
6258
6262
  }).strict();
@@ -9024,8 +9028,8 @@ var init_methods = __esm({
9024
9028
  },
9025
9029
  // ---- deploy:*(persona 上云:persona 目录 = git 仓库工作树,发布 = 推送触发仓库流水线)----
9026
9030
  "deploy:get": {
9027
- summary: "\u4E0A\u4E91\u9875\u9762\u8981\u7684\u5168\u90E8\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\uFF08git \u73B0\u7B97\uFF09\u3001\u626B\u63CF\u5386\u53F2\uFF08\u6BCF\u6761\u5E26\u6E05\u5355\u5FEB\u7167\uFF09\u3001\u7EBF\u4E0A\u6B63\u8DD1\u7684\u662F\u54EA\u4E00\u7248\u3001\u4ED3\u5E93 Secrets \u91CC\u5404\u53D8\u91CF\u540D\u586B\u8FC7\u6CA1\u6709\uFF08**\u53EA\u6709\u540D\u5B57\u548C\u65F6\u95F4\uFF0C\u6CA1\u6709\u503C**\uFF09\uFF1Bowner-only",
9028
- args: DeployPersonaArgsSchema
9031
+ summary: "\u4E0A\u4E91\u9875\u9762\u8981\u7684\u5168\u90E8\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\uFF08git \u73B0\u7B97\uFF09\u3001\u626B\u63CF\u5386\u53F2\uFF08\u6BCF\u6761\u5E26\u6E05\u5355\u5FEB\u7167\uFF09\u3001\u53D1\u5E03\u5386\u53F2\uFF08\u6700\u540E\u4E00\u6761 = \u7EBF\u4E0A\u6B63\u8DD1\u7684\uFF09\u3001\u4ED3\u5E93 Secrets \u91CC\u5404\u53D8\u91CF\u540D\u586B\u8FC7\u6CA1\u6709\uFF08**\u53EA\u6709\u540D\u5B57\u548C\u65F6\u95F4\uFF0C\u6CA1\u6709\u503C**\uFF09\u3001\u4E00\u6761\u6D41\u6C34\u7EBF\u72B6\u6001\uFF08\u7F3A\u7701\u4ED3\u5E93\u6700\u65B0\u90A3\u6761\uFF1B`releaseHead` \u6307\u540D\u770B\u54EA\u6B21\u53D1\u5E03\u7684\uFF09\uFF1Bowner-only",
9032
+ args: DeployGetArgsSchema
9029
9033
  },
9030
9034
  "deploy:scan": {
9031
9035
  summary: "\u8D77\u4E00\u6B21\u626B\u63CF\u3002**\u6CA1\u4ED3\u5E93\u5148\u5EFA\u4ED3**\uFF08GitHub REST \u5EFA\u5728\u7EC4\u7EC7\u4E0B\u3001\u79C1\u6709\uFF0Cgit \u63A8\u9996\u4E2A\u63D0\u4EA4\uFF1Btoken \u6765\u81EA\u672C\u673A git \u7684\u8EAB\u4EFD\uFF0C\u6CA1\u6388\u6743\u5148\u62D2\uFF09\u3002\u628A persona \u76EE\u5F55\u63D0\u4EA4\u5230\u672C\u5730\uFF08\u4E0D\u63A8\uFF09\u3001\u5728\u626B\u63CF\u5386\u53F2\u91CC\u8FFD\u52A0\u4E00\u6761\u3001\u8D77 persona-butler \u7684\u626B\u63CF\u4F1A\u8BDD\uFF1B\u6B63\u5728\u626B\u7684\u8BDD\u539F\u6837\u8FD4\u56DE\u4E0D\u8D77\u7B2C\u4E8C\u4E2A\u4F1A\u8BDD\u3002\u5E26 scanBase\uFF08hard / soft\uFF09\u6309\u8BE5\u6863\u4F4D\u626B\uFF08soft \u4E0D\u6210\u7ACB\u81EA\u52A8\u9000 hard\uFF09\uFF0C\u7F3A\u5E2D daemon \u81EA\u52A8\u5B9A\uFF1Bowner-only",
@@ -22583,17 +22587,17 @@ var require_luxon = __commonJS({
22583
22587
  constructor(dt2, intl, opts) {
22584
22588
  this.opts = opts;
22585
22589
  this.originalZone = void 0;
22586
- let z3 = void 0;
22590
+ let z4 = void 0;
22587
22591
  if (this.opts.timeZone) {
22588
22592
  this.dt = dt2;
22589
22593
  } else if (dt2.zone.type === "fixed") {
22590
22594
  const gmtOffset = -1 * (dt2.offset / 60);
22591
22595
  const offsetZ = gmtOffset >= 0 ? `Etc/GMT+${gmtOffset}` : `Etc/GMT${gmtOffset}`;
22592
22596
  if (dt2.offset !== 0 && IANAZone.create(offsetZ).valid) {
22593
- z3 = offsetZ;
22597
+ z4 = offsetZ;
22594
22598
  this.dt = dt2;
22595
22599
  } else {
22596
- z3 = "UTC";
22600
+ z4 = "UTC";
22597
22601
  this.dt = dt2.offset === 0 ? dt2 : dt2.setZone("UTC").plus({
22598
22602
  minutes: dt2.offset
22599
22603
  });
@@ -22603,9 +22607,9 @@ var require_luxon = __commonJS({
22603
22607
  this.dt = dt2;
22604
22608
  } else if (dt2.zone.type === "iana") {
22605
22609
  this.dt = dt2;
22606
- z3 = dt2.zone.name;
22610
+ z4 = dt2.zone.name;
22607
22611
  } else {
22608
- z3 = "UTC";
22612
+ z4 = "UTC";
22609
22613
  this.dt = dt2.setZone("UTC").plus({
22610
22614
  minutes: dt2.offset
22611
22615
  });
@@ -22614,7 +22618,7 @@ var require_luxon = __commonJS({
22614
22618
  const intlOpts = {
22615
22619
  ...this.opts
22616
22620
  };
22617
- intlOpts.timeZone = intlOpts.timeZone || z3;
22621
+ intlOpts.timeZone = intlOpts.timeZone || z4;
22618
22622
  this.dtf = getCachedDTF(intl, intlOpts);
22619
22623
  }
22620
22624
  format() {
@@ -55365,6 +55369,7 @@ function redactEvidence(evidence) {
55365
55369
  var import_promises4 = __toESM(require("fs/promises"), 1);
55366
55370
  var import_node_path33 = __toESM(require("path"), 1);
55367
55371
  var import_node_crypto8 = require("crypto");
55372
+ init_zod();
55368
55373
  init_protocol();
55369
55374
 
55370
55375
  // src/deploy/connectors.ts
@@ -55567,7 +55572,7 @@ async function restoreDeployFileRaw(dir, raw) {
55567
55572
  if (raw === void 0) await import_promises4.default.rm(file, { force: true });
55568
55573
  else await import_promises4.default.writeFile(file, raw);
55569
55574
  }
55570
- var emptyScanFile = () => ({ version: 2, scans: [] });
55575
+ var emptyScanFile = () => ({ version: 3, scans: [], releases: [] });
55571
55576
  var LEGACY_SCAN_ID = "legacy";
55572
55577
  var newScanId = () => (0, import_node_crypto8.randomBytes)(4).toString("hex");
55573
55578
  var z1 = DeployScanSchema.omit({ id: true, manifest: true }).extend({ releasedHead: DeployScanSchema.shape.head }).strict();
@@ -55575,11 +55580,16 @@ function migrateV1(v1, manifest) {
55575
55580
  const { releasedHead, ...rest } = v1;
55576
55581
  const entry = { ...rest, id: LEGACY_SCAN_ID, manifest: manifest ?? emptyDeployFile().manifest };
55577
55582
  return {
55578
- version: 2,
55583
+ version: 3,
55579
55584
  scans: [entry],
55580
- ...releasedHead ? { released: { head: releasedHead, contentHead: releasedHead, scanId: LEGACY_SCAN_ID, at: v1.head === releasedHead ? v1.finishedAt ?? v1.startedAt : 0 } } : {}
55585
+ releases: releasedHead ? [{ head: releasedHead, contentHead: releasedHead, scanId: LEGACY_SCAN_ID, at: v1.head === releasedHead ? v1.finishedAt ?? v1.startedAt : 0 }] : []
55581
55586
  };
55582
55587
  }
55588
+ var z2 = external_exports.object({ version: external_exports.literal(2), scans: external_exports.array(DeployScanSchema), released: DeployReleasedSchema.optional() }).strict();
55589
+ function migrateV2(v22) {
55590
+ const { released, ...rest } = v22;
55591
+ return { ...rest, version: 3, releases: released ? [released] : [] };
55592
+ }
55583
55593
  function normalizeLegacyScan(raw) {
55584
55594
  const fix = (o2) => {
55585
55595
  if (!o2 || typeof o2 !== "object") return o2;
@@ -55610,6 +55620,11 @@ async function readScanFile(dir) {
55610
55620
  if (!v1.success) throw badShape(v1.error.issues);
55611
55621
  return migrateV1(v1.data, (await readDeployFile(dir).catch(() => void 0))?.manifest);
55612
55622
  }
55623
+ if (typeof raw === "object" && raw !== null && raw.version === 2) {
55624
+ const v22 = z2.safeParse(raw);
55625
+ if (!v22.success) throw badShape(v22.error.issues);
55626
+ return migrateV2(v22.data);
55627
+ }
55613
55628
  const parsed = DeployScanFileSchema.safeParse(raw);
55614
55629
  if (!parsed.success) throw badShape(parsed.error.issues);
55615
55630
  return parsed.data;
@@ -55881,7 +55896,7 @@ var s = (null != a ? a({ getRandomValue: function() {
55881
55896
  }) : Promise.reject(new Error("Unsupported libsodium ESM export shape"))).then(function(e) {
55882
55897
  r = e, t.libsodium = r, (function() {
55883
55898
  if (r._sodium_init() < 0) throw new Error("libsodium was not correctly initialized.");
55884
- for (var e2 = ["crypto_aead_aegis128l_decrypt", "crypto_aead_aegis128l_decrypt_detached", "crypto_aead_aegis128l_encrypt", "crypto_aead_aegis128l_encrypt_detached", "crypto_aead_aegis128l_keygen", "crypto_aead_aegis256_decrypt", "crypto_aead_aegis256_decrypt_detached", "crypto_aead_aegis256_encrypt", "crypto_aead_aegis256_encrypt_detached", "crypto_aead_aegis256_keygen", "crypto_aead_chacha20poly1305_decrypt", "crypto_aead_chacha20poly1305_decrypt_detached", "crypto_aead_chacha20poly1305_encrypt", "crypto_aead_chacha20poly1305_encrypt_detached", "crypto_aead_chacha20poly1305_ietf_decrypt", "crypto_aead_chacha20poly1305_ietf_decrypt_detached", "crypto_aead_chacha20poly1305_ietf_encrypt", "crypto_aead_chacha20poly1305_ietf_encrypt_detached", "crypto_aead_chacha20poly1305_ietf_keygen", "crypto_aead_chacha20poly1305_keygen", "crypto_aead_xchacha20poly1305_ietf_decrypt", "crypto_aead_xchacha20poly1305_ietf_decrypt_detached", "crypto_aead_xchacha20poly1305_ietf_encrypt", "crypto_aead_xchacha20poly1305_ietf_encrypt_detached", "crypto_aead_xchacha20poly1305_ietf_keygen", "crypto_auth", "crypto_auth_hmacsha256", "crypto_auth_hmacsha256_final", "crypto_auth_hmacsha256_init", "crypto_auth_hmacsha256_keygen", "crypto_auth_hmacsha256_update", "crypto_auth_hmacsha256_verify", "crypto_auth_hmacsha512", "crypto_auth_hmacsha512256", "crypto_auth_hmacsha512256_final", "crypto_auth_hmacsha512256_init", "crypto_auth_hmacsha512256_keygen", "crypto_auth_hmacsha512256_update", "crypto_auth_hmacsha512256_verify", "crypto_auth_hmacsha512_final", "crypto_auth_hmacsha512_init", "crypto_auth_hmacsha512_keygen", "crypto_auth_hmacsha512_update", "crypto_auth_hmacsha512_verify", "crypto_auth_keygen", "crypto_auth_verify", "crypto_box_beforenm", "crypto_box_curve25519xchacha20poly1305_beforenm", "crypto_box_curve25519xchacha20poly1305_detached", "crypto_box_curve25519xchacha20poly1305_detached_afternm", "crypto_box_curve25519xchacha20poly1305_easy", "crypto_box_curve25519xchacha20poly1305_easy_afternm", "crypto_box_curve25519xchacha20poly1305_keypair", "crypto_box_curve25519xchacha20poly1305_open_detached", "crypto_box_curve25519xchacha20poly1305_open_detached_afternm", "crypto_box_curve25519xchacha20poly1305_open_easy", "crypto_box_curve25519xchacha20poly1305_open_easy_afternm", "crypto_box_curve25519xchacha20poly1305_seal", "crypto_box_curve25519xchacha20poly1305_seal_open", "crypto_box_curve25519xchacha20poly1305_seed_keypair", "crypto_box_detached", "crypto_box_easy", "crypto_box_easy_afternm", "crypto_box_keypair", "crypto_box_open_detached", "crypto_box_open_easy", "crypto_box_open_easy_afternm", "crypto_box_seal", "crypto_box_seal_open", "crypto_box_seed_keypair", "crypto_core_ed25519_add", "crypto_core_ed25519_from_hash", "crypto_core_ed25519_from_uniform", "crypto_core_ed25519_is_valid_point", "crypto_core_ed25519_random", "crypto_core_ed25519_scalar_add", "crypto_core_ed25519_scalar_complement", "crypto_core_ed25519_scalar_invert", "crypto_core_ed25519_scalar_mul", "crypto_core_ed25519_scalar_negate", "crypto_core_ed25519_scalar_random", "crypto_core_ed25519_scalar_reduce", "crypto_core_ed25519_scalar_sub", "crypto_core_ed25519_sub", "crypto_core_hchacha20", "crypto_core_hsalsa20", "crypto_core_ristretto255_add", "crypto_core_ristretto255_from_hash", "crypto_core_ristretto255_is_valid_point", "crypto_core_ristretto255_random", "crypto_core_ristretto255_scalar_add", "crypto_core_ristretto255_scalar_complement", "crypto_core_ristretto255_scalar_invert", "crypto_core_ristretto255_scalar_mul", "crypto_core_ristretto255_scalar_negate", "crypto_core_ristretto255_scalar_random", "crypto_core_ristretto255_scalar_reduce", "crypto_core_ristretto255_scalar_sub", "crypto_core_ristretto255_sub", "crypto_generichash", "crypto_generichash_blake2b_salt_personal", "crypto_generichash_final", "crypto_generichash_init", "crypto_generichash_keygen", "crypto_generichash_update", "crypto_hash", "crypto_hash_sha256", "crypto_hash_sha256_final", "crypto_hash_sha256_init", "crypto_hash_sha256_update", "crypto_hash_sha3256", "crypto_hash_sha3256_final", "crypto_hash_sha3256_init", "crypto_hash_sha3256_update", "crypto_hash_sha3512", "crypto_hash_sha3512_final", "crypto_hash_sha3512_init", "crypto_hash_sha3512_update", "crypto_hash_sha512", "crypto_hash_sha512_final", "crypto_hash_sha512_init", "crypto_hash_sha512_update", "crypto_ipcrypt_decrypt", "crypto_ipcrypt_encrypt", "crypto_ipcrypt_keygen", "crypto_ipcrypt_nd_decrypt", "crypto_ipcrypt_nd_encrypt", "crypto_ipcrypt_nd_keygen", "crypto_ipcrypt_ndx_decrypt", "crypto_ipcrypt_ndx_encrypt", "crypto_ipcrypt_ndx_keygen", "crypto_ipcrypt_pfx_decrypt", "crypto_ipcrypt_pfx_encrypt", "crypto_ipcrypt_pfx_keygen", "crypto_kdf_derive_from_key", "crypto_kdf_keygen", "crypto_kem_dec", "crypto_kem_enc", "crypto_kem_keypair", "crypto_kem_mlkem768_dec", "crypto_kem_mlkem768_enc", "crypto_kem_mlkem768_enc_deterministic", "crypto_kem_mlkem768_keypair", "crypto_kem_mlkem768_seed_keypair", "crypto_kem_primitive", "crypto_kem_seed_keypair", "crypto_kem_xwing_dec", "crypto_kem_xwing_enc", "crypto_kem_xwing_enc_deterministic", "crypto_kem_xwing_keypair", "crypto_kem_xwing_seed_keypair", "crypto_kx_client_session_keys", "crypto_kx_keypair", "crypto_kx_seed_keypair", "crypto_kx_server_session_keys", "crypto_onetimeauth", "crypto_onetimeauth_final", "crypto_onetimeauth_init", "crypto_onetimeauth_keygen", "crypto_onetimeauth_update", "crypto_onetimeauth_verify", "crypto_pwhash", "crypto_pwhash_scryptsalsa208sha256", "crypto_pwhash_scryptsalsa208sha256_ll", "crypto_pwhash_scryptsalsa208sha256_str", "crypto_pwhash_scryptsalsa208sha256_str_verify", "crypto_pwhash_str", "crypto_pwhash_str_needs_rehash", "crypto_pwhash_str_verify", "crypto_scalarmult", "crypto_scalarmult_base", "crypto_scalarmult_ed25519", "crypto_scalarmult_ed25519_base", "crypto_scalarmult_ed25519_base_noclamp", "crypto_scalarmult_ed25519_noclamp", "crypto_scalarmult_ristretto255", "crypto_scalarmult_ristretto255_base", "crypto_secretbox_detached", "crypto_secretbox_easy", "crypto_secretbox_keygen", "crypto_secretbox_open_detached", "crypto_secretbox_open_easy", "crypto_secretstream_xchacha20poly1305_init_pull", "crypto_secretstream_xchacha20poly1305_init_push", "crypto_secretstream_xchacha20poly1305_keygen", "crypto_secretstream_xchacha20poly1305_pull", "crypto_secretstream_xchacha20poly1305_push", "crypto_secretstream_xchacha20poly1305_rekey", "crypto_shorthash", "crypto_shorthash_keygen", "crypto_shorthash_siphashx24", "crypto_sign", "crypto_sign_detached", "crypto_sign_ed25519_pk_to_curve25519", "crypto_sign_ed25519_sk_to_curve25519", "crypto_sign_ed25519_sk_to_pk", "crypto_sign_ed25519_sk_to_seed", "crypto_sign_final_create", "crypto_sign_final_verify", "crypto_sign_init", "crypto_sign_keypair", "crypto_sign_open", "crypto_sign_seed_keypair", "crypto_sign_update", "crypto_sign_verify_detached", "crypto_stream_chacha20", "crypto_stream_chacha20_ietf_xor", "crypto_stream_chacha20_ietf_xor_ic", "crypto_stream_chacha20_keygen", "crypto_stream_chacha20_xor", "crypto_stream_chacha20_xor_ic", "crypto_stream_keygen", "crypto_stream_xchacha20_keygen", "crypto_stream_xchacha20_xor", "crypto_stream_xchacha20_xor_ic", "crypto_xof_shake128", "crypto_xof_shake128_init", "crypto_xof_shake128_init_with_domain", "crypto_xof_shake128_squeeze", "crypto_xof_shake128_update", "crypto_xof_shake256", "crypto_xof_shake256_init", "crypto_xof_shake256_init_with_domain", "crypto_xof_shake256_squeeze", "crypto_xof_shake256_update", "crypto_xof_turboshake128", "crypto_xof_turboshake128_init", "crypto_xof_turboshake128_init_with_domain", "crypto_xof_turboshake128_squeeze", "crypto_xof_turboshake128_update", "crypto_xof_turboshake256", "crypto_xof_turboshake256_init", "crypto_xof_turboshake256_init_with_domain", "crypto_xof_turboshake256_squeeze", "crypto_xof_turboshake256_update", "randombytes_buf", "randombytes_buf_deterministic", "randombytes_close", "randombytes_random", "randombytes_set_implementation", "randombytes_stir", "randombytes_uniform", "sodium_bin2ip", "sodium_ip2bin", "sodium_version_string"], a3 = [C, R, P, X, D2, G, F2, V, q, H, z2, W, j, J, Q, Z, $2, ee, re, te, ae, _e, ne, se, ce, pe, oe, he, ye, ie, le, ue, de, ve, ge, be, fe, me, ke, xe, Ee, Te, Se, we, Ye, Be, Ke, Ae, Ie, Me, Ne, Le, Ue, Oe, Ce, Re, Pe, Xe, De, Ge, Fe, Ve, qe, He, ze, We, je, Je, Qe, Ze, $e, er, rr, tr, ar, _r, nr, sr, cr, pr, or, hr, yr, ir, lr, ur, dr, vr, gr, br, fr, mr, kr, xr, Er, Tr, Sr, wr, Yr, Br, Kr, Ar, Ir, Mr, Nr, Lr, Ur, Or, Cr, Rr, Pr, Xr, Dr, Gr, Fr, Vr, qr, Hr, zr, Wr, jr, Jr, Qr, Zr, $r, et, rt, tt, at, _t, nt, st, ct, pt, ot, ht, yt, it, lt, ut, dt, vt, gt, bt, ft, mt, kt, xt, Et, Tt, St, wt, Yt, Bt, Kt, At, It, Mt, Nt, Lt, Ut, Ot, Ct, Rt, Pt, Xt, Dt, Gt, Ft, Vt, qt, Ht, zt, Wt, jt, Jt, Qt, Zt, $t, ea, ra, ta, aa, _a, na, sa, ca, pa, oa, ha, ya, ia, la, ua, da, va, ga, ba, fa, ma, ka, xa, Ea, Ta, Sa, wa, Ya, Ba, Ka, Aa, Ia, Ma, Na, La, Ua, Oa, Ca, Ra, Pa, Xa, Da, Ga, Fa, Va, qa, Ha, za, Wa, ja, Ja, Qa, Za, $a, e_, r_, t_, a_, __, n_, s_, c_, p_, o_, h_, y_], _4 = 0; _4 < a3.length; _4++) "function" == typeof r["_" + e2[_4]] && (t[e2[_4]] = a3[_4]);
55899
+ for (var e2 = ["crypto_aead_aegis128l_decrypt", "crypto_aead_aegis128l_decrypt_detached", "crypto_aead_aegis128l_encrypt", "crypto_aead_aegis128l_encrypt_detached", "crypto_aead_aegis128l_keygen", "crypto_aead_aegis256_decrypt", "crypto_aead_aegis256_decrypt_detached", "crypto_aead_aegis256_encrypt", "crypto_aead_aegis256_encrypt_detached", "crypto_aead_aegis256_keygen", "crypto_aead_chacha20poly1305_decrypt", "crypto_aead_chacha20poly1305_decrypt_detached", "crypto_aead_chacha20poly1305_encrypt", "crypto_aead_chacha20poly1305_encrypt_detached", "crypto_aead_chacha20poly1305_ietf_decrypt", "crypto_aead_chacha20poly1305_ietf_decrypt_detached", "crypto_aead_chacha20poly1305_ietf_encrypt", "crypto_aead_chacha20poly1305_ietf_encrypt_detached", "crypto_aead_chacha20poly1305_ietf_keygen", "crypto_aead_chacha20poly1305_keygen", "crypto_aead_xchacha20poly1305_ietf_decrypt", "crypto_aead_xchacha20poly1305_ietf_decrypt_detached", "crypto_aead_xchacha20poly1305_ietf_encrypt", "crypto_aead_xchacha20poly1305_ietf_encrypt_detached", "crypto_aead_xchacha20poly1305_ietf_keygen", "crypto_auth", "crypto_auth_hmacsha256", "crypto_auth_hmacsha256_final", "crypto_auth_hmacsha256_init", "crypto_auth_hmacsha256_keygen", "crypto_auth_hmacsha256_update", "crypto_auth_hmacsha256_verify", "crypto_auth_hmacsha512", "crypto_auth_hmacsha512256", "crypto_auth_hmacsha512256_final", "crypto_auth_hmacsha512256_init", "crypto_auth_hmacsha512256_keygen", "crypto_auth_hmacsha512256_update", "crypto_auth_hmacsha512256_verify", "crypto_auth_hmacsha512_final", "crypto_auth_hmacsha512_init", "crypto_auth_hmacsha512_keygen", "crypto_auth_hmacsha512_update", "crypto_auth_hmacsha512_verify", "crypto_auth_keygen", "crypto_auth_verify", "crypto_box_beforenm", "crypto_box_curve25519xchacha20poly1305_beforenm", "crypto_box_curve25519xchacha20poly1305_detached", "crypto_box_curve25519xchacha20poly1305_detached_afternm", "crypto_box_curve25519xchacha20poly1305_easy", "crypto_box_curve25519xchacha20poly1305_easy_afternm", "crypto_box_curve25519xchacha20poly1305_keypair", "crypto_box_curve25519xchacha20poly1305_open_detached", "crypto_box_curve25519xchacha20poly1305_open_detached_afternm", "crypto_box_curve25519xchacha20poly1305_open_easy", "crypto_box_curve25519xchacha20poly1305_open_easy_afternm", "crypto_box_curve25519xchacha20poly1305_seal", "crypto_box_curve25519xchacha20poly1305_seal_open", "crypto_box_curve25519xchacha20poly1305_seed_keypair", "crypto_box_detached", "crypto_box_easy", "crypto_box_easy_afternm", "crypto_box_keypair", "crypto_box_open_detached", "crypto_box_open_easy", "crypto_box_open_easy_afternm", "crypto_box_seal", "crypto_box_seal_open", "crypto_box_seed_keypair", "crypto_core_ed25519_add", "crypto_core_ed25519_from_hash", "crypto_core_ed25519_from_uniform", "crypto_core_ed25519_is_valid_point", "crypto_core_ed25519_random", "crypto_core_ed25519_scalar_add", "crypto_core_ed25519_scalar_complement", "crypto_core_ed25519_scalar_invert", "crypto_core_ed25519_scalar_mul", "crypto_core_ed25519_scalar_negate", "crypto_core_ed25519_scalar_random", "crypto_core_ed25519_scalar_reduce", "crypto_core_ed25519_scalar_sub", "crypto_core_ed25519_sub", "crypto_core_hchacha20", "crypto_core_hsalsa20", "crypto_core_ristretto255_add", "crypto_core_ristretto255_from_hash", "crypto_core_ristretto255_is_valid_point", "crypto_core_ristretto255_random", "crypto_core_ristretto255_scalar_add", "crypto_core_ristretto255_scalar_complement", "crypto_core_ristretto255_scalar_invert", "crypto_core_ristretto255_scalar_mul", "crypto_core_ristretto255_scalar_negate", "crypto_core_ristretto255_scalar_random", "crypto_core_ristretto255_scalar_reduce", "crypto_core_ristretto255_scalar_sub", "crypto_core_ristretto255_sub", "crypto_generichash", "crypto_generichash_blake2b_salt_personal", "crypto_generichash_final", "crypto_generichash_init", "crypto_generichash_keygen", "crypto_generichash_update", "crypto_hash", "crypto_hash_sha256", "crypto_hash_sha256_final", "crypto_hash_sha256_init", "crypto_hash_sha256_update", "crypto_hash_sha3256", "crypto_hash_sha3256_final", "crypto_hash_sha3256_init", "crypto_hash_sha3256_update", "crypto_hash_sha3512", "crypto_hash_sha3512_final", "crypto_hash_sha3512_init", "crypto_hash_sha3512_update", "crypto_hash_sha512", "crypto_hash_sha512_final", "crypto_hash_sha512_init", "crypto_hash_sha512_update", "crypto_ipcrypt_decrypt", "crypto_ipcrypt_encrypt", "crypto_ipcrypt_keygen", "crypto_ipcrypt_nd_decrypt", "crypto_ipcrypt_nd_encrypt", "crypto_ipcrypt_nd_keygen", "crypto_ipcrypt_ndx_decrypt", "crypto_ipcrypt_ndx_encrypt", "crypto_ipcrypt_ndx_keygen", "crypto_ipcrypt_pfx_decrypt", "crypto_ipcrypt_pfx_encrypt", "crypto_ipcrypt_pfx_keygen", "crypto_kdf_derive_from_key", "crypto_kdf_keygen", "crypto_kem_dec", "crypto_kem_enc", "crypto_kem_keypair", "crypto_kem_mlkem768_dec", "crypto_kem_mlkem768_enc", "crypto_kem_mlkem768_enc_deterministic", "crypto_kem_mlkem768_keypair", "crypto_kem_mlkem768_seed_keypair", "crypto_kem_primitive", "crypto_kem_seed_keypair", "crypto_kem_xwing_dec", "crypto_kem_xwing_enc", "crypto_kem_xwing_enc_deterministic", "crypto_kem_xwing_keypair", "crypto_kem_xwing_seed_keypair", "crypto_kx_client_session_keys", "crypto_kx_keypair", "crypto_kx_seed_keypair", "crypto_kx_server_session_keys", "crypto_onetimeauth", "crypto_onetimeauth_final", "crypto_onetimeauth_init", "crypto_onetimeauth_keygen", "crypto_onetimeauth_update", "crypto_onetimeauth_verify", "crypto_pwhash", "crypto_pwhash_scryptsalsa208sha256", "crypto_pwhash_scryptsalsa208sha256_ll", "crypto_pwhash_scryptsalsa208sha256_str", "crypto_pwhash_scryptsalsa208sha256_str_verify", "crypto_pwhash_str", "crypto_pwhash_str_needs_rehash", "crypto_pwhash_str_verify", "crypto_scalarmult", "crypto_scalarmult_base", "crypto_scalarmult_ed25519", "crypto_scalarmult_ed25519_base", "crypto_scalarmult_ed25519_base_noclamp", "crypto_scalarmult_ed25519_noclamp", "crypto_scalarmult_ristretto255", "crypto_scalarmult_ristretto255_base", "crypto_secretbox_detached", "crypto_secretbox_easy", "crypto_secretbox_keygen", "crypto_secretbox_open_detached", "crypto_secretbox_open_easy", "crypto_secretstream_xchacha20poly1305_init_pull", "crypto_secretstream_xchacha20poly1305_init_push", "crypto_secretstream_xchacha20poly1305_keygen", "crypto_secretstream_xchacha20poly1305_pull", "crypto_secretstream_xchacha20poly1305_push", "crypto_secretstream_xchacha20poly1305_rekey", "crypto_shorthash", "crypto_shorthash_keygen", "crypto_shorthash_siphashx24", "crypto_sign", "crypto_sign_detached", "crypto_sign_ed25519_pk_to_curve25519", "crypto_sign_ed25519_sk_to_curve25519", "crypto_sign_ed25519_sk_to_pk", "crypto_sign_ed25519_sk_to_seed", "crypto_sign_final_create", "crypto_sign_final_verify", "crypto_sign_init", "crypto_sign_keypair", "crypto_sign_open", "crypto_sign_seed_keypair", "crypto_sign_update", "crypto_sign_verify_detached", "crypto_stream_chacha20", "crypto_stream_chacha20_ietf_xor", "crypto_stream_chacha20_ietf_xor_ic", "crypto_stream_chacha20_keygen", "crypto_stream_chacha20_xor", "crypto_stream_chacha20_xor_ic", "crypto_stream_keygen", "crypto_stream_xchacha20_keygen", "crypto_stream_xchacha20_xor", "crypto_stream_xchacha20_xor_ic", "crypto_xof_shake128", "crypto_xof_shake128_init", "crypto_xof_shake128_init_with_domain", "crypto_xof_shake128_squeeze", "crypto_xof_shake128_update", "crypto_xof_shake256", "crypto_xof_shake256_init", "crypto_xof_shake256_init_with_domain", "crypto_xof_shake256_squeeze", "crypto_xof_shake256_update", "crypto_xof_turboshake128", "crypto_xof_turboshake128_init", "crypto_xof_turboshake128_init_with_domain", "crypto_xof_turboshake128_squeeze", "crypto_xof_turboshake128_update", "crypto_xof_turboshake256", "crypto_xof_turboshake256_init", "crypto_xof_turboshake256_init_with_domain", "crypto_xof_turboshake256_squeeze", "crypto_xof_turboshake256_update", "randombytes_buf", "randombytes_buf_deterministic", "randombytes_close", "randombytes_random", "randombytes_set_implementation", "randombytes_stir", "randombytes_uniform", "sodium_bin2ip", "sodium_ip2bin", "sodium_version_string"], a3 = [C, R, P, X, D2, G, F2, V, q, H, z3, W, j, J, Q, Z, $2, ee, re, te, ae, _e, ne, se, ce, pe, oe, he, ye, ie, le, ue, de, ve, ge, be, fe, me, ke, xe, Ee, Te, Se, we, Ye, Be, Ke, Ae, Ie, Me, Ne, Le, Ue, Oe, Ce, Re, Pe, Xe, De, Ge, Fe, Ve, qe, He, ze, We, je, Je, Qe, Ze, $e, er, rr, tr, ar, _r, nr, sr, cr, pr, or, hr, yr, ir, lr, ur, dr, vr, gr, br, fr, mr, kr, xr, Er, Tr, Sr, wr, Yr, Br, Kr, Ar, Ir, Mr, Nr, Lr, Ur, Or, Cr, Rr, Pr, Xr, Dr, Gr, Fr, Vr, qr, Hr, zr, Wr, jr, Jr, Qr, Zr, $r, et, rt, tt, at, _t, nt, st, ct, pt, ot, ht, yt, it, lt, ut, dt, vt, gt, bt, ft, mt, kt, xt, Et, Tt, St, wt, Yt, Bt, Kt, At, It, Mt, Nt, Lt, Ut, Ot, Ct, Rt, Pt, Xt, Dt, Gt, Ft, Vt, qt, Ht, zt, Wt, jt, Jt, Qt, Zt, $t, ea, ra, ta, aa, _a, na, sa, ca, pa, oa, ha, ya, ia, la, ua, da, va, ga, ba, fa, ma, ka, xa, Ea, Ta, Sa, wa, Ya, Ba, Ka, Aa, Ia, Ma, Na, La, Ua, Oa, Ca, Ra, Pa, Xa, Da, Ga, Fa, Va, qa, Ha, za, Wa, ja, Ja, Qa, Za, $a, e_, r_, t_, a_, __, n_, s_, c_, p_, o_, h_, y_], _4 = 0; _4 < a3.length; _4++) "function" == typeof r["_" + e2[_4]] && (t[e2[_4]] = a3[_4]);
55885
55900
  var n3 = ["SODIUM_LIBRARY_VERSION_MAJOR", "SODIUM_LIBRARY_VERSION_MINOR", "crypto_aead_aegis128l_ABYTES", "crypto_aead_aegis128l_KEYBYTES", "crypto_aead_aegis128l_MESSAGEBYTES_MAX", "crypto_aead_aegis128l_NPUBBYTES", "crypto_aead_aegis128l_NSECBYTES", "crypto_aead_aegis256_ABYTES", "crypto_aead_aegis256_KEYBYTES", "crypto_aead_aegis256_MESSAGEBYTES_MAX", "crypto_aead_aegis256_NPUBBYTES", "crypto_aead_aegis256_NSECBYTES", "crypto_aead_aes256gcm_ABYTES", "crypto_aead_aes256gcm_KEYBYTES", "crypto_aead_aes256gcm_MESSAGEBYTES_MAX", "crypto_aead_aes256gcm_NPUBBYTES", "crypto_aead_aes256gcm_NSECBYTES", "crypto_aead_chacha20poly1305_ABYTES", "crypto_aead_chacha20poly1305_IETF_ABYTES", "crypto_aead_chacha20poly1305_IETF_KEYBYTES", "crypto_aead_chacha20poly1305_IETF_MESSAGEBYTES_MAX", "crypto_aead_chacha20poly1305_IETF_NPUBBYTES", "crypto_aead_chacha20poly1305_IETF_NSECBYTES", "crypto_aead_chacha20poly1305_KEYBYTES", "crypto_aead_chacha20poly1305_MESSAGEBYTES_MAX", "crypto_aead_chacha20poly1305_NPUBBYTES", "crypto_aead_chacha20poly1305_NSECBYTES", "crypto_aead_chacha20poly1305_ietf_ABYTES", "crypto_aead_chacha20poly1305_ietf_KEYBYTES", "crypto_aead_chacha20poly1305_ietf_MESSAGEBYTES_MAX", "crypto_aead_chacha20poly1305_ietf_NPUBBYTES", "crypto_aead_chacha20poly1305_ietf_NSECBYTES", "crypto_aead_xchacha20poly1305_IETF_ABYTES", "crypto_aead_xchacha20poly1305_IETF_KEYBYTES", "crypto_aead_xchacha20poly1305_IETF_MESSAGEBYTES_MAX", "crypto_aead_xchacha20poly1305_IETF_NPUBBYTES", "crypto_aead_xchacha20poly1305_IETF_NSECBYTES", "crypto_aead_xchacha20poly1305_ietf_ABYTES", "crypto_aead_xchacha20poly1305_ietf_KEYBYTES", "crypto_aead_xchacha20poly1305_ietf_MESSAGEBYTES_MAX", "crypto_aead_xchacha20poly1305_ietf_NPUBBYTES", "crypto_aead_xchacha20poly1305_ietf_NSECBYTES", "crypto_auth_BYTES", "crypto_auth_KEYBYTES", "crypto_auth_hmacsha256_BYTES", "crypto_auth_hmacsha256_KEYBYTES", "crypto_auth_hmacsha512256_BYTES", "crypto_auth_hmacsha512256_KEYBYTES", "crypto_auth_hmacsha512_BYTES", "crypto_auth_hmacsha512_KEYBYTES", "crypto_box_BEFORENMBYTES", "crypto_box_MACBYTES", "crypto_box_MESSAGEBYTES_MAX", "crypto_box_NONCEBYTES", "crypto_box_PUBLICKEYBYTES", "crypto_box_SEALBYTES", "crypto_box_SECRETKEYBYTES", "crypto_box_SEEDBYTES", "crypto_box_curve25519xchacha20poly1305_BEFORENMBYTES", "crypto_box_curve25519xchacha20poly1305_MACBYTES", "crypto_box_curve25519xchacha20poly1305_MESSAGEBYTES_MAX", "crypto_box_curve25519xchacha20poly1305_NONCEBYTES", "crypto_box_curve25519xchacha20poly1305_PUBLICKEYBYTES", "crypto_box_curve25519xchacha20poly1305_SEALBYTES", "crypto_box_curve25519xchacha20poly1305_SECRETKEYBYTES", "crypto_box_curve25519xchacha20poly1305_SEEDBYTES", "crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES", "crypto_box_curve25519xsalsa20poly1305_MACBYTES", "crypto_box_curve25519xsalsa20poly1305_MESSAGEBYTES_MAX", "crypto_box_curve25519xsalsa20poly1305_NONCEBYTES", "crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES", "crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES", "crypto_box_curve25519xsalsa20poly1305_SEEDBYTES", "crypto_core_ed25519_BYTES", "crypto_core_ed25519_HASHBYTES", "crypto_core_ed25519_NONREDUCEDSCALARBYTES", "crypto_core_ed25519_SCALARBYTES", "crypto_core_ed25519_UNIFORMBYTES", "crypto_core_hchacha20_CONSTBYTES", "crypto_core_hchacha20_INPUTBYTES", "crypto_core_hchacha20_KEYBYTES", "crypto_core_hchacha20_OUTPUTBYTES", "crypto_core_hsalsa20_CONSTBYTES", "crypto_core_hsalsa20_INPUTBYTES", "crypto_core_hsalsa20_KEYBYTES", "crypto_core_hsalsa20_OUTPUTBYTES", "crypto_core_ristretto255_BYTES", "crypto_core_ristretto255_HASHBYTES", "crypto_core_ristretto255_NONREDUCEDSCALARBYTES", "crypto_core_ristretto255_SCALARBYTES", "crypto_core_salsa2012_CONSTBYTES", "crypto_core_salsa2012_INPUTBYTES", "crypto_core_salsa2012_KEYBYTES", "crypto_core_salsa2012_OUTPUTBYTES", "crypto_core_salsa208_CONSTBYTES", "crypto_core_salsa208_INPUTBYTES", "crypto_core_salsa208_KEYBYTES", "crypto_core_salsa208_OUTPUTBYTES", "crypto_core_salsa20_CONSTBYTES", "crypto_core_salsa20_INPUTBYTES", "crypto_core_salsa20_KEYBYTES", "crypto_core_salsa20_OUTPUTBYTES", "crypto_generichash_BYTES", "crypto_generichash_BYTES_MAX", "crypto_generichash_BYTES_MIN", "crypto_generichash_KEYBYTES", "crypto_generichash_KEYBYTES_MAX", "crypto_generichash_KEYBYTES_MIN", "crypto_generichash_blake2b_BYTES", "crypto_generichash_blake2b_BYTES_MAX", "crypto_generichash_blake2b_BYTES_MIN", "crypto_generichash_blake2b_KEYBYTES", "crypto_generichash_blake2b_KEYBYTES_MAX", "crypto_generichash_blake2b_KEYBYTES_MIN", "crypto_generichash_blake2b_PERSONALBYTES", "crypto_generichash_blake2b_SALTBYTES", "crypto_hash_BYTES", "crypto_hash_sha256_BYTES", "crypto_hash_sha3256_BYTES", "crypto_hash_sha3512_BYTES", "crypto_hash_sha512_BYTES", "crypto_ipcrypt_BYTES", "crypto_ipcrypt_KEYBYTES", "crypto_ipcrypt_NDX_INPUTBYTES", "crypto_ipcrypt_NDX_KEYBYTES", "crypto_ipcrypt_NDX_OUTPUTBYTES", "crypto_ipcrypt_NDX_TWEAKBYTES", "crypto_ipcrypt_ND_INPUTBYTES", "crypto_ipcrypt_ND_KEYBYTES", "crypto_ipcrypt_ND_OUTPUTBYTES", "crypto_ipcrypt_ND_TWEAKBYTES", "crypto_ipcrypt_PFX_BYTES", "crypto_ipcrypt_PFX_KEYBYTES", "crypto_kdf_BYTES_MAX", "crypto_kdf_BYTES_MIN", "crypto_kdf_CONTEXTBYTES", "crypto_kdf_KEYBYTES", "crypto_kdf_blake2b_BYTES_MAX", "crypto_kdf_blake2b_BYTES_MIN", "crypto_kdf_blake2b_CONTEXTBYTES", "crypto_kdf_blake2b_KEYBYTES", "crypto_kdf_hkdf_sha256_BYTES_MAX", "crypto_kdf_hkdf_sha256_BYTES_MIN", "crypto_kdf_hkdf_sha256_KEYBYTES", "crypto_kdf_hkdf_sha512_BYTES_MAX", "crypto_kdf_hkdf_sha512_BYTES_MIN", "crypto_kdf_hkdf_sha512_KEYBYTES", "crypto_kem_CIPHERTEXTBYTES", "crypto_kem_PUBLICKEYBYTES", "crypto_kem_SECRETKEYBYTES", "crypto_kem_SEEDBYTES", "crypto_kem_SHAREDSECRETBYTES", "crypto_kem_mlkem768_CIPHERTEXTBYTES", "crypto_kem_mlkem768_PUBLICKEYBYTES", "crypto_kem_mlkem768_SECRETKEYBYTES", "crypto_kem_mlkem768_SEEDBYTES", "crypto_kem_mlkem768_SHAREDSECRETBYTES", "crypto_kem_xwing_CIPHERTEXTBYTES", "crypto_kem_xwing_PUBLICKEYBYTES", "crypto_kem_xwing_SECRETKEYBYTES", "crypto_kem_xwing_SEEDBYTES", "crypto_kem_xwing_SHAREDSECRETBYTES", "crypto_kx_PUBLICKEYBYTES", "crypto_kx_SECRETKEYBYTES", "crypto_kx_SEEDBYTES", "crypto_kx_SESSIONKEYBYTES", "crypto_onetimeauth_BYTES", "crypto_onetimeauth_KEYBYTES", "crypto_onetimeauth_poly1305_BYTES", "crypto_onetimeauth_poly1305_KEYBYTES", "crypto_pwhash_ALG_ARGON2I13", "crypto_pwhash_ALG_ARGON2ID13", "crypto_pwhash_ALG_DEFAULT", "crypto_pwhash_BYTES_MAX", "crypto_pwhash_BYTES_MIN", "crypto_pwhash_MEMLIMIT_INTERACTIVE", "crypto_pwhash_MEMLIMIT_MAX", "crypto_pwhash_MEMLIMIT_MIN", "crypto_pwhash_MEMLIMIT_MODERATE", "crypto_pwhash_MEMLIMIT_SENSITIVE", "crypto_pwhash_OPSLIMIT_INTERACTIVE", "crypto_pwhash_OPSLIMIT_MAX", "crypto_pwhash_OPSLIMIT_MIN", "crypto_pwhash_OPSLIMIT_MODERATE", "crypto_pwhash_OPSLIMIT_SENSITIVE", "crypto_pwhash_PASSWD_MAX", "crypto_pwhash_PASSWD_MIN", "crypto_pwhash_SALTBYTES", "crypto_pwhash_STRBYTES", "crypto_pwhash_argon2i_BYTES_MAX", "crypto_pwhash_argon2i_BYTES_MIN", "crypto_pwhash_argon2i_MEMLIMIT_INTERACTIVE", "crypto_pwhash_argon2i_MEMLIMIT_MAX", "crypto_pwhash_argon2i_MEMLIMIT_MIN", "crypto_pwhash_argon2i_MEMLIMIT_MODERATE", "crypto_pwhash_argon2i_MEMLIMIT_SENSITIVE", "crypto_pwhash_argon2i_OPSLIMIT_INTERACTIVE", "crypto_pwhash_argon2i_OPSLIMIT_MAX", "crypto_pwhash_argon2i_OPSLIMIT_MIN", "crypto_pwhash_argon2i_OPSLIMIT_MODERATE", "crypto_pwhash_argon2i_OPSLIMIT_SENSITIVE", "crypto_pwhash_argon2i_PASSWD_MAX", "crypto_pwhash_argon2i_PASSWD_MIN", "crypto_pwhash_argon2i_SALTBYTES", "crypto_pwhash_argon2i_STRBYTES", "crypto_pwhash_argon2id_BYTES_MAX", "crypto_pwhash_argon2id_BYTES_MIN", "crypto_pwhash_argon2id_MEMLIMIT_INTERACTIVE", "crypto_pwhash_argon2id_MEMLIMIT_MAX", "crypto_pwhash_argon2id_MEMLIMIT_MIN", "crypto_pwhash_argon2id_MEMLIMIT_MODERATE", "crypto_pwhash_argon2id_MEMLIMIT_SENSITIVE", "crypto_pwhash_argon2id_OPSLIMIT_INTERACTIVE", "crypto_pwhash_argon2id_OPSLIMIT_MAX", "crypto_pwhash_argon2id_OPSLIMIT_MIN", "crypto_pwhash_argon2id_OPSLIMIT_MODERATE", "crypto_pwhash_argon2id_OPSLIMIT_SENSITIVE", "crypto_pwhash_argon2id_PASSWD_MAX", "crypto_pwhash_argon2id_PASSWD_MIN", "crypto_pwhash_argon2id_SALTBYTES", "crypto_pwhash_argon2id_STRBYTES", "crypto_pwhash_scryptsalsa208sha256_BYTES_MAX", "crypto_pwhash_scryptsalsa208sha256_BYTES_MIN", "crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_INTERACTIVE", "crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MAX", "crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_MIN", "crypto_pwhash_scryptsalsa208sha256_MEMLIMIT_SENSITIVE", "crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_INTERACTIVE", "crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MAX", "crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_MIN", "crypto_pwhash_scryptsalsa208sha256_OPSLIMIT_SENSITIVE", "crypto_pwhash_scryptsalsa208sha256_PASSWD_MAX", "crypto_pwhash_scryptsalsa208sha256_PASSWD_MIN", "crypto_pwhash_scryptsalsa208sha256_SALTBYTES", "crypto_pwhash_scryptsalsa208sha256_STRBYTES", "crypto_scalarmult_BYTES", "crypto_scalarmult_SCALARBYTES", "crypto_scalarmult_curve25519_BYTES", "crypto_scalarmult_curve25519_SCALARBYTES", "crypto_scalarmult_ed25519_BYTES", "crypto_scalarmult_ed25519_SCALARBYTES", "crypto_scalarmult_ristretto255_BYTES", "crypto_scalarmult_ristretto255_SCALARBYTES", "crypto_secretbox_KEYBYTES", "crypto_secretbox_MACBYTES", "crypto_secretbox_MESSAGEBYTES_MAX", "crypto_secretbox_NONCEBYTES", "crypto_secretbox_xchacha20poly1305_KEYBYTES", "crypto_secretbox_xchacha20poly1305_MACBYTES", "crypto_secretbox_xchacha20poly1305_MESSAGEBYTES_MAX", "crypto_secretbox_xchacha20poly1305_NONCEBYTES", "crypto_secretbox_xsalsa20poly1305_KEYBYTES", "crypto_secretbox_xsalsa20poly1305_MACBYTES", "crypto_secretbox_xsalsa20poly1305_MESSAGEBYTES_MAX", "crypto_secretbox_xsalsa20poly1305_NONCEBYTES", "crypto_secretstream_xchacha20poly1305_ABYTES", "crypto_secretstream_xchacha20poly1305_HEADERBYTES", "crypto_secretstream_xchacha20poly1305_KEYBYTES", "crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX", "crypto_secretstream_xchacha20poly1305_TAG_FINAL", "crypto_secretstream_xchacha20poly1305_TAG_MESSAGE", "crypto_secretstream_xchacha20poly1305_TAG_PUSH", "crypto_secretstream_xchacha20poly1305_TAG_REKEY", "crypto_shorthash_BYTES", "crypto_shorthash_KEYBYTES", "crypto_shorthash_siphash24_BYTES", "crypto_shorthash_siphash24_KEYBYTES", "crypto_shorthash_siphashx24_BYTES", "crypto_shorthash_siphashx24_KEYBYTES", "crypto_sign_BYTES", "crypto_sign_MESSAGEBYTES_MAX", "crypto_sign_PUBLICKEYBYTES", "crypto_sign_SECRETKEYBYTES", "crypto_sign_SEEDBYTES", "crypto_sign_ed25519_BYTES", "crypto_sign_ed25519_MESSAGEBYTES_MAX", "crypto_sign_ed25519_PUBLICKEYBYTES", "crypto_sign_ed25519_SECRETKEYBYTES", "crypto_sign_ed25519_SEEDBYTES", "crypto_stream_KEYBYTES", "crypto_stream_MESSAGEBYTES_MAX", "crypto_stream_NONCEBYTES", "crypto_stream_chacha20_IETF_KEYBYTES", "crypto_stream_chacha20_IETF_MESSAGEBYTES_MAX", "crypto_stream_chacha20_IETF_NONCEBYTES", "crypto_stream_chacha20_KEYBYTES", "crypto_stream_chacha20_MESSAGEBYTES_MAX", "crypto_stream_chacha20_NONCEBYTES", "crypto_stream_chacha20_ietf_KEYBYTES", "crypto_stream_chacha20_ietf_MESSAGEBYTES_MAX", "crypto_stream_chacha20_ietf_NONCEBYTES", "crypto_stream_salsa2012_KEYBYTES", "crypto_stream_salsa2012_MESSAGEBYTES_MAX", "crypto_stream_salsa2012_NONCEBYTES", "crypto_stream_salsa208_KEYBYTES", "crypto_stream_salsa208_MESSAGEBYTES_MAX", "crypto_stream_salsa208_NONCEBYTES", "crypto_stream_salsa20_KEYBYTES", "crypto_stream_salsa20_MESSAGEBYTES_MAX", "crypto_stream_salsa20_NONCEBYTES", "crypto_stream_xchacha20_KEYBYTES", "crypto_stream_xchacha20_MESSAGEBYTES_MAX", "crypto_stream_xchacha20_NONCEBYTES", "crypto_stream_xsalsa20_KEYBYTES", "crypto_stream_xsalsa20_MESSAGEBYTES_MAX", "crypto_stream_xsalsa20_NONCEBYTES", "crypto_verify_16_BYTES", "crypto_verify_32_BYTES", "crypto_verify_64_BYTES", "crypto_xof_shake128_BLOCKBYTES", "crypto_xof_shake128_STATEBYTES", "crypto_xof_shake256_BLOCKBYTES", "crypto_xof_shake256_STATEBYTES", "crypto_xof_turboshake128_BLOCKBYTES", "crypto_xof_turboshake128_STATEBYTES", "crypto_xof_turboshake256_BLOCKBYTES", "crypto_xof_turboshake256_STATEBYTES"];
55886
55901
  for (_4 = 0; _4 < n3.length; _4++) "function" == typeof (c3 = r["_" + n3[_4].toLowerCase()]) && (t[n3[_4]] = c3());
55887
55902
  var s3 = ["SODIUM_VERSION_STRING", "crypto_kem_PRIMITIVE", "crypto_pwhash_STRPREFIX", "crypto_pwhash_argon2i_STRPREFIX", "crypto_pwhash_argon2id_STRPREFIX", "crypto_pwhash_scryptsalsa208sha256_STRPREFIX"];
@@ -56240,7 +56255,7 @@ function H(e) {
56240
56255
  var n2 = S2(a2, e);
56241
56256
  return M2(t2), n2;
56242
56257
  }
56243
- function z2(e, t2, a2, _3, n2, s2) {
56258
+ function z3(e, t2, a2, _3, n2, s2) {
56244
56259
  var c2 = [];
56245
56260
  Y(s2);
56246
56261
  var p3 = null;
@@ -59544,6 +59559,8 @@ var runCommand = (cmd, args, opts = {}) => new Promise((resolve9) => {
59544
59559
 
59545
59560
  // src/deploy/repo.ts
59546
59561
  var DEPLOY_FILE_REL = DEPLOY_FILE.split(import_node_path34.default.sep).join("/");
59562
+ var PERSONA_FILE_REL = ".clawd/persona.json";
59563
+ var DIRTY_IGNORED = [DEPLOY_FILE_REL, PERSONA_FILE_REL];
59547
59564
  var RepoError = class extends Error {
59548
59565
  };
59549
59566
  var tail = (s2, n2 = 400) => s2.trim().slice(-n2);
@@ -59592,7 +59609,7 @@ async function repoInfo(exec, dir) {
59592
59609
  const url = origin.stdout.trim();
59593
59610
  const branch = (await git(exec, dir, ["rev-parse", "--abbrev-ref", "HEAD"])).stdout.trim() || "main";
59594
59611
  const head = (await git(exec, dir, ["rev-parse", "HEAD"])).stdout.trim() || "(\u8FD8\u6CA1\u6709\u63D0\u4EA4)";
59595
- const status = await git(exec, dir, ["status", "--porcelain", "--", ".", `:(exclude)${DEPLOY_FILE_REL}`]);
59612
+ const status = await git(exec, dir, ["status", "--porcelain", "--", ".", ...DIRTY_IGNORED.map((f2) => `:(exclude)${f2}`)]);
59596
59613
  const dirty = status.spawnError !== void 0 || status.code !== 0 || status.stdout.trim().length > 0;
59597
59614
  const aheadRaw = await git(exec, dir, ["rev-list", "--count", "@{u}..HEAD"]);
59598
59615
  const ahead = aheadRaw.code === 0 ? Number(aheadRaw.stdout.trim()) || 0 : 0;
@@ -59765,7 +59782,13 @@ function toJob(raw) {
59765
59782
  };
59766
59783
  }
59767
59784
  async function latestRun(api, slug) {
59768
- const listed = await api.getJson(`/repos/${slug}/actions/runs?per_page=1`);
59785
+ return fetchRun(api, slug, "per_page=1");
59786
+ }
59787
+ async function runByHead(api, slug, head) {
59788
+ return fetchRun(api, slug, `head_sha=${encodeURIComponent(head)}&per_page=1`);
59789
+ }
59790
+ async function fetchRun(api, slug, query) {
59791
+ const listed = await api.getJson(`/repos/${slug}/actions/runs?${query}`);
59769
59792
  const raw = listed?.workflow_runs?.[0];
59770
59793
  if (!raw || typeof raw.id !== "number" || typeof raw.head_sha !== "string" || typeof raw.html_url !== "string") {
59771
59794
  return void 0;
@@ -59869,6 +59892,15 @@ function buildDeployHandlers(deps) {
59869
59892
  const cacheMs = deps.secretsCacheMs ?? SECRETS_CACHE_MS;
59870
59893
  const secretsCache = /* @__PURE__ */ new Map();
59871
59894
  const runCache = /* @__PURE__ */ new Map();
59895
+ const runCacheKey = (personaId2, head) => `${personaId2}:${head ?? "latest"}`;
59896
+ const cachedRun = async (personaId2, api, slug, head) => {
59897
+ const key = runCacheKey(personaId2, head);
59898
+ const hit = runCache.get(key);
59899
+ if (hit && (head !== void 0 && hit.run?.status === "completed" || deps.now() - hit.at < RUN_CACHE_MS)) return hit.run;
59900
+ const run = head ? await runByHead(api, slug, head) : await latestRun(api, slug);
59901
+ runCache.set(key, { at: deps.now(), run });
59902
+ return run;
59903
+ };
59872
59904
  deps.githubIdentity.onChange(() => secretsCache.clear());
59873
59905
  async function requireGithub() {
59874
59906
  const auth = await deps.githubIdentity.refresh();
@@ -59888,7 +59920,7 @@ function buildDeployHandlers(deps) {
59888
59920
  secretsCache.set(personaId2, { at: deps.now(), list });
59889
59921
  return list;
59890
59922
  }
59891
- async function stateOf(personaId2) {
59923
+ async function stateOf(personaId2, releaseHead) {
59892
59924
  const dir = deps.personaDir(personaId2);
59893
59925
  const repo2 = await repoInfo(deps.exec, dir);
59894
59926
  const github = await deps.githubIdentity.status();
@@ -59911,35 +59943,30 @@ function buildDeployHandlers(deps) {
59911
59943
  } catch {
59912
59944
  secrets = void 0;
59913
59945
  }
59914
- const hit = runCache.get(personaId2);
59915
- if (hit && deps.now() - hit.at < RUN_CACHE_MS) {
59916
- run = hit.run;
59917
- } else {
59918
- run = await latestRun(api, repoSlug(repo2.url));
59919
- runCache.set(personaId2, { at: deps.now(), run });
59920
- }
59946
+ run = await cachedRun(personaId2, api, repoSlug(repo2.url), releaseHead);
59921
59947
  }
59922
59948
  return {
59923
59949
  personaId: personaId2,
59924
59950
  github,
59925
59951
  ...repo2 ? { repo: repo2 } : {},
59926
59952
  scans,
59927
- ...file.released ? { released: file.released } : {},
59953
+ releases: file.releases,
59928
59954
  ...secrets ? { secrets } : {},
59929
59955
  ...run ? { run } : {},
59930
59956
  ...historyError ? { historyError } : {}
59931
59957
  };
59932
59958
  }
59933
- const view = async (personaId2) => ({
59934
- response: { type: "deploy:state", ...await stateOf(personaId2) }
59959
+ const view = async (personaId2, releaseHead) => ({
59960
+ response: { type: "deploy:state", ...await stateOf(personaId2, releaseHead) }
59935
59961
  });
59936
59962
  async function beginScan(personaId2, dir, file, contentHead, want) {
59937
59963
  liveScans.set(personaId2, {});
59938
- const releasedEntry = file.released ? file.scans.find((s2) => s2.id === file.released.scanId) : void 0;
59964
+ const released = file.releases.at(-1);
59965
+ const releasedEntry = released ? file.scans.find((s2) => s2.id === released.scanId) : void 0;
59939
59966
  const scanBase = pickScanBase({
59940
59967
  // **有记录 ≠ 清单能用**:被发那条要是没跑完(OTA 重启 / butler 崩,见 scan-task.ts 的收尾判定)清单是半截的。
59941
59968
  hasUsableManifest: releasedEntry?.status === "done",
59942
- releasedHead: await hasCommit(deps.exec, dir, file.released?.head) ? file.released?.head : void 0,
59969
+ releasedHead: await hasCommit(deps.exec, dir, released?.head) ? released?.head : void 0,
59943
59970
  ...want ? { want } : {}
59944
59971
  });
59945
59972
  const lastDone = [...file.scans].reverse().find((s2) => s2.status === "done");
@@ -59990,9 +60017,9 @@ function buildDeployHandlers(deps) {
59990
60017
  }
59991
60018
  const get = async (frame, _client, ctx) => {
59992
60019
  ensureOwner(ctx);
59993
- const { personaId: personaId2 } = parseArgs2(DeployPersonaArgsSchema, frame, "deploy:get");
60020
+ const { personaId: personaId2, releaseHead } = parseArgs2(DeployGetArgsSchema, frame, "deploy:get");
59994
60021
  mustPersona(personaId2);
59995
- return view(personaId2);
60022
+ return view(personaId2, releaseHead);
59996
60023
  };
59997
60024
  const patch = async (frame, _client, ctx) => {
59998
60025
  ensureOwner(ctx);
@@ -60097,9 +60124,9 @@ function buildDeployHandlers(deps) {
60097
60124
  } catch (err) {
60098
60125
  throw toClawdError(err);
60099
60126
  }
60100
- runCache.delete(personaId2);
60127
+ runCache.delete(runCacheKey(personaId2));
60101
60128
  try {
60102
- await beginScan(personaId2, dir, file, contentHeadOf({ head }, file.released), scanBase);
60129
+ await beginScan(personaId2, dir, file, contentHeadOf({ head }, file.releases.at(-1)), scanBase);
60103
60130
  } catch (err) {
60104
60131
  liveScans.delete(personaId2);
60105
60132
  throw err;
@@ -60119,7 +60146,7 @@ function buildDeployHandlers(deps) {
60119
60146
  const file = await readHistory(dir);
60120
60147
  const entry = mustScan(file, scanId);
60121
60148
  if (entry.status !== "done") throw invalid(entry.status === "scanning" ? "\u8FD9\u6B21\u626B\u63CF\u8FD8\u5728\u8DD1\uFF0C\u7B49\u5B83\u626B\u5B8C" : "\u8FD9\u6B21\u626B\u63CF\u6CA1\u8DD1\u5B8C\uFF0C\u6E05\u5355\u4E0D\u5B8C\u6574\u2014\u2014\u91CD\u65B0\u626B\u63CF");
60122
- if (!isScanFresh(entry, repo2, file.released)) {
60149
+ if (!isScanFresh(entry, repo2, file.releases.at(-1))) {
60123
60150
  throw invalid(repo2.dirty ? "\u6709\u672A\u63D0\u4EA4\u7684\u6539\u52A8\uFF0C\u6E05\u5355\u662F\u6539\u52A8\u524D\u626B\u7684\u2014\u2014\u91CD\u65B0\u626B\u63CF" : "\u8FD9\u6B21\u626B\u63CF\u5BF9\u5E94\u7684\u4E0D\u662F\u5F53\u524D\u8FD9\u4E00\u7248 persona\u2014\u2014\u91CD\u65B0\u626B\u63CF");
60124
60151
  }
60125
60152
  const blockers = [];
@@ -60146,10 +60173,11 @@ function buildDeployHandlers(deps) {
60146
60173
  if ((await repoInfo(deps.exec, dir))?.head === repo2.head) await restoreDeployFileRaw(dir, before);
60147
60174
  throw err;
60148
60175
  }
60149
- runCache.delete(personaId2);
60176
+ runCache.delete(runCacheKey(personaId2));
60177
+ const latest = await readHistory(dir);
60150
60178
  await writeScanFile(dir, {
60151
- ...await readHistory(dir),
60152
- released: { head: result.sha, contentHead: entry.head, scanId: entry.id, at: deps.now() }
60179
+ ...latest,
60180
+ releases: [...latest.releases, { head: result.sha, contentHead: entry.head, scanId: entry.id, at: deps.now() }]
60153
60181
  });
60154
60182
  return { response: { type: "deploy:release", ...result } };
60155
60183
  } catch (err) {
@@ -60171,7 +60199,8 @@ function buildDeployHandlers(deps) {
60171
60199
  }
60172
60200
  try {
60173
60201
  await rerunJob(api, slug, jobId);
60174
- runCache.delete(personaId2);
60202
+ runCache.delete(runCacheKey(personaId2));
60203
+ runCache.delete(runCacheKey(personaId2, run.headSha));
60175
60204
  } catch (err) {
60176
60205
  throw new ClawdError(ERROR_CODES.INTERNAL, err instanceof Error ? err.message : String(err));
60177
60206
  }
@@ -71308,7 +71337,7 @@ function computeMethodAccess(args) {
71308
71337
  }
71309
71338
 
71310
71339
  // src/version.ts
71311
- var version = "0.2.564".length > 0 ? "0.2.564" : "dev";
71340
+ var version = "0.2.566".length > 0 ? "0.2.566" : "dev";
71312
71341
 
71313
71342
  // src/cli-probe/probe.ts
71314
71343
  var fs78 = __toESM(require("fs"), 1);
@@ -21446,9 +21446,9 @@ var DeployReleasedSchema = external_exports.object({
21446
21446
  at: external_exports.number()
21447
21447
  }).strict();
21448
21448
  var DeployScanFileSchema = external_exports.object({
21449
- version: external_exports.literal(2),
21449
+ version: external_exports.literal(3),
21450
21450
  scans: external_exports.array(DeployScanSchema),
21451
- released: DeployReleasedSchema.optional()
21451
+ releases: external_exports.array(DeployReleasedSchema)
21452
21452
  }).strict();
21453
21453
  var DeployRepoSchema = external_exports.object({
21454
21454
  url: external_exports.string().min(1),
@@ -21457,10 +21457,11 @@ var DeployRepoSchema = external_exports.object({
21457
21457
  /**
21458
21458
  * persona 的**内容**有没有未提交的改动。
21459
21459
  *
21460
- * **`.clawd/deploy.json` 不算**(daemon 侧 `repoInfo` 把它排出了 pathspec):那个文件是
21461
- * 对 persona 的**断言**——扫描在写、页面上编辑清单也在写。算进来的话每扫一次就把自己
21462
- * 弄脏一次,`isScanFresh` 永远为假、发布再也点不亮。排除的只有这一个文件,
21463
- * `.clawd/` 下别的(persona.json 等)照旧算。
21460
+ * **两个文件不算**(daemon 侧 `repoInfo` 的 `DIRTY_IGNORED` 把它们排出了 pathspec):
21461
+ * - `.clawd/deploy.json`——发布产物,`deploy:release` 那一刻整份重写;算进来的话发布前后那几秒页面会闪「有未提交的改动」
21462
+ * - `.clawd/persona.json`——结构化配置(tool / model / size …),扫描不读它、流水线从发布 commit 读它,改了不需要重扫
21463
+ * (design 2026-09-21-deploy-page-polish §3.4)
21464
+ * `.clawd/` 下别的、以及 persona 的内容(CLAUDE.md / skills / .mcp.json)照旧算。
21464
21465
  */
21465
21466
  dirty: external_exports.boolean(),
21466
21467
  /** 本地领先远端几个提交 */
@@ -21500,13 +21501,13 @@ var DeployStateSchema = external_exports.object({
21500
21501
  repo: DeployRepoSchema.optional(),
21501
21502
  /** 扫描历史,升序,最后一条最新。没扫过就是空数组 */
21502
21503
  scans: external_exports.array(DeployScanSchema).default([]),
21503
- /** 线上正跑的是哪一版;从没发布过就缺席 */
21504
- released: DeployReleasedSchema.optional(),
21504
+ /** 发布历史,升序,最后一条 = 线上正跑的那版。从没发布过就是空数组 */
21505
+ releases: external_exports.array(DeployReleasedSchema).default([]),
21505
21506
  /** 没仓库时缺席(查不了) */
21506
21507
  secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
21507
21508
  /**
21508
- * 最新那次流水线走到哪了。**缺席是常态**:没推过、没授权 GitHub、GitHub 查不到、仓库还没有 run,
21509
- * 都不该让整页打不开——同 `secrets` 的处理。
21509
+ * 流水线走到哪了:不带 `releaseHead` 时是仓库最新那条 run(= 最后一次发布的),带了就是指名那次发布的。
21510
+ * **缺席是常态**:没推过、没授权 GitHub、GitHub 查不到、仓库还没有 run,都不该让整页打不开——同 `secrets` 的处理。
21510
21511
  */
21511
21512
  run: DeployRunSchema.optional(),
21512
21513
  /**
@@ -21522,6 +21523,9 @@ var DeployReleaseResultSchema = external_exports.object({
21522
21523
  var DeployPersonaArgsSchema = external_exports.object({
21523
21524
  personaId: external_exports.string().min(1)
21524
21525
  }).strict();
21526
+ var DeployGetArgsSchema = DeployPersonaArgsSchema.extend({
21527
+ releaseHead: external_exports.string().min(1).optional()
21528
+ }).strict();
21525
21529
  var DeployScanArgsSchema = DeployPersonaArgsSchema.extend({
21526
21530
  scanBase: ScanBaseKindSchema.optional()
21527
21531
  }).strict();
@@ -24008,8 +24012,8 @@ var METHOD_DOCS = {
24008
24012
  },
24009
24013
  // ---- deploy:*(persona 上云:persona 目录 = git 仓库工作树,发布 = 推送触发仓库流水线)----
24010
24014
  "deploy:get": {
24011
- summary: "\u4E0A\u4E91\u9875\u9762\u8981\u7684\u5168\u90E8\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\uFF08git \u73B0\u7B97\uFF09\u3001\u626B\u63CF\u5386\u53F2\uFF08\u6BCF\u6761\u5E26\u6E05\u5355\u5FEB\u7167\uFF09\u3001\u7EBF\u4E0A\u6B63\u8DD1\u7684\u662F\u54EA\u4E00\u7248\u3001\u4ED3\u5E93 Secrets \u91CC\u5404\u53D8\u91CF\u540D\u586B\u8FC7\u6CA1\u6709\uFF08**\u53EA\u6709\u540D\u5B57\u548C\u65F6\u95F4\uFF0C\u6CA1\u6709\u503C**\uFF09\uFF1Bowner-only",
24012
- args: DeployPersonaArgsSchema
24015
+ summary: "\u4E0A\u4E91\u9875\u9762\u8981\u7684\u5168\u90E8\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\uFF08git \u73B0\u7B97\uFF09\u3001\u626B\u63CF\u5386\u53F2\uFF08\u6BCF\u6761\u5E26\u6E05\u5355\u5FEB\u7167\uFF09\u3001\u53D1\u5E03\u5386\u53F2\uFF08\u6700\u540E\u4E00\u6761 = \u7EBF\u4E0A\u6B63\u8DD1\u7684\uFF09\u3001\u4ED3\u5E93 Secrets \u91CC\u5404\u53D8\u91CF\u540D\u586B\u8FC7\u6CA1\u6709\uFF08**\u53EA\u6709\u540D\u5B57\u548C\u65F6\u95F4\uFF0C\u6CA1\u6709\u503C**\uFF09\u3001\u4E00\u6761\u6D41\u6C34\u7EBF\u72B6\u6001\uFF08\u7F3A\u7701\u4ED3\u5E93\u6700\u65B0\u90A3\u6761\uFF1B`releaseHead` \u6307\u540D\u770B\u54EA\u6B21\u53D1\u5E03\u7684\uFF09\uFF1Bowner-only",
24016
+ args: DeployGetArgsSchema
24013
24017
  },
24014
24018
  "deploy:scan": {
24015
24019
  summary: "\u8D77\u4E00\u6B21\u626B\u63CF\u3002**\u6CA1\u4ED3\u5E93\u5148\u5EFA\u4ED3**\uFF08GitHub REST \u5EFA\u5728\u7EC4\u7EC7\u4E0B\u3001\u79C1\u6709\uFF0Cgit \u63A8\u9996\u4E2A\u63D0\u4EA4\uFF1Btoken \u6765\u81EA\u672C\u673A git \u7684\u8EAB\u4EFD\uFF0C\u6CA1\u6388\u6743\u5148\u62D2\uFF09\u3002\u628A persona \u76EE\u5F55\u63D0\u4EA4\u5230\u672C\u5730\uFF08\u4E0D\u63A8\uFF09\u3001\u5728\u626B\u63CF\u5386\u53F2\u91CC\u8FFD\u52A0\u4E00\u6761\u3001\u8D77 persona-butler \u7684\u626B\u63CF\u4F1A\u8BDD\uFF1B\u6B63\u5728\u626B\u7684\u8BDD\u539F\u6837\u8FD4\u56DE\u4E0D\u8D77\u7B2C\u4E8C\u4E2A\u4F1A\u8BDD\u3002\u5E26 scanBase\uFF08hard / soft\uFF09\u6309\u8BE5\u6863\u4F4D\u626B\uFF08soft \u4E0D\u6210\u7ACB\u81EA\u52A8\u9000 hard\uFF09\uFF0C\u7F3A\u5E2D daemon \u81EA\u52A8\u5B9A\uFF1Bowner-only",