@clawos-dev/clawd 0.2.712 → 0.2.714

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.
@@ -31495,7 +31495,9 @@ var DeployConfigSchema = external_exports.object({
31495
31495
  effort: external_exports.string(),
31496
31496
  size: external_exports.string().min(1),
31497
31497
  cpu: external_exports.number().positive(),
31498
- taskConcurrency: external_exports.number().int().positive()
31498
+ taskConcurrency: external_exports.number().int().positive(),
31499
+ // Optional to preserve the exact serialization of legacy attested configs.
31500
+ minPods: external_exports.number().int().nonnegative().safe().optional()
31499
31501
  }).strict();
31500
31502
  var VerifiedPersonaReleaseSchema = external_exports.object({
31501
31503
  version: external_exports.literal(1),
@@ -31561,6 +31563,8 @@ var PersonaFileSchema = external_exports.object({
31561
31563
  cpu: external_exports.number().finite().optional(),
31562
31564
  /** Cloud task-Pod concurrency, validated at release. Local execution ignores it; changes apply on the next publication. */
31563
31565
  taskConcurrency: external_exports.number().int().positive().optional(),
31566
+ /** Cloud-wide warm capacity; user identity is assigned only when a Pod is claimed. */
31567
+ minPods: external_exports.number().int().nonnegative().safe().optional(),
31564
31568
  cloudEngine: PersonaCloudEngineSchema.optional(),
31565
31569
  createdAt: external_exports.number(),
31566
31570
  updatedAt: external_exports.number(),
@@ -31661,6 +31665,7 @@ var PersonaUpdateArgsSchema = external_exports.object({
31661
31665
  size: PersonaSizeSchema.optional(),
31662
31666
  cpu: PersonaCpuSchema.optional(),
31663
31667
  taskConcurrency: PersonaFileSchema.shape.taskConcurrency,
31668
+ minPods: PersonaFileSchema.shape.minPods,
31664
31669
  // 整体替换(上云页每次交完整的 { model, effort });切 tool 不清它
31665
31670
  cloudEngine: PersonaCloudEngineSchema.optional(),
31666
31671
  personality: external_exports.string().optional(),
@@ -31803,6 +31808,22 @@ var DeployUnpublishRunSchema = external_exports.object({
31803
31808
  conclusion: external_exports.enum(["success", "failure"]).optional(),
31804
31809
  htmlUrl: external_exports.string().min(1)
31805
31810
  }).strict();
31811
+ var ReservationStateSchema = external_exports.object({
31812
+ desired: external_exports.number().int().nonnegative().safe(),
31813
+ ready: external_exports.number().int().nonnegative().safe(),
31814
+ bound: external_exports.number().int().nonnegative().safe(),
31815
+ starting: external_exports.number().int().nonnegative().safe(),
31816
+ retiring: external_exports.number().int().nonnegative().safe(),
31817
+ observedAt: external_exports.number(),
31818
+ error: external_exports.string().nullable()
31819
+ }).strict();
31820
+ var DeployCloudStatusSchema = external_exports.object({
31821
+ online: external_exports.boolean().optional(),
31822
+ image: ImageDigestSchema.optional(),
31823
+ minPods: external_exports.number().int().nonnegative().safe().optional(),
31824
+ reservation: ReservationStateSchema.nullable().optional(),
31825
+ reservationError: external_exports.string().optional()
31826
+ }).strict();
31806
31827
  var DeployStateSchema = external_exports.object({
31807
31828
  personaId: external_exports.string().min(1),
31808
31829
  engineChannels: DeployEngineChannelsSchema.optional(),
@@ -31818,20 +31839,8 @@ var DeployStateSchema = external_exports.object({
31818
31839
  releases: external_exports.array(DeployReleasedSchema).default([]),
31819
31840
  promotions: external_exports.array(DeployPromotionSchema).optional(),
31820
31841
  targets: external_exports.object({
31821
- integration: external_exports.object({
31822
- run: DeployRunSchema.optional(),
31823
- secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
31824
- online: external_exports.boolean().optional(),
31825
- image: ImageDigestSchema.optional(),
31826
- unpublish: DeployUnpublishRunSchema.optional()
31827
- }).strict().optional(),
31828
- production: external_exports.object({
31829
- run: DeployRunSchema.optional(),
31830
- secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
31831
- online: external_exports.boolean().optional(),
31832
- image: ImageDigestSchema.optional(),
31833
- unpublish: DeployUnpublishRunSchema.optional()
31834
- }).strict().optional()
31842
+ integration: DeployCloudStatusSchema.extend({ run: DeployRunSchema.optional(), secrets: external_exports.array(DeploySecretPresenceSchema).optional(), unpublish: DeployUnpublishRunSchema.optional() }).optional(),
31843
+ production: DeployCloudStatusSchema.extend({ run: DeployRunSchema.optional(), secrets: external_exports.array(DeploySecretPresenceSchema).optional(), unpublish: DeployUnpublishRunSchema.optional() }).optional()
31835
31844
  }).strict().optional(),
31836
31845
  /** 没仓库时缺席(查不了) */
31837
31846
  secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
@@ -34795,6 +34804,7 @@ function renderDeployWorkflow(config2) {
34795
34804
  " --cpu '${{ steps.plan.outputs.cpu }}' \\",
34796
34805
  " --config-source '${{ steps.plan.outputs.config_source }}' \\",
34797
34806
  " --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
34807
+ " --min-pods '${{ steps.plan.outputs.min_pods }}' \\",
34798
34808
  " --engine '${{ steps.plan.outputs.engine }}' \\",
34799
34809
  " --connectors '${{ steps.plan.outputs.connectors }}' \\",
34800
34810
  " --run-number '${{ github.run_number }}'",
package/dist/cli.cjs CHANGED
@@ -6205,6 +6205,7 @@ var init_environment_schemas = __esm({
6205
6205
  "go",
6206
6206
  "chromium",
6207
6207
  "fonts-wqy-microhei",
6208
+ "openssh-server",
6208
6209
  "pnpm",
6209
6210
  "whiteboard-cli",
6210
6211
  "s",
@@ -6374,7 +6375,9 @@ var init_release_schemas = __esm({
6374
6375
  effort: external_exports.string(),
6375
6376
  size: external_exports.string().min(1),
6376
6377
  cpu: external_exports.number().positive(),
6377
- taskConcurrency: external_exports.number().int().positive()
6378
+ taskConcurrency: external_exports.number().int().positive(),
6379
+ // Optional to preserve the exact serialization of legacy attested configs.
6380
+ minPods: external_exports.number().int().nonnegative().safe().optional()
6378
6381
  }).strict();
6379
6382
  VerifiedPersonaReleaseSchema = external_exports.object({
6380
6383
  version: external_exports.literal(1),
@@ -6469,6 +6472,8 @@ var init_persona_schemas = __esm({
6469
6472
  cpu: external_exports.number().finite().optional(),
6470
6473
  /** Cloud task-Pod concurrency, validated at release. Local execution ignores it; changes apply on the next publication. */
6471
6474
  taskConcurrency: external_exports.number().int().positive().optional(),
6475
+ /** Cloud-wide warm capacity; user identity is assigned only when a Pod is claimed. */
6476
+ minPods: external_exports.number().int().nonnegative().safe().optional(),
6472
6477
  cloudEngine: PersonaCloudEngineSchema.optional(),
6473
6478
  createdAt: external_exports.number(),
6474
6479
  updatedAt: external_exports.number(),
@@ -6569,6 +6574,7 @@ var init_persona_schemas = __esm({
6569
6574
  size: PersonaSizeSchema.optional(),
6570
6575
  cpu: PersonaCpuSchema.optional(),
6571
6576
  taskConcurrency: PersonaFileSchema.shape.taskConcurrency,
6577
+ minPods: PersonaFileSchema.shape.minPods,
6572
6578
  // 整体替换(上云页每次交完整的 { model, effort });切 tool 不清它
6573
6579
  cloudEngine: PersonaCloudEngineSchema.optional(),
6574
6580
  personality: external_exports.string().optional(),
@@ -6635,16 +6641,16 @@ function configOfPersona(p3) {
6635
6641
  const { tool, model, effort } = cloudEngineSettings(p3);
6636
6642
  const size = (p3.size ?? "").trim() || DEFAULT_PERSONA_SIZE;
6637
6643
  const cpu = p3.cpu ?? PERSONA_CPU_DEFAULTS[size] ?? PERSONA_CPU_DEFAULTS[DEFAULT_PERSONA_SIZE];
6638
- return { engine: tool, model: model.trim(), effort: effort.trim(), size, cpu, taskConcurrency: p3.taskConcurrency ?? DEFAULT_TASK_CONCURRENCY };
6644
+ return { engine: tool, model: model.trim(), effort: effort.trim(), size, cpu, taskConcurrency: p3.taskConcurrency ?? DEFAULT_TASK_CONCURRENCY, minPods: p3.minPods ?? 0 };
6639
6645
  }
6640
6646
  function changedConfigKeys(a2, b3) {
6641
6647
  if (!a2 || !b3) return null;
6642
- return CONFIG_KEYS.filter((key) => a2[key] !== b3[key]);
6648
+ return CONFIG_KEYS.filter((key) => key === "minPods" ? (a2.minPods ?? 0) !== (b3.minPods ?? 0) : a2[key] !== b3[key]);
6643
6649
  }
6644
6650
  function repoSlug(url) {
6645
6651
  return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
6646
6652
  }
6647
- var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DEPLOY_PROMOTION_PHASES, DeployPromotionSchema, DeployEngineChannelSchema, DeployEngineChannelsSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, ENGINE_AUTH_SECRETS, ENGINE_AUTH_PARTIAL_BLOCKER, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_VERIFY_STAGE, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployUnpublishRunSchema, DeployStateSchema, DeployUnpublishResultSchema, DeployLocalStateSchema, DeployPatchResultSchema, DeploySecretsResultSchema, DEPLOY_WORKFLOW_VERSION, DEFAULT_TASK_CONCURRENCY, CONFIG_KEYS, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployApplyConfigArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6653
+ var DeployFileSchema, SCAN_BASE_KINDS, ScanBaseKindSchema, DeployScanStatusSchema, DeployScanSchema, DeployReleasedSchema, DEPLOY_PROMOTION_PHASES, DeployPromotionSchema, DeployEngineChannelSchema, DeployEngineChannelsSchema, DeployScanFileSchema, DeployRepoSchema, DeploySecretPresenceSchema, ENGINE_AUTH_SECRETS, ENGINE_AUTH_PARTIAL_BLOCKER, DEPLOY_STAGE_STATUSES, DeployStageStatusSchema, DEPLOY_VERIFY_STAGE, DEPLOY_STAGE_KEYS, DeployStageKeySchema, DeployJobSchema, DeployRunSchema, CLOUD_ENGINES, DeployUnpublishRunSchema, ReservationStateSchema, DeployCloudStatusSchema, DeployStateSchema, DeployUnpublishResultSchema, DeployLocalStateSchema, DeployPatchResultSchema, DeploySecretsResultSchema, DEPLOY_WORKFLOW_VERSION, workflowVersionForConfigKeys, DEFAULT_TASK_CONCURRENCY, CONFIG_KEYS, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployApplyConfigArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6648
6654
  var init_deploy_schemas = __esm({
6649
6655
  "../protocol/src/deploy-schemas.ts"() {
6650
6656
  "use strict";
@@ -6781,6 +6787,22 @@ var init_deploy_schemas = __esm({
6781
6787
  conclusion: external_exports.enum(["success", "failure"]).optional(),
6782
6788
  htmlUrl: external_exports.string().min(1)
6783
6789
  }).strict();
6790
+ ReservationStateSchema = external_exports.object({
6791
+ desired: external_exports.number().int().nonnegative().safe(),
6792
+ ready: external_exports.number().int().nonnegative().safe(),
6793
+ bound: external_exports.number().int().nonnegative().safe(),
6794
+ starting: external_exports.number().int().nonnegative().safe(),
6795
+ retiring: external_exports.number().int().nonnegative().safe(),
6796
+ observedAt: external_exports.number(),
6797
+ error: external_exports.string().nullable()
6798
+ }).strict();
6799
+ DeployCloudStatusSchema = external_exports.object({
6800
+ online: external_exports.boolean().optional(),
6801
+ image: ImageDigestSchema.optional(),
6802
+ minPods: external_exports.number().int().nonnegative().safe().optional(),
6803
+ reservation: ReservationStateSchema.nullable().optional(),
6804
+ reservationError: external_exports.string().optional()
6805
+ }).strict();
6784
6806
  DeployStateSchema = external_exports.object({
6785
6807
  personaId: external_exports.string().min(1),
6786
6808
  engineChannels: DeployEngineChannelsSchema.optional(),
@@ -6796,20 +6818,8 @@ var init_deploy_schemas = __esm({
6796
6818
  releases: external_exports.array(DeployReleasedSchema).default([]),
6797
6819
  promotions: external_exports.array(DeployPromotionSchema).optional(),
6798
6820
  targets: external_exports.object({
6799
- integration: external_exports.object({
6800
- run: DeployRunSchema.optional(),
6801
- secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
6802
- online: external_exports.boolean().optional(),
6803
- image: ImageDigestSchema.optional(),
6804
- unpublish: DeployUnpublishRunSchema.optional()
6805
- }).strict().optional(),
6806
- production: external_exports.object({
6807
- run: DeployRunSchema.optional(),
6808
- secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
6809
- online: external_exports.boolean().optional(),
6810
- image: ImageDigestSchema.optional(),
6811
- unpublish: DeployUnpublishRunSchema.optional()
6812
- }).strict().optional()
6821
+ integration: DeployCloudStatusSchema.extend({ run: DeployRunSchema.optional(), secrets: external_exports.array(DeploySecretPresenceSchema).optional(), unpublish: DeployUnpublishRunSchema.optional() }).optional(),
6822
+ production: DeployCloudStatusSchema.extend({ run: DeployRunSchema.optional(), secrets: external_exports.array(DeploySecretPresenceSchema).optional(), unpublish: DeployUnpublishRunSchema.optional() }).optional()
6813
6823
  }).strict().optional(),
6814
6824
  /** 没仓库时缺席(查不了) */
6815
6825
  secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
@@ -6850,9 +6860,10 @@ var init_deploy_schemas = __esm({
6850
6860
  secrets: external_exports.array(DeploySecretPresenceSchema).optional(),
6851
6861
  engineChannels: DeployEngineChannelsSchema.optional()
6852
6862
  }).strict();
6853
- DEPLOY_WORKFLOW_VERSION = 2;
6863
+ DEPLOY_WORKFLOW_VERSION = 3;
6864
+ workflowVersionForConfigKeys = (keys) => keys.includes("minPods") ? 3 : 2;
6854
6865
  DEFAULT_TASK_CONCURRENCY = 4;
6855
- CONFIG_KEYS = ["engine", "model", "effort", "size", "cpu", "taskConcurrency"];
6866
+ CONFIG_KEYS = ["engine", "model", "effort", "size", "cpu", "taskConcurrency", "minPods"];
6856
6867
  DeployReleaseResultSchema = external_exports.object({
6857
6868
  sha: external_exports.string().min(1),
6858
6869
  actionsUrl: external_exports.string().min(1),
@@ -58271,6 +58282,7 @@ var CloudGatewayClient = class {
58271
58282
  ...typeof d2.model === "string" && d2.model ? { model: d2.model } : {},
58272
58283
  ...typeof d2.effort === "string" && d2.effort ? { effort: d2.effort } : {},
58273
58284
  ...typeof d2.registeredAt === "number" ? { registeredAt: d2.registeredAt } : {},
58285
+ ...typeof d2.minPods === "number" && Number.isSafeInteger(d2.minPods) && d2.minPods >= 0 ? { minPods: d2.minPods } : {},
58274
58286
  ...Array.isArray(d2.connectors) ? { connectors: d2.connectors.map((c2) => EnvConnectorSchema.safeParse(c2)).flatMap((p3) => p3.success ? [p3.data] : []) } : {}
58275
58287
  });
58276
58288
  }
@@ -58383,6 +58395,7 @@ var CloudGatewayClient = class {
58383
58395
  const qs = new URLSearchParams();
58384
58396
  if (q3.window) qs.set("window", q3.window);
58385
58397
  if (q3.entry) qs.set("entry", q3.entry);
58398
+ if (q3.reservationOnly) qs.set("part", "reservation");
58386
58399
  const query = qs.toString();
58387
58400
  try {
58388
58401
  const res = await this.fetchImpl(gatewayUrl + GATEWAY_ROUTES.metrics(q3.personaId) + (query ? `?${query}` : ""), {
@@ -62853,6 +62866,7 @@ function renderDeployWorkflow(config) {
62853
62866
  " --cpu '${{ steps.plan.outputs.cpu }}' \\",
62854
62867
  " --config-source '${{ steps.plan.outputs.config_source }}' \\",
62855
62868
  " --task-concurrency '${{ steps.plan.outputs.task_concurrency }}' \\",
62869
+ " --min-pods '${{ steps.plan.outputs.min_pods }}' \\",
62856
62870
  " --engine '${{ steps.plan.outputs.engine }}' \\",
62857
62871
  " --connectors '${{ steps.plan.outputs.connectors }}' \\",
62858
62872
  " --run-number '${{ github.run_number }}'",
@@ -64305,7 +64319,7 @@ function buildDeployHandlers(deps) {
64305
64319
  const latestPromotion = file.promotions.at(-1);
64306
64320
  const cloud = file.releases.some((r2) => r2.environment === environment2) || environment2 === "production" && latestPromotion ? await measure("cloud", () => cachedCloud(personaId2, environment2, targetRun, targetUnpublish, cloudName, () => observe(environment2), snapshots.has(environment2)), { environment: environment2 }) : {};
64307
64321
  const { image, online: targetOnline } = cloud;
64308
- return { ...targetUnpublish ? { unpublish: targetUnpublish } : {}, ...targetRun ? { run: targetRun } : {}, ...targetSecretsList ? { secrets: targetSecretsList } : {}, ...image ? { image } : {}, ...targetOnline !== void 0 ? { online: targetOnline } : {} };
64322
+ return { ...cloud, ...targetUnpublish ? { unpublish: targetUnpublish } : {}, ...targetRun ? { run: targetRun } : {}, ...targetSecretsList ? { secrets: targetSecretsList } : {}, ...image ? { image } : {}, ...targetOnline !== void 0 ? { online: targetOnline } : {} };
64309
64323
  };
64310
64324
  const productionRunRead = Promise.all([prodRunRead, legacyRunRead]).then(([prodRun2, legacyRun2]) => prodRun2 ?? (latestProductionRelease(file.releases)?.legacy ? legacyRun2 : void 0));
64311
64325
  const settled = await Promise.allSettled([loadTarget("integration", intRunRead), loadTarget("production", productionRunRead), intRunRead, prodRunRead, legacyRunRead]);
@@ -64663,7 +64677,7 @@ function buildDeployHandlers(deps) {
64663
64677
  return void 0;
64664
64678
  }
64665
64679
  };
64666
- const CONFIG_KEY_LABEL = { engine: "\u5F15\u64CE", model: "\u6A21\u578B", effort: "\u63A8\u7406\u6863\u4F4D", size: "\u89C4\u683C", cpu: "CPU", taskConcurrency: "\u4EFB\u52A1\u5E76\u53D1" };
64680
+ const CONFIG_KEY_LABEL = { engine: "\u5F15\u64CE", model: "\u6A21\u578B", effort: "\u63A8\u7406\u6863\u4F4D", size: "\u89C4\u683C", cpu: "CPU", taskConcurrency: "\u4EFB\u52A1\u5E76\u53D1", minPods: "\u4FDD\u5E95 Pod \u6570" };
64667
64681
  const assertConfigTested = async (personaId2, record4) => {
64668
64682
  const changed = changedConfigKeys(configOfPersona(deps.personaEngine(personaId2) ?? {}), await testedConfigOf(mustPersona(personaId2), record4));
64669
64683
  if (changed?.length) throw invalid(`\u914D\u7F6E\u6539\u8FC7\u4E86\uFF08${changed.map((k3) => CONFIG_KEY_LABEL[k3]).join("\u3001")}\uFF09\uFF0C\u5148\u300C\u5E94\u7528\u5230\u6D4B\u8BD5\u73AF\u5883\u300D\u5E76\u786E\u8BA4\uFF0C\u518D\u4E0A\u7EBF`);
@@ -64935,7 +64949,7 @@ function buildDeployHandlers(deps) {
64935
64949
  const file = await readHistory(dir);
64936
64950
  const latest = [...file.releases].reverse().find((r2) => r2.environment === "integration");
64937
64951
  if (!latest || latest.id !== releaseId) throw invalid("\u53EA\u80FD\u5BF9\u6700\u65B0\u4E00\u6B21\u6D4B\u8BD5\u53D1\u5E03\u5E94\u7528\u914D\u7F6E\uFF0C\u5237\u65B0\u9875\u9762\u540E\u518D\u8BD5");
64938
- if (!latest.workflowVersion || latest.workflowVersion < DEPLOY_WORKFLOW_VERSION) throw invalid("\u8FD9\u4E2A\u4ED3\u5E93\u7684\u53D1\u5E03\u6D41\u6C34\u7EBF\u662F\u65E7\u7248\u672C\uFF0C\u4E0D\u8BA4\u65B0\u914D\u7F6E\u2014\u2014\u8BF7\u5148\u5B8C\u6574\u91CD\u65B0\u53D1\u5E03\u4E00\u6B21\uFF08\u4F1A\u91CD\u65B0\u6784\u5EFA\uFF09");
64952
+ if (!latest.workflowVersion) throw invalid("\u8FD9\u4E2A\u4ED3\u5E93\u7684\u53D1\u5E03\u6D41\u6C34\u7EBF\u662F\u65E7\u7248\u672C\uFF0C\u4E0D\u8BA4\u65B0\u914D\u7F6E\u2014\u2014\u8BF7\u5148\u5B8C\u6574\u91CD\u65B0\u53D1\u5E03\u4E00\u6B21\uFF08\u4F1A\u91CD\u65B0\u6784\u5EFA\uFF09");
64939
64953
  const repo2 = await repoInfo(deps.exec, dir);
64940
64954
  if (!repo2) throw invalid("\u4ED3\u5E93\u4E0D\u5B58\u5728");
64941
64955
  const { api } = await requireGithub();
@@ -64954,7 +64968,9 @@ function buildDeployHandlers(deps) {
64954
64968
  const source = await testedRelease(personaId2, base.id, false);
64955
64969
  const config = configOfPersona(deps.personaEngine(personaId2) ?? {});
64956
64970
  if (!config.model) throw invalid("\u8FD8\u6CA1\u9009\u6A21\u578B\u2014\u2014\u5728\u4E0A\u4E91\u9875\u300C\u5F15\u64CE\u4E0E\u6A21\u578B\u300D\u91CC\u9009\u4E00\u4E2A");
64957
- if (!retryAfterFailure && !(changedConfigKeys(config, await testedConfigOf(dir, source)) ?? ["engine"]).length) throw invalid("\u914D\u7F6E\u548C\u6D4B\u8BD5\u73AF\u5883\u91CC\u7684\u4E00\u81F4\uFF0C\u6CA1\u6709\u9700\u8981\u5E94\u7528\u7684");
64971
+ const keys = changedConfigKeys(config, await testedConfigOf(dir, source));
64972
+ if (!retryAfterFailure && keys?.length === 0) throw invalid("\u914D\u7F6E\u548C\u6D4B\u8BD5\u73AF\u5883\u91CC\u7684\u4E00\u81F4\uFF0C\u6CA1\u6709\u9700\u8981\u5E94\u7528\u7684");
64973
+ if (latest.workflowVersion < (keys ? workflowVersionForConfigKeys(keys) : DEPLOY_WORKFLOW_VERSION)) throw invalid("\u8FD9\u4E2A\u4ED3\u5E93\u7684\u53D1\u5E03\u6D41\u6C34\u7EBF\u662F\u65E7\u7248\u672C\uFF0C\u4E0D\u8BA4\u4FDD\u5E95 Pod \u6570\u2014\u2014\u8BF7\u5148\u5B8C\u6574\u91CD\u65B0\u53D1\u5E03\u4E00\u6B21\uFF08\u4F1A\u91CD\u65B0\u6784\u5EFA\uFF09");
64958
64974
  const id = (0, import_node_crypto15.randomUUID)();
64959
64975
  try {
64960
64976
  await api.dispatchWorkflow(slug, DEPLOY_WORKFLOW_FILE, "integration", { environment: "integration", release_json: JSON.stringify(source.verified), config_json: JSON.stringify(config), config_id: id });
@@ -65258,6 +65274,7 @@ var SubscriptionChannelStore = class {
65258
65274
 
65259
65275
  // src/index.ts
65260
65276
  init_subscription_channels_apply();
65277
+ init_protocol();
65261
65278
 
65262
65279
  // src/deploy/local-probe.ts
65263
65280
  function pickVersion(s2) {
@@ -75962,7 +75979,7 @@ function computeMethodAccess(args) {
75962
75979
  }
75963
75980
 
75964
75981
  // src/version.ts
75965
- var version = "0.2.712".length > 0 ? "0.2.712" : "dev";
75982
+ var version = "0.2.714".length > 0 ? "0.2.714" : "dev";
75966
75983
 
75967
75984
  // src/cli-probe/probe.ts
75968
75985
  var fs87 = __toESM(require("fs"), 1);
@@ -79652,7 +79669,7 @@ async function startDaemon(config) {
79652
79669
  personaDir: (personaId2) => personaStore.personaDirPath(personaId2),
79653
79670
  personaEngine: (personaId2) => {
79654
79671
  const p3 = personaRegistry.get(personaId2);
79655
- return p3 ? { ...p3.tool ? { tool: p3.tool } : {}, ...p3.model ? { model: p3.model } : {}, ...p3.effort ? { effort: p3.effort } : {}, ...p3.cloudEngine ? { cloudEngine: p3.cloudEngine } : {}, ...p3.size ? { size: p3.size } : {}, ...p3.cpu !== void 0 ? { cpu: p3.cpu } : {}, ...p3.taskConcurrency !== void 0 ? { taskConcurrency: p3.taskConcurrency } : {} } : void 0;
79672
+ return p3 ? { ...p3.tool ? { tool: p3.tool } : {}, ...p3.model ? { model: p3.model } : {}, ...p3.effort ? { effort: p3.effort } : {}, ...p3.cloudEngine ? { cloudEngine: p3.cloudEngine } : {}, ...p3.size ? { size: p3.size } : {}, ...p3.cpu !== void 0 ? { cpu: p3.cpu } : {}, ...p3.taskConcurrency !== void 0 ? { taskConcurrency: p3.taskConcurrency } : {}, ...p3.minPods !== void 0 ? { minPods: p3.minPods } : {} } : void 0;
79656
79673
  },
79657
79674
  exec: runCommand,
79658
79675
  // 探本机前刷一次登录 shell 的 PATH:daemon 继承的是 app 启动时的快照,之后装的 CLI(~/.local/bin)看不见。
@@ -79687,9 +79704,20 @@ async function startDaemon(config) {
79687
79704
  // 拉不到(没登录飞书 / gateway 不通 / healthz 5s 没回)→ undefined,页面不给下线按钮也不撤「线上」标。
79688
79705
  // 失败上界:中心那一跳自带 15s,healthz 这一趟 5s——deploy:get 要保证页面打得开,gateway 接了连接不回时不能挂到 undici 默认的 300s
79689
79706
  cloudState: async (personaId2, environment) => {
79690
- const list = await gatewayForEnvironment(environment).listPersonas({ healthzTimeoutMs: 5e3 });
79707
+ const gateway = gatewayForEnvironment(environment);
79708
+ const list = await gateway.listPersonas({ healthzTimeoutMs: 5e3 });
79691
79709
  const persona = list.find((p3) => p3.personaId === personaId2);
79692
- return { online: persona !== void 0, ...persona?.image ? { image: persona.image } : {} };
79710
+ const base = { online: persona !== void 0, ...persona?.image ? { image: persona.image } : {}, minPods: persona?.minPods ?? 0 };
79711
+ if (!base.minPods) return base;
79712
+ try {
79713
+ const response = await gateway.fetchMetrics({ personaId: personaId2, window: null, entry: null, reservationOnly: true });
79714
+ if (response.status !== 200) throw new Error("\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u9884\u7559 Pod \u72B6\u6001");
79715
+ const parsed = ReservationStateSchema.safeParse(JSON.parse(response.body).reservation);
79716
+ if (!parsed.success) throw new Error("gateway \u672A\u8FD4\u56DE\u6709\u6548\u7684\u9884\u7559\u72B6\u6001");
79717
+ return { ...base, reservation: parsed.data };
79718
+ } catch (e) {
79719
+ return { ...base, reservation: null, reservationError: e instanceof Error ? e.message : "\u6682\u65F6\u65E0\u6CD5\u786E\u8BA4\u9884\u7559 Pod \u72B6\u6001" };
79720
+ }
79693
79721
  },
79694
79722
  publisherFeishuAuth: async (personaId2, environment) => {
79695
79723
  const loginPass = requireEnvironmentIdentity(environmentStores, environment).loginPass;