@clawos-dev/clawd 0.2.664 → 0.2.665

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.
@@ -31584,6 +31584,16 @@ var DeployStateSchema = external_exports.object({
31584
31584
  var DeployUnpublishResultSchema = external_exports.object({
31585
31585
  before: external_exports.number().nullable()
31586
31586
  }).strict();
31587
+ var DeployLocalStateSchema = DeployStateSchema.pick({
31588
+ personaId: true,
31589
+ github: true,
31590
+ repo: true,
31591
+ scans: true,
31592
+ releases: true,
31593
+ promotions: true,
31594
+ engineChannels: true,
31595
+ historyError: true
31596
+ });
31587
31597
  var DeployPatchResultSchema = DeployStateSchema.pick({ scans: true });
31588
31598
  var DeploySecretsResultSchema = external_exports.object({
31589
31599
  environment: DeployEnvironmentSchema,
@@ -33829,6 +33839,10 @@ var METHOD_DOCS = {
33829
33839
  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",
33830
33840
  args: DeployGetArgsSchema
33831
33841
  },
33842
+ "deploy:getLocal": {
33843
+ summary: "\u4E0A\u4E91\u9875\u8981\u7684**\u672C\u673A\u90E8\u5206**\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\u3001\u626B\u63CF\u5386\u53F2\u3001\u53D1\u5E03\u5386\u53F2\u3001promotion \u8BB0\u5F55\u3001GitHub \u8EAB\u4EFD\u72B6\u6001\u3001\u6A21\u578B\u8BA2\u9605\u6E20\u9053\u3002\u53EA\u8BFB\u672C\u673A\u6587\u4EF6\uFF0C**\u4E0D\u95EE GitHub Actions / gateway / \u98DE\u4E66**\uFF08\u6CA1\u6709\u6D41\u6C34\u7EBF run\u3001Secrets\u3001\u5728\u7EBF\u72B6\u6001\u3001\u4E0B\u7EBF run\uFF09\uFF0C\u4E5F\u4E0D\u89E6\u53D1\u4EFB\u4F55\u4F1A\u5199\u76D8\u7684\u8FDC\u7A0B\u526F\u4F5C\u7528\uFF1BGitHub \u767B\u5F55\u8EAB\u4EFD\u6CBF\u7528 20 \u79D2\u7F13\u5B58\uFF0C\u672A\u547D\u4E2D\u65F6\u95EE\u4E00\u6B21 GET /user\u3002\u626B\u63CF\u671F\u95F4\u8F6E\u8BE2\u3001persona \u5361\u7247\u7528\u5B83\uFF1B\u8981\u5B8C\u6574\u72B6\u6001\u8D70 deploy:get\uFF1Bowner-only",
33844
+ args: DeployPersonaArgsSchema
33845
+ },
33832
33846
  "deploy:scan": {
33833
33847
  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",
33834
33848
  args: DeployScanArgsSchema
package/dist/cli.cjs CHANGED
@@ -6317,7 +6317,7 @@ function cloudEngineSettings(p3) {
6317
6317
  function repoSlug(url) {
6318
6318
  return url.trim().replace(/^git@[^:]+:/, "").replace(/^https?:\/\/[^/]+\//, "").replace(/\.git$/, "");
6319
6319
  }
6320
- 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, DeployPatchResultSchema, DeploySecretsResultSchema, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6320
+ 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, DeployReleaseResultSchema, DeployPersonaArgsSchema, DeployGetArgsSchema, DeployScanArgsSchema, DeployReleaseArgsSchema, DeployConfirmTestArgsSchema, DeployPromoteArgsSchema, DeployOpenTestArgsSchema, DeployEnvironmentArgsSchema, DeployConfirmTestResultSchema, DeployPromoteResultSchema, DeployOpenTestResultSchema, DeployPatchArgsSchema, DeployPutSecretArgsSchema, DeploySetEngineAuthArgsSchema, DeployRerunJobArgsSchema, DeployReportFindingArgsSchema, DeployFinishScanArgsSchema, PERSONA_REPO_ORG;
6321
6321
  var init_deploy_schemas = __esm({
6322
6322
  "../protocol/src/deploy-schemas.ts"() {
6323
6323
  "use strict";
@@ -6500,6 +6500,16 @@ var init_deploy_schemas = __esm({
6500
6500
  DeployUnpublishResultSchema = external_exports.object({
6501
6501
  before: external_exports.number().nullable()
6502
6502
  }).strict();
6503
+ DeployLocalStateSchema = DeployStateSchema.pick({
6504
+ personaId: true,
6505
+ github: true,
6506
+ repo: true,
6507
+ scans: true,
6508
+ releases: true,
6509
+ promotions: true,
6510
+ engineChannels: true,
6511
+ historyError: true
6512
+ });
6503
6513
  DeployPatchResultSchema = DeployStateSchema.pick({ scans: true });
6504
6514
  DeploySecretsResultSchema = external_exports.object({
6505
6515
  environment: DeployEnvironmentSchema,
@@ -9059,6 +9069,10 @@ var init_methods = __esm({
9059
9069
  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",
9060
9070
  args: DeployGetArgsSchema
9061
9071
  },
9072
+ "deploy:getLocal": {
9073
+ summary: "\u4E0A\u4E91\u9875\u8981\u7684**\u672C\u673A\u90E8\u5206**\uFF1A\u4ED3\u5E93\u7ED1\u5B9A\u72B6\u6001\u3001\u626B\u63CF\u5386\u53F2\u3001\u53D1\u5E03\u5386\u53F2\u3001promotion \u8BB0\u5F55\u3001GitHub \u8EAB\u4EFD\u72B6\u6001\u3001\u6A21\u578B\u8BA2\u9605\u6E20\u9053\u3002\u53EA\u8BFB\u672C\u673A\u6587\u4EF6\uFF0C**\u4E0D\u95EE GitHub Actions / gateway / \u98DE\u4E66**\uFF08\u6CA1\u6709\u6D41\u6C34\u7EBF run\u3001Secrets\u3001\u5728\u7EBF\u72B6\u6001\u3001\u4E0B\u7EBF run\uFF09\uFF0C\u4E5F\u4E0D\u89E6\u53D1\u4EFB\u4F55\u4F1A\u5199\u76D8\u7684\u8FDC\u7A0B\u526F\u4F5C\u7528\uFF1BGitHub \u767B\u5F55\u8EAB\u4EFD\u6CBF\u7528 20 \u79D2\u7F13\u5B58\uFF0C\u672A\u547D\u4E2D\u65F6\u95EE\u4E00\u6B21 GET /user\u3002\u626B\u63CF\u671F\u95F4\u8F6E\u8BE2\u3001persona \u5361\u7247\u7528\u5B83\uFF1B\u8981\u5B8C\u6574\u72B6\u6001\u8D70 deploy:get\uFF1Bowner-only",
9074
+ args: DeployPersonaArgsSchema
9075
+ },
9062
9076
  "deploy:scan": {
9063
9077
  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",
9064
9078
  args: DeployScanArgsSchema
@@ -63466,12 +63480,44 @@ function buildDeployHandlers(deps) {
63466
63480
  for (const env of ["integration", "production"]) secretsCache.delete(personaId2 + ":" + env);
63467
63481
  secretsCache.delete(personaId2);
63468
63482
  }
63469
- async function stateOf(personaId2, selection = {}, measure = directRead) {
63470
- const { releaseHead, releaseId, environment } = selection;
63471
- const historical = releaseHead !== void 0 || releaseId !== void 0;
63483
+ async function readLocal(personaId2, historical, measure) {
63472
63484
  const dir = deps.personaDir(personaId2);
63473
63485
  const repo2 = await measure("repo", () => repoInfo(deps.exec, dir));
63474
63486
  const github = await measure("github.identity", () => deps.githubIdentity.status());
63487
+ let file = emptyScanFile();
63488
+ let historyError;
63489
+ try {
63490
+ file = await measure("history", () => readHistory(dir));
63491
+ } catch (err) {
63492
+ historyError = err instanceof Error ? err.message : String(err);
63493
+ }
63494
+ file = await measure("history.settle", () => settleStale(personaId2, dir, file));
63495
+ const pending = file.promotions.at(-1);
63496
+ const bound = pending && file.releases.find((r2) => r2.id === pending.releaseId);
63497
+ if (!historical && pending && !pending.verified && !["completed", "failed"].includes(pending.phase) && bound?.verified && bound.confirmation?.fingerprint === bound.verified.verification.fingerprint) {
63498
+ file = { ...file, promotions: file.promotions.map((p3) => p3.id === pending.id ? { ...p3, verified: bound.verified } : p3) };
63499
+ await writeScanFile(dir, file);
63500
+ }
63501
+ return { dir, repo: repo2, github, file, historyError };
63502
+ }
63503
+ async function localStateOf(personaId2, measure = directRead) {
63504
+ const { file, repo: repo2, github, historyError } = await readLocal(personaId2, false, measure);
63505
+ return {
63506
+ personaId: personaId2,
63507
+ github,
63508
+ ...file.engineChannels ? { engineChannels: file.engineChannels } : {},
63509
+ ...repo2 ? { repo: repo2 } : {},
63510
+ scans: file.scans,
63511
+ releases: file.releases,
63512
+ promotions: file.promotions,
63513
+ ...historyError ? { historyError } : {}
63514
+ };
63515
+ }
63516
+ async function stateOf(personaId2, selection = {}, measure = directRead) {
63517
+ const { releaseHead, releaseId, environment } = selection;
63518
+ const historical = releaseHead !== void 0 || releaseId !== void 0;
63519
+ const { dir, repo: repo2, github, historyError, file: stored } = await readLocal(personaId2, historical, measure);
63520
+ let file = stored;
63475
63521
  const auth = deps.githubIdentity.cached();
63476
63522
  const rawApi = auth ? deps.githubApi(auth.token) : void 0;
63477
63523
  const requests = /* @__PURE__ */ new Map();
@@ -63500,20 +63546,6 @@ function buildDeployHandlers(deps) {
63500
63546
  }
63501
63547
  return promise;
63502
63548
  };
63503
- let file = emptyScanFile();
63504
- let historyError;
63505
- try {
63506
- file = await measure("history", () => readHistory(dir));
63507
- } catch (err) {
63508
- historyError = err instanceof Error ? err.message : String(err);
63509
- }
63510
- file = await measure("history.settle", () => settleStale(personaId2, dir, file));
63511
- const pending = file.promotions.at(-1);
63512
- const bound = pending && file.releases.find((r2) => r2.id === pending.releaseId);
63513
- if (!historical && pending && !pending.verified && !["completed", "failed"].includes(pending.phase) && bound?.verified && bound.confirmation?.fingerprint === bound.verified.verification.fingerprint) {
63514
- file = { ...file, promotions: file.promotions.map((p3) => p3.id === pending.id ? { ...p3, verified: bound.verified } : p3) };
63515
- await writeScanFile(dir, file);
63516
- }
63517
63549
  const { scans } = file;
63518
63550
  const selected = releaseId ? file.releases.find((r2) => r2.id === releaseId && (!environment || r2.environment === environment)) : releaseHead ? file.releases.find((r2) => r2.head === releaseHead && (!environment || r2.environment === environment)) : void 0;
63519
63551
  const publisherFeishuAuthRead = scans.at(-1)?.manifest.connectors.some(isFeishuPublisherConnector) ? (async () => {
@@ -63559,12 +63591,12 @@ function buildDeployHandlers(deps) {
63559
63591
  return intRun2;
63560
63592
  })();
63561
63593
  const prodRunRead = (async () => {
63562
- const pending2 = file.promotions.at(-1);
63563
- if (!historical && pending2?.verified && ["dispatched", "dispatching"].includes(pending2.phase)) {
63594
+ const pending = file.promotions.at(-1);
63595
+ if (!historical && pending?.verified && ["dispatched", "dispatching"].includes(pending.phase)) {
63564
63596
  await intRunRead;
63565
- const source = file.releases.find((r2) => r2.id === pending2.releaseId);
63597
+ const source = file.releases.find((r2) => r2.id === pending.releaseId);
63566
63598
  if (source) {
63567
- await measure("promotion", () => continuePromotion(personaId2, { ...source, verified: pending2.verified }, pending2, false, api, async () => (await observe("production")).image));
63599
+ await measure("promotion", () => continuePromotion(personaId2, { ...source, verified: pending.verified }, pending, false, api, async () => (await observe("production")).image));
63568
63600
  file = await readHistory(dir);
63569
63601
  }
63570
63602
  }
@@ -63639,6 +63671,9 @@ function buildDeployHandlers(deps) {
63639
63671
  const view = async (personaId2, selection, measure) => ({
63640
63672
  response: { type: "deploy:state", ...await stateOf(personaId2, selection, measure) }
63641
63673
  });
63674
+ const localView = async (personaId2, measure) => ({
63675
+ response: { type: "deploy:state", ...await localStateOf(personaId2, measure) }
63676
+ });
63642
63677
  async function scansResult(dir) {
63643
63678
  return { response: { type: "deploy:scans", scans: (await readHistory(dir)).scans } };
63644
63679
  }
@@ -63912,9 +63947,9 @@ function buildDeployHandlers(deps) {
63912
63947
  throw toClawdError(error);
63913
63948
  }
63914
63949
  const live = liveScans.get(personaId2);
63915
- if (live && live.sessionId === void 0) return view(personaId2);
63950
+ if (live && live.sessionId === void 0) return localView(personaId2);
63916
63951
  let file = await readHistory(dir).catch(() => emptyScanFile());
63917
- if (file.scans.some((s2) => s2.status === "scanning" && isLiveScan(live, s2))) return view(personaId2);
63952
+ if (file.scans.some((s2) => s2.status === "scanning" && isLiveScan(live, s2))) return localView(personaId2);
63918
63953
  file = await settleStale(personaId2, dir, file);
63919
63954
  let head;
63920
63955
  try {
@@ -63929,7 +63964,7 @@ function buildDeployHandlers(deps) {
63929
63964
  liveScans.delete(personaId2);
63930
63965
  throw err;
63931
63966
  }
63932
- return view(personaId2);
63967
+ return localView(personaId2);
63933
63968
  };
63934
63969
  const configureTestIdentity = async (api, slug) => {
63935
63970
  await requireIntegrationPublishingConfig(api, slug);
@@ -64168,18 +64203,12 @@ function buildDeployHandlers(deps) {
64168
64203
  const id = await deps.openTestPersona(personaId2, record4.verified, releaseId);
64169
64204
  return { response: { type: "deploy:openTest", personaId: id, expectedImage: record4.verified.image } };
64170
64205
  };
64171
- const getInFlight = /* @__PURE__ */ new Map();
64172
- const coalescedGet = async (frame, client, ctx) => {
64173
- ensureOwner(ctx);
64174
- const args = parseArgs2(DeployGetArgsSchema, frame, "deploy:get");
64175
- const key = JSON.stringify(args);
64176
- const hit = getInFlight.get(key);
64177
- if (hit) return hit;
64206
+ function startTrace(personaId2, event) {
64178
64207
  const started = import_node_perf_hooks.performance.now();
64179
64208
  const traceId = (0, import_node_crypto14.randomUUID)();
64180
- const log = (message, meta) => {
64209
+ const log = (phase, meta) => {
64181
64210
  try {
64182
- deps.logger?.info(message, { personaId: args.personaId, traceId, ...meta });
64211
+ deps.logger?.info(`${event}.${phase}`, { personaId: personaId2, traceId, ...meta });
64183
64212
  } catch {
64184
64213
  }
64185
64214
  };
@@ -64192,7 +64221,7 @@ function buildDeployHandlers(deps) {
64192
64221
  return result;
64193
64222
  } finally {
64194
64223
  const finished = import_node_perf_hooks.performance.now();
64195
- log(stage === "total" ? "deploy.get.finished" : "deploy.get.stage", {
64224
+ log(stage === "total" ? "finished" : "stage", {
64196
64225
  stage,
64197
64226
  status,
64198
64227
  ...details,
@@ -64201,10 +64230,20 @@ function buildDeployHandlers(deps) {
64201
64230
  });
64202
64231
  }
64203
64232
  };
64204
- log("deploy.get.started", { historical: args.releaseHead !== void 0 || args.releaseId !== void 0, ...args.environment ? { environment: args.environment } : {} });
64233
+ return { log, measure, started };
64234
+ }
64235
+ const getInFlight = /* @__PURE__ */ new Map();
64236
+ const coalescedGet = async (frame, client, ctx) => {
64237
+ ensureOwner(ctx);
64238
+ const args = parseArgs2(DeployGetArgsSchema, frame, "deploy:get");
64239
+ const key = JSON.stringify(args);
64240
+ const hit = getInFlight.get(key);
64241
+ if (hit) return hit;
64242
+ const { log, measure, started } = startTrace(args.personaId, "deploy.get");
64243
+ log("started", { historical: args.releaseHead !== void 0 || args.releaseId !== void 0, ...args.environment ? { environment: args.environment } : {} });
64205
64244
  const promise = measure("total", () => enqueue(args.personaId, async () => {
64206
64245
  const durationMs = Math.round((import_node_perf_hooks.performance.now() - started) * 100) / 100;
64207
- log("deploy.get.stage", { stage: "queue", status: "ok", durationMs, elapsedMs: durationMs });
64246
+ log("stage", { stage: "queue", status: "ok", durationMs, elapsedMs: durationMs });
64208
64247
  const { personaId: personaId2, ...selection } = args;
64209
64248
  mustPersona(personaId2);
64210
64249
  return view(personaId2, selection, measure);
@@ -64216,8 +64255,30 @@ function buildDeployHandlers(deps) {
64216
64255
  });
64217
64256
  return promise;
64218
64257
  };
64258
+ const localInFlight = /* @__PURE__ */ new Map();
64259
+ const coalescedLocalGet = async (frame, _client, ctx) => {
64260
+ ensureOwner(ctx);
64261
+ const { personaId: personaId2 } = parseArgs2(DeployPersonaArgsSchema, frame, "deploy:getLocal");
64262
+ const hit = localInFlight.get(personaId2);
64263
+ if (hit) return hit;
64264
+ const { log, measure, started } = startTrace(personaId2, "deploy.getLocal");
64265
+ log("started", {});
64266
+ const promise = measure("total", () => enqueue(personaId2, async () => {
64267
+ const durationMs = Math.round((import_node_perf_hooks.performance.now() - started) * 100) / 100;
64268
+ log("stage", { stage: "queue", status: "ok", durationMs, elapsedMs: durationMs });
64269
+ mustPersona(personaId2);
64270
+ return localView(personaId2, measure);
64271
+ }));
64272
+ localInFlight.set(personaId2, promise);
64273
+ void promise.finally(() => {
64274
+ if (localInFlight.get(personaId2) === promise) localInFlight.delete(personaId2);
64275
+ }).catch(() => {
64276
+ });
64277
+ return promise;
64278
+ };
64219
64279
  return {
64220
64280
  "deploy:get": coalescedGet,
64281
+ "deploy:getLocal": coalescedLocalGet,
64221
64282
  "deploy:confirmTest": serial(confirmTest),
64222
64283
  "deploy:promote": serial(promote),
64223
64284
  "deploy:openTest": serial(openTest),
@@ -74525,6 +74586,7 @@ var METHOD_GRANT_MAP = {
74525
74586
  "visitor:list": ADMIN_ANY,
74526
74587
  // Deployment handlers use owner credentials and can publish resources; exclude guests.
74527
74588
  "deploy:get": ADMIN_ANY,
74589
+ "deploy:getLocal": ADMIN_ANY,
74528
74590
  "deploy:scan": ADMIN_ANY,
74529
74591
  "deploy:patch": ADMIN_ANY,
74530
74592
  "deploy:putSecret": ADMIN_ANY,
@@ -74755,7 +74817,7 @@ function computeMethodAccess(args) {
74755
74817
  }
74756
74818
 
74757
74819
  // src/version.ts
74758
- var version = "0.2.664".length > 0 ? "0.2.664" : "dev";
74820
+ var version = "0.2.665".length > 0 ? "0.2.665" : "dev";
74759
74821
 
74760
74822
  // src/cli-probe/probe.ts
74761
74823
  var fs86 = __toESM(require("fs"), 1);