@kontextmind/kxm 0.7.72 → 0.7.74

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.
@@ -19594,46 +19594,49 @@ var HubClient = class {
19594
19594
  await this.register();
19595
19595
  }
19596
19596
  async request(path4, init = {}, includeIdentity = true) {
19597
- const requestTimeoutMs = this.options.requestTimeoutMs ?? 15e3;
19598
- const timeoutSignal = AbortSignal.timeout(requestTimeoutMs);
19599
- const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
19600
- let response;
19597
+ return await hubJsonRequest(this.options, path4, init, this.headers(includeIdentity));
19598
+ }
19599
+ };
19600
+ async function hubJsonRequest(options, path4, init, headers) {
19601
+ const requestTimeoutMs = options.requestTimeoutMs ?? 15e3;
19602
+ const timeoutSignal = AbortSignal.timeout(requestTimeoutMs);
19603
+ const signal = init.signal ? AbortSignal.any([init.signal, timeoutSignal]) : timeoutSignal;
19604
+ let response;
19605
+ try {
19606
+ response = await (options.fetchImpl ?? fetch)(`${options.serverUrl.replace(/\/$/, "")}${path4}`, {
19607
+ ...init,
19608
+ signal,
19609
+ headers: { ...headers, ...init.headers ?? {} }
19610
+ });
19611
+ } catch (error) {
19612
+ if (timeoutSignal.aborted) throw new Error(`request timed out after ${requestTimeoutMs}ms`);
19613
+ throw error;
19614
+ }
19615
+ const text = await response.text();
19616
+ let body = {};
19617
+ if (text) {
19601
19618
  try {
19602
- response = await (this.options.fetchImpl ?? fetch)(`${this.options.serverUrl.replace(/\/$/, "")}${path4}`, {
19603
- ...init,
19604
- signal,
19605
- headers: { ...this.headers(includeIdentity), ...init.headers ?? {} }
19606
- });
19607
- } catch (error) {
19608
- if (timeoutSignal.aborted) throw new Error(`request timed out after ${requestTimeoutMs}ms`);
19609
- throw error;
19610
- }
19611
- const text = await response.text();
19612
- let body = {};
19613
- if (text) {
19614
- try {
19615
- body = JSON.parse(text);
19616
- } catch {
19617
- throw new Error(`hub returned invalid JSON with HTTP ${response.status}`);
19618
- }
19619
- }
19620
- if (!response.ok) {
19621
- const extras = {};
19622
- for (const key of ["operation", "nextAction", "assignedCoordinatorName"]) {
19623
- if (typeof body[key] === "string") extras[key] = body[key];
19624
- }
19625
- if (body.lease && typeof body.lease === "object") extras.lease = body.lease;
19626
- throw new HubHttpError(
19627
- response.status,
19628
- String(body.error ?? `HTTP ${response.status}`),
19629
- typeof body.code === "string" ? body.code : void 0,
19630
- response.headers.get("x-request-id") ?? void 0,
19631
- Object.keys(extras).length > 0 ? extras : void 0
19632
- );
19619
+ body = JSON.parse(text);
19620
+ } catch {
19621
+ throw new Error(`hub returned invalid JSON with HTTP ${response.status}`);
19633
19622
  }
19634
- return body;
19635
19623
  }
19636
- };
19624
+ if (!response.ok) {
19625
+ const extras = {};
19626
+ for (const key of ["operation", "nextAction", "assignedCoordinatorName"]) {
19627
+ if (typeof body[key] === "string") extras[key] = body[key];
19628
+ }
19629
+ if (body.lease && typeof body.lease === "object") extras.lease = body.lease;
19630
+ throw new HubHttpError(
19631
+ response.status,
19632
+ String(body.error ?? `HTTP ${response.status}`),
19633
+ typeof body.code === "string" ? body.code : void 0,
19634
+ response.headers.get("x-request-id") ?? void 0,
19635
+ Object.keys(extras).length > 0 ? extras : void 0
19636
+ );
19637
+ }
19638
+ return body;
19639
+ }
19637
19640
 
19638
19641
  // plugins/kxm/src/hub-env.ts
19639
19642
  import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync as writeFileSync2 } from "node:fs";
@@ -22167,6 +22170,7 @@ var KxmSchemaRegistry = class {
22167
22170
  driveReceiptValidator;
22168
22171
  coordinatorValidator;
22169
22172
  intakeMessageValidator;
22173
+ syncEventValidator;
22170
22174
  constructor(schemasDir = DEFAULT_SCHEMA_DIR) {
22171
22175
  this.schemasDir = resolve3(schemasDir);
22172
22176
  this.ajv = new import__.Ajv2020({ allErrors: true, strict: true, strictRequired: false });
@@ -22183,6 +22187,7 @@ var KxmSchemaRegistry = class {
22183
22187
  const driveReceiptFile = "drive-receipt.schema.json";
22184
22188
  const coordinatorFile = "coordinator.schema.json";
22185
22189
  const intakeMessageFile = "intake-message.schema.json";
22190
+ const syncEventFile = "sync-event.schema.json";
22186
22191
  this.ajv.addSchema(readJsonObject(join6(this.schemasDir, localBindingsFile)));
22187
22192
  this.ajv.addSchema(readJsonObject(join6(this.schemasDir, templateProvenanceFile)));
22188
22193
  this.ajv.addSchema(readJsonObject(join6(this.schemasDir, initOperationFile)));
@@ -22191,6 +22196,7 @@ var KxmSchemaRegistry = class {
22191
22196
  this.ajv.addSchema(readJsonObject(join6(this.schemasDir, driveReceiptFile)));
22192
22197
  this.ajv.addSchema(readJsonObject(join6(this.schemasDir, coordinatorFile)));
22193
22198
  this.ajv.addSchema(readJsonObject(join6(this.schemasDir, intakeMessageFile)));
22199
+ this.ajv.addSchema(readJsonObject(join6(this.schemasDir, syncEventFile)));
22194
22200
  for (const [kind, definition] of Object.entries(RESOURCE_SCHEMA)) {
22195
22201
  const validator = this.ajv.getSchema(`https://schemas.kxm.dev/${definition.file}`);
22196
22202
  if (!validator) throw new Error(`schema did not compile: ${definition.file}`);
@@ -22204,6 +22210,7 @@ var KxmSchemaRegistry = class {
22204
22210
  const driveReceiptValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${driveReceiptFile}`);
22205
22211
  const coordinatorValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${coordinatorFile}`);
22206
22212
  const intakeMessageValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${intakeMessageFile}`);
22213
+ const syncEventValidator = this.ajv.getSchema(`https://schemas.kxm.dev/${syncEventFile}`);
22207
22214
  if (!localBindingsValidator) throw new Error(`schema did not compile: ${localBindingsFile}`);
22208
22215
  if (!templateProvenanceValidator) throw new Error(`schema did not compile: ${templateProvenanceFile}`);
22209
22216
  if (!initOperationValidator) throw new Error(`schema did not compile: ${initOperationFile}`);
@@ -22212,6 +22219,7 @@ var KxmSchemaRegistry = class {
22212
22219
  if (!driveReceiptValidator) throw new Error(`schema did not compile: ${driveReceiptFile}`);
22213
22220
  if (!coordinatorValidator) throw new Error(`schema did not compile: ${coordinatorFile}`);
22214
22221
  if (!intakeMessageValidator) throw new Error(`schema did not compile: ${intakeMessageFile}`);
22222
+ if (!syncEventValidator) throw new Error(`schema did not compile: ${syncEventFile}`);
22215
22223
  this.localBindingsValidator = localBindingsValidator;
22216
22224
  this.templateProvenanceValidator = templateProvenanceValidator;
22217
22225
  this.initOperationValidator = initOperationValidator;
@@ -22220,6 +22228,7 @@ var KxmSchemaRegistry = class {
22220
22228
  this.driveReceiptValidator = driveReceiptValidator;
22221
22229
  this.coordinatorValidator = coordinatorValidator;
22222
22230
  this.intakeMessageValidator = intakeMessageValidator;
22231
+ this.syncEventValidator = syncEventValidator;
22223
22232
  }
22224
22233
  validate(kind, value, file) {
22225
22234
  const definition = RESOURCE_SCHEMA[kind];
@@ -23258,12 +23267,12 @@ function planKxmInitialization(start = process.cwd(), options = {}) {
23258
23267
 
23259
23268
  // plugins/kxm/src/runtime-supervisor.ts
23260
23269
  import { spawn as spawn2 } from "node:child_process";
23261
- import { createHash as createHash11, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
23262
- import { chmodSync as chmodSync4, existsSync as existsSync12, lstatSync as lstatSync6, mkdirSync as mkdirSync8, readFileSync as readFileSync11, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
23263
- import { dirname as dirname8, isAbsolute as isAbsolute5, join as join12 } from "node:path";
23270
+ import { createHash as createHash12, createHmac, randomBytes as randomBytes2, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
23271
+ import { chmodSync as chmodSync4, existsSync as existsSync13, lstatSync as lstatSync6, mkdirSync as mkdirSync9, readFileSync as readFileSync12, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
23272
+ import { dirname as dirname9, isAbsolute as isAbsolute6, join as join13 } from "node:path";
23264
23273
 
23265
23274
  // plugins/kxm/src/runtime-store.ts
23266
- import { createHash as createHash9, randomUUID as randomUUID4 } from "node:crypto";
23275
+ import { createHash as createHash10, randomUUID as randomUUID4 } from "node:crypto";
23267
23276
  import { existsSync as existsSync9, lstatSync as lstatSync4, mkdirSync as mkdirSync6, readFileSync as readFileSync8, realpathSync as realpathSync3, writeFileSync as writeFileSync6 } from "node:fs";
23268
23277
  import { dirname as dirname7, join as join9, resolve as resolve6 } from "node:path";
23269
23278
 
@@ -23620,8 +23629,88 @@ function writeKxmLocalBindings(projectRoot, projectId, repositories, options = {
23620
23629
  return { file, written: true, record };
23621
23630
  }
23622
23631
 
23632
+ // plugins/kxm/src/sync-transform.ts
23633
+ import { createHash as createHash8 } from "node:crypto";
23634
+
23635
+ // plugins/kxm/src/redact.ts
23636
+ var SECRET_PATTERNS = [
23637
+ /\bsk-[A-Za-z0-9_-]{8,}\b/g,
23638
+ /\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
23639
+ /\bghp_[A-Za-z0-9_]{20,}\b/g,
23640
+ /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
23641
+ /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/gi,
23642
+ /\bBearer\s+[A-Za-z0-9._~+/=-]+\b/gi,
23643
+ /\bya29\.[A-Za-z0-9._~+/-]+=*/g,
23644
+ /\b1\/\/[A-Za-z0-9_-]+/g,
23645
+ /\b1\/[A-Za-z0-9_-]{20,}/g,
23646
+ /("?(?:access_token|refresh_token|id_token|sessionKey|session_key|claude_oauth_token|anthropicApiKey)"?\s*[:=]\s*")[^"]*(")/gi,
23647
+ /\bKXM_[A-Z0-9_]*(TOKEN|SECRET|KEY)[A-Z0-9_]*=\S+/gi,
23648
+ /\b(GITHUB_TOKEN|GH_TOKEN|KXM_AUTH_TOKEN|KXM_WORKFLOW_SIGNAL_SECRET|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|CLAUDE_API_KEY)=\S+/gi,
23649
+ /\b[A-Fa-f0-9]{64}\b/g
23650
+ ];
23651
+ function redactSecrets(value) {
23652
+ let result = value;
23653
+ for (const pattern of SECRET_PATTERNS) {
23654
+ result = result.replace(pattern, "[redacted]");
23655
+ }
23656
+ return result;
23657
+ }
23658
+ function redactStringList(values, maxItems = 32) {
23659
+ return values.slice(0, maxItems).map((value) => redactSecrets(value).slice(0, 500));
23660
+ }
23661
+
23662
+ // plugins/kxm/src/sync-transform.ts
23663
+ var KXM_DEFAULT_SYNC_POLICY = Object.freeze({
23664
+ prompts: "title-only",
23665
+ results: "bounded-summary",
23666
+ evidence: "references",
23667
+ artifacts: "metadata",
23668
+ fileChanges: "paths-only",
23669
+ rawLogs: false,
23670
+ diffs: false,
23671
+ environmentValues: false
23672
+ });
23673
+ var KXM_DEFAULT_SYNC_POLICY_REVISION = `sha256:${createHash8("sha256").update(kxmCanonicalJson(KXM_DEFAULT_SYNC_POLICY), "utf8").digest("hex")}`;
23674
+ var SCALAR_FIELDS = [
23675
+ "workflowId",
23676
+ "promptHash",
23677
+ "status",
23678
+ "previousStatus",
23679
+ "outcome",
23680
+ "stepId",
23681
+ "stepAttempt",
23682
+ "fromStepId",
23683
+ "toStepId",
23684
+ "assignmentId",
23685
+ "attemptId",
23686
+ "agentId",
23687
+ "instanceNo",
23688
+ "scopeEpoch",
23689
+ "resolutionAction"
23690
+ ];
23691
+ var CARRIED_FIELDS = /* @__PURE__ */ new Set([
23692
+ ...SCALAR_FIELDS,
23693
+ "displayTitle",
23694
+ "summary",
23695
+ "reason",
23696
+ "executor",
23697
+ "model",
23698
+ "timing",
23699
+ "usage",
23700
+ "evidenceRefs",
23701
+ "artifacts",
23702
+ "receipt",
23703
+ "error",
23704
+ "effect",
23705
+ "lease",
23706
+ "actor",
23707
+ "resolvedBy",
23708
+ "suppliedRefs",
23709
+ "counts"
23710
+ ]);
23711
+
23623
23712
  // plugins/kxm/src/database.ts
23624
- import { createHash as createHash8, randomBytes } from "node:crypto";
23713
+ import { createHash as createHash9, randomBytes } from "node:crypto";
23625
23714
  import {
23626
23715
  chmodSync as chmodSync3,
23627
23716
  copyFileSync,
@@ -23774,7 +23863,7 @@ function checkIntegrity(database) {
23774
23863
  }
23775
23864
  function fileSha256(filePath) {
23776
23865
  const bytes = readFileSync7(filePath);
23777
- return `sha256:${createHash8("sha256").update(bytes).digest("hex")}`;
23866
+ return `sha256:${createHash9("sha256").update(bytes).digest("hex")}`;
23778
23867
  }
23779
23868
  function backupDatabaseFile(sourcePath, targetPath, storeId) {
23780
23869
  const resolvedSource = resolve5(sourcePath);
@@ -23896,7 +23985,7 @@ function discoverProjectStores(projectRoot, options = {}) {
23896
23985
  const stores = [];
23897
23986
  const hubPath = options.hubDataPath ? resolve5(options.hubDataPath) : join8(root, ".kxm", "state", "kxm.db");
23898
23987
  if (existsSync8(hubPath)) {
23899
- stores.push({ storeId: "hub-store", sourcePath: hubPath, maxSupportedVersion: 4 });
23988
+ stores.push({ storeId: "hub-store", sourcePath: hubPath, maxSupportedVersion: 5 });
23900
23989
  }
23901
23990
  const registryPath = join8(root, ".kxm", "runtime", "registry.db");
23902
23991
  if (existsSync8(registryPath)) {
@@ -23915,7 +24004,7 @@ function discoverProjectStores(projectRoot, options = {}) {
23915
24004
  stores.push({
23916
24005
  storeId: `events:${key}`,
23917
24006
  sourcePath: join8(eventsDir, entry.name),
23918
- maxSupportedVersion: 4
24007
+ maxSupportedVersion: 6
23919
24008
  });
23920
24009
  }
23921
24010
  }
@@ -23958,7 +24047,7 @@ function createBackup(options = {}) {
23958
24047
  stores: backedUpStores
23959
24048
  };
23960
24049
  const manifestJson = JSON.stringify(manifest, null, 2) + "\n";
23961
- const manifestSha256 = `sha256:${createHash8("sha256").update(manifestJson, "utf8").digest("hex")}`;
24050
+ const manifestSha256 = `sha256:${createHash9("sha256").update(manifestJson, "utf8").digest("hex")}`;
23962
24051
  manifest.manifestSha256 = manifestSha256;
23963
24052
  const finalJson = JSON.stringify(manifest, null, 2) + "\n";
23964
24053
  const manifestPath = join8(outDir, "manifest.json");
@@ -24002,11 +24091,11 @@ function restoreBackup(manifestPathOrDir, options = {}) {
24002
24091
  `backup file ${store.backupFile} sha256 ${actualSha256} does not match manifest hash ${store.sha256}`
24003
24092
  );
24004
24093
  }
24005
- let maxSupported = 4;
24094
+ let maxSupported = 5;
24006
24095
  if (store.storeId === "registry" || store.storeId === "binding-store") {
24007
24096
  maxSupported = 1;
24008
24097
  } else if (store.storeId.startsWith("events:")) {
24009
- maxSupported = 5;
24098
+ maxSupported = 6;
24010
24099
  }
24011
24100
  let targetPath = store.sourcePath;
24012
24101
  if (options.projectRoot && manifest.projectRoot && targetPath.startsWith(manifest.projectRoot)) {
@@ -24054,7 +24143,7 @@ function projectRuntimeKey(projectRoot) {
24054
24143
  canonical2 = resolve6(projectRoot);
24055
24144
  }
24056
24145
  const folded = process.platform === "win32" ? canonical2.toLocaleLowerCase("en-US") : canonical2;
24057
- return createHash9("sha256").update(folded, "utf8").digest("hex").slice(0, 24);
24146
+ return createHash10("sha256").update(folded, "utf8").digest("hex").slice(0, 24);
24058
24147
  }
24059
24148
  var KXM_REGISTRY_SCHEMA_VERSION = 1;
24060
24149
  var REGISTRY_TABLES = {
@@ -24174,6 +24263,15 @@ var KxmRuntimeRegistry = class {
24174
24263
  return this.readSupervisorRow();
24175
24264
  }
24176
24265
  /** Register or revalidate a project's home binding. Home Runtime is immutable. */
24266
+ /** All projects registered to this Runtime, for restart recovery: the
24267
+ * supervisor needs to reopen their contexts so pending outbox rows resume
24268
+ * syncing and presence keeps beating. */
24269
+ projectsForRuntime(homeRuntimeId) {
24270
+ const rows = this.database.prepare(
24271
+ "SELECT project_root, project_id FROM projects WHERE home_runtime_id = ? ORDER BY registered_at"
24272
+ ).all(homeRuntimeId);
24273
+ return rows.map((row) => ({ projectRoot: row.project_root, projectId: row.project_id }));
24274
+ }
24177
24275
  registerProject(registration) {
24178
24276
  const projectRoot = resolve6(registration.projectRoot);
24179
24277
  const projectKey = projectRuntimeKey(projectRoot);
@@ -24350,7 +24448,8 @@ var EVENT_STORE_TABLES = {
24350
24448
  "schema",
24351
24449
  "record"
24352
24450
  ],
24353
- project_controls: ["project_id", "paused", "reason", "updated_at", "actor", "schema", "record"]
24451
+ project_controls: ["project_id", "paused", "reason", "updated_at", "actor", "schema", "record"],
24452
+ outbox: ["seq", "run_id", "sequence", "sync_event", "attempted_at", "acked_at"]
24354
24453
  };
24355
24454
  var KXM_EVENT_STORE_TABLE_NAMES = Object.keys(EVENT_STORE_TABLES).sort();
24356
24455
 
@@ -24867,7 +24966,7 @@ var RECORD_LIMIT = 16 * 1024 * 1024;
24867
24966
 
24868
24967
  // plugins/kxm/src/prices.ts
24869
24968
  var import_yaml3 = __toESM(require_dist(), 1);
24870
- import { createHash as createHash10 } from "node:crypto";
24969
+ import { createHash as createHash11 } from "node:crypto";
24871
24970
  import { existsSync as existsSync10, readFileSync as readFileSync9, statSync } from "node:fs";
24872
24971
  import { join as join10 } from "node:path";
24873
24972
 
@@ -24930,7 +25029,7 @@ function hashPriceCatalog(catalog) {
24930
25029
  }))
24931
25030
  })).sort((a, b2) => a.id.localeCompare(b2.id))
24932
25031
  };
24933
- return createHash10("sha256").update(JSON.stringify(canonical2), "utf8").digest("hex");
25032
+ return createHash11("sha256").update(JSON.stringify(canonical2), "utf8").digest("hex");
24934
25033
  }
24935
25034
  function parsePriceCatalog(text) {
24936
25035
  const parsed = (0, import_yaml3.parse)(text);
@@ -25736,9 +25835,144 @@ function formatRoutingReport(report2, options = {}) {
25736
25835
  return lines.join("\n");
25737
25836
  }
25738
25837
 
25838
+ // plugins/kxm/src/hub-binding.ts
25839
+ import { existsSync as existsSync12, mkdirSync as mkdirSync8, readFileSync as readFileSync11, renameSync as renameSync3, rmSync as rmSync3, writeFileSync as writeFileSync8 } from "node:fs";
25840
+ import { homedir as homedir4 } from "node:os";
25841
+ import { dirname as dirname8, isAbsolute as isAbsolute5, join as join12, resolve as resolve8 } from "node:path";
25842
+ var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
25843
+ var HUB_HEALTH_PROBE_MS = 300;
25844
+ var HubBindingError = class extends Error {
25845
+ constructor(message) {
25846
+ super(message);
25847
+ this.name = "HubBindingError";
25848
+ }
25849
+ };
25850
+ function resolveUserStateRoot2(env) {
25851
+ const explicit = env.KXM_STATE_HOME?.trim();
25852
+ if (explicit) {
25853
+ if (!isAbsolute5(explicit)) throw new HubBindingError("local_state_root_not_absolute");
25854
+ return resolve8(explicit);
25855
+ }
25856
+ if (process.platform === "win32") {
25857
+ const localAppData = env.LOCALAPPDATA?.trim();
25858
+ const base2 = localAppData && isAbsolute5(localAppData) ? localAppData : join12(homedir4(), "AppData", "Local");
25859
+ return resolve8(base2, "KXM");
25860
+ }
25861
+ if (process.platform === "darwin") return resolve8(homedir4(), "Library", "Application Support", "KXM");
25862
+ const xdgState = env.XDG_STATE_HOME?.trim();
25863
+ const base = xdgState && isAbsolute5(xdgState) ? xdgState : join12(homedir4(), ".local", "state");
25864
+ return resolve8(base, "kxm");
25865
+ }
25866
+ function hubBindingFile(env = process.env) {
25867
+ return join12(resolveUserStateRoot2(env), "hub-binding.json");
25868
+ }
25869
+ function validateHubUrl(raw) {
25870
+ let parsed;
25871
+ try {
25872
+ parsed = new URL(raw);
25873
+ } catch {
25874
+ throw new HubBindingError("hub_url_invalid");
25875
+ }
25876
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "" || parsed.search !== "" || parsed.hash !== "" || raw.includes("?") || raw.includes("#")) {
25877
+ throw new HubBindingError("hub_url_invalid");
25878
+ }
25879
+ return parsed.href.replace(/\/$/, "");
25880
+ }
25881
+ function hubBindingScope(url) {
25882
+ let host;
25883
+ try {
25884
+ host = new URL(url).hostname.toLowerCase();
25885
+ } catch {
25886
+ return "remote";
25887
+ }
25888
+ if (host === "localhost" || host === "::1" || host === "[::1]" || host.endsWith(".localhost")) return "loopback";
25889
+ const v4 = /^127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/.exec(host);
25890
+ return v4 && [v4[1], v4[2], v4[3]].every((part) => Number(part) <= 255) ? "loopback" : "remote";
25891
+ }
25892
+ function isIsoTimestamp(value) {
25893
+ if (Number.isNaN(Date.parse(value))) return false;
25894
+ return value === new Date(value).toISOString();
25895
+ }
25896
+ function isAbortError(error) {
25897
+ return Boolean(
25898
+ error && typeof error === "object" && ("name" in error && error.name === "AbortError" || "code" in error && error.code === "ABORT_ERR")
25899
+ );
25900
+ }
25901
+ function readHubBinding(env = process.env) {
25902
+ const file = hubBindingFile(env);
25903
+ if (!existsSync12(file)) return void 0;
25904
+ let parsed;
25905
+ try {
25906
+ parsed = JSON.parse(readFileSync11(file, "utf8"));
25907
+ } catch {
25908
+ throw new HubBindingError(`malformed hub binding at ${file}`);
25909
+ }
25910
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
25911
+ throw new HubBindingError(`malformed hub binding at ${file}`);
25912
+ }
25913
+ const row = parsed;
25914
+ const keys = Object.keys(row);
25915
+ if (keys.length !== 3 || row.schema !== HUB_BINDING_SCHEMA || typeof row.url !== "string" || typeof row.boundAt !== "string" || !isIsoTimestamp(row.boundAt)) {
25916
+ throw new HubBindingError(`malformed hub binding at ${file}`);
25917
+ }
25918
+ let url;
25919
+ try {
25920
+ url = validateHubUrl(row.url);
25921
+ } catch {
25922
+ throw new HubBindingError(`malformed hub binding at ${file}`);
25923
+ }
25924
+ return { schema: HUB_BINDING_SCHEMA, url, boundAt: row.boundAt };
25925
+ }
25926
+ function writeHubBinding(record, env = process.env) {
25927
+ const file = hubBindingFile(env);
25928
+ mkdirSync8(dirname8(file), { recursive: true, mode: 448 });
25929
+ const temporary = join12(dirname8(file), `.hub-binding-${process.pid}.tmp`);
25930
+ try {
25931
+ writeFileSync8(temporary, `${JSON.stringify(record, null, 2)}
25932
+ `, { encoding: "utf8", mode: 384 });
25933
+ renameSync3(temporary, file);
25934
+ } finally {
25935
+ rmSync3(temporary, { force: true });
25936
+ }
25937
+ return file;
25938
+ }
25939
+ function removeHubBinding(env = process.env) {
25940
+ const file = hubBindingFile(env);
25941
+ try {
25942
+ rmSync3(file);
25943
+ return true;
25944
+ } catch (error) {
25945
+ if (error.code === "ENOENT") return false;
25946
+ throw error;
25947
+ }
25948
+ }
25949
+ async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
25950
+ const started = Date.now();
25951
+ const controller = new AbortController();
25952
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
25953
+ try {
25954
+ const response = await fetchImpl(`${url}/health`, { signal: controller.signal });
25955
+ if (!response.ok) return { health: "unknown", probeMs: Date.now() - started };
25956
+ let body;
25957
+ try {
25958
+ body = await response.json();
25959
+ } catch {
25960
+ return { health: "unknown", probeMs: Date.now() - started };
25961
+ }
25962
+ if (body && typeof body === "object" && body.ok === true) {
25963
+ return { health: "on", probeMs: Date.now() - started };
25964
+ }
25965
+ return { health: "unknown", probeMs: Date.now() - started };
25966
+ } catch (error) {
25967
+ return { health: isAbortError(error) ? "unknown" : "off", probeMs: Date.now() - started };
25968
+ } finally {
25969
+ clearTimeout(timer);
25970
+ }
25971
+ }
25972
+
25739
25973
  // plugins/kxm/src/runtime-supervisor.ts
25740
25974
  function kxmSupervisorTokenFile(paths) {
25741
- return join12(paths.runtimeDir, "supervisor.token");
25975
+ return join13(paths.runtimeDir, "supervisor.token");
25742
25976
  }
25743
25977
  function readKxmSupervisorToken(paths) {
25744
25978
  const file = kxmSupervisorTokenFile(paths);
@@ -25747,7 +25981,7 @@ function readKxmSupervisorToken(paths) {
25747
25981
  if (stat.isSymbolicLink() || !stat.isFile()) {
25748
25982
  throw runtimeError("runtime_path_invalid", file, "supervisor token file must be a regular file, not a link");
25749
25983
  }
25750
- const token = readFileSync11(file, "utf8").trim();
25984
+ const token = readFileSync12(file, "utf8").trim();
25751
25985
  return token.length >= 32 ? token : void 0;
25752
25986
  }
25753
25987
  function processAlive(pid) {
@@ -25761,11 +25995,11 @@ function processAlive(pid) {
25761
25995
  var HEARTBEAT_STALE_MS = 15e3;
25762
25996
  var SUPERVISOR_ERROR_MAX_AGE_MS = 3e4;
25763
25997
  function supervisorErrorFile(paths) {
25764
- return join12(paths.runtimeDir, "supervisor.error");
25998
+ return join13(paths.runtimeDir, "supervisor.error");
25765
25999
  }
25766
26000
  function clearSupervisorError(paths) {
25767
26001
  const file = supervisorErrorFile(paths);
25768
- if (existsSync12(file)) rmSync3(file, { force: true });
26002
+ if (existsSync13(file)) rmSync4(file, { force: true });
25769
26003
  }
25770
26004
  function readRecentSupervisorError(paths) {
25771
26005
  const file = supervisorErrorFile(paths);
@@ -25774,13 +26008,13 @@ function readRecentSupervisorError(paths) {
25774
26008
  const ageMs = Date.now() - stat.mtimeMs;
25775
26009
  if (ageMs > SUPERVISOR_ERROR_MAX_AGE_MS) return void 0;
25776
26010
  try {
25777
- return readFileSync11(file, "utf8").trim();
26011
+ return readFileSync12(file, "utf8").trim();
25778
26012
  } catch {
25779
26013
  return void 0;
25780
26014
  }
25781
26015
  }
25782
26016
  function kxmSupervisorStatus(paths) {
25783
- if (!existsSync12(paths.registryDb)) return { running: false };
26017
+ if (!existsSync13(paths.registryDb)) return { running: false };
25784
26018
  const registry = new KxmRuntimeRegistry(paths.registryDb);
25785
26019
  try {
25786
26020
  const record = registry.supervisor();
@@ -25850,7 +26084,7 @@ async function ensureKxmSupervisor(options = {}) {
25850
26084
  throw runtimeError("runtime_supervisor_unreachable", paths.registryDb, `runtime supervisor pid ${status.pid} is registered as running but cannot be probed`);
25851
26085
  }
25852
26086
  clearSupervisorError(paths);
25853
- const scriptPath = join12(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
26087
+ const scriptPath = join13(findKxmRepoRoot(import.meta.url), "scripts", "kxm-runtime-supervisor.mjs");
25854
26088
  const spawnImpl = options.spawnImpl ?? ((script, env) => {
25855
26089
  const child = spawn2(process.execPath, [script], {
25856
26090
  detached: true,
@@ -25905,36 +26139,9 @@ async function kxmRuntimeRequest(handle, method, path4, body) {
25905
26139
  import { spawn as spawn3 } from "node:child_process";
25906
26140
  import { join as join15, resolve as resolve9 } from "node:path";
25907
26141
 
25908
- // plugins/kxm/src/redact.ts
25909
- var SECRET_PATTERNS = [
25910
- /\bsk-[A-Za-z0-9_-]{8,}\b/g,
25911
- /\bsk-ant-[A-Za-z0-9_-]{8,}\b/g,
25912
- /\bghp_[A-Za-z0-9_]{20,}\b/g,
25913
- /\bgithub_pat_[A-Za-z0-9_]{20,}\b/g,
25914
- /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/gi,
25915
- /\bBearer\s+[A-Za-z0-9._~+/=-]+\b/gi,
25916
- /\bya29\.[A-Za-z0-9._~+/-]+=*/g,
25917
- /\b1\/\/[A-Za-z0-9_-]+/g,
25918
- /\b1\/[A-Za-z0-9_-]{20,}/g,
25919
- /("?(?:access_token|refresh_token|id_token|sessionKey|session_key|claude_oauth_token|anthropicApiKey)"?\s*[:=]\s*")[^"]*(")/gi,
25920
- /\bKXM_[A-Z0-9_]*(TOKEN|SECRET|KEY)[A-Z0-9_]*=\S+/gi,
25921
- /\b(GITHUB_TOKEN|GH_TOKEN|KXM_AUTH_TOKEN|KXM_WORKFLOW_SIGNAL_SECRET|ANTHROPIC_API_KEY|ANTHROPIC_AUTH_TOKEN|CLAUDE_API_KEY)=\S+/gi,
25922
- /\b[A-Fa-f0-9]{64}\b/g
25923
- ];
25924
- function redactSecrets(value) {
25925
- let result = value;
25926
- for (const pattern of SECRET_PATTERNS) {
25927
- result = result.replace(pattern, "[redacted]");
25928
- }
25929
- return result;
25930
- }
25931
- function redactStringList(values, maxItems = 32) {
25932
- return values.slice(0, maxItems).map((value) => redactSecrets(value).slice(0, 500));
25933
- }
25934
-
25935
26142
  // plugins/kxm/src/telemetry.ts
25936
- import { appendFileSync, mkdirSync as mkdirSync9, readFileSync as readFileSync12 } from "node:fs";
25937
- import { dirname as dirname9, join as join13 } from "node:path";
26143
+ import { appendFileSync, mkdirSync as mkdirSync10, readFileSync as readFileSync13 } from "node:fs";
26144
+ import { dirname as dirname10, join as join14 } from "node:path";
25938
26145
  var TELEMETRY_SCHEMA = "kxm.telemetry.v1";
25939
26146
  function inferImprovementTarget(input) {
25940
26147
  const explicit = input.env?.KXM_IMPROVE_TARGET?.trim();
@@ -25944,12 +26151,12 @@ function inferImprovementTarget(input) {
25944
26151
  return project || workflowId ? "project" : "cli";
25945
26152
  }
25946
26153
  function appendTelemetry(path4, event) {
25947
- mkdirSync9(dirname9(path4), { recursive: true });
26154
+ mkdirSync10(dirname10(path4), { recursive: true });
25948
26155
  appendFileSync(path4, `${JSON.stringify(event)}
25949
26156
  `, { encoding: "utf8", mode: 384 });
25950
26157
  }
25951
26158
  function telemetryPath(logsDir) {
25952
- return join13(logsDir, "telemetry.jsonl");
26159
+ return join14(logsDir, "telemetry.jsonl");
25953
26160
  }
25954
26161
  function makeTelemetryEvent(input) {
25955
26162
  return {
@@ -25964,7 +26171,7 @@ function makeTelemetryEvent(input) {
25964
26171
  function readRoutingRecords(path4) {
25965
26172
  const records = [];
25966
26173
  try {
25967
- const raw = readFileSync12(path4, "utf8");
26174
+ const raw = readFileSync13(path4, "utf8");
25968
26175
  for (const line of raw.split(/\r?\n/)) {
25969
26176
  if (!line.trim()) continue;
25970
26177
  try {
@@ -26040,141 +26247,6 @@ function workerResult(worker, payload) {
26040
26247
  };
26041
26248
  }
26042
26249
 
26043
- // plugins/kxm/src/hub-binding.ts
26044
- import { existsSync as existsSync13, mkdirSync as mkdirSync10, readFileSync as readFileSync13, renameSync as renameSync4, rmSync as rmSync4, writeFileSync as writeFileSync9 } from "node:fs";
26045
- import { homedir as homedir4 } from "node:os";
26046
- import { dirname as dirname10, isAbsolute as isAbsolute6, join as join14, resolve as resolve8 } from "node:path";
26047
- var HUB_BINDING_SCHEMA = "kxm.hub-binding.v1";
26048
- var HUB_HEALTH_PROBE_MS = 300;
26049
- var HubBindingError = class extends Error {
26050
- constructor(message) {
26051
- super(message);
26052
- this.name = "HubBindingError";
26053
- }
26054
- };
26055
- function resolveUserStateRoot2(env) {
26056
- const explicit = env.KXM_STATE_HOME?.trim();
26057
- if (explicit) {
26058
- if (!isAbsolute6(explicit)) throw new HubBindingError("local_state_root_not_absolute");
26059
- return resolve8(explicit);
26060
- }
26061
- if (process.platform === "win32") {
26062
- const localAppData = env.LOCALAPPDATA?.trim();
26063
- const base2 = localAppData && isAbsolute6(localAppData) ? localAppData : join14(homedir4(), "AppData", "Local");
26064
- return resolve8(base2, "KXM");
26065
- }
26066
- if (process.platform === "darwin") return resolve8(homedir4(), "Library", "Application Support", "KXM");
26067
- const xdgState = env.XDG_STATE_HOME?.trim();
26068
- const base = xdgState && isAbsolute6(xdgState) ? xdgState : join14(homedir4(), ".local", "state");
26069
- return resolve8(base, "kxm");
26070
- }
26071
- function hubBindingFile(env = process.env) {
26072
- return join14(resolveUserStateRoot2(env), "hub-binding.json");
26073
- }
26074
- function validateHubUrl(raw) {
26075
- let parsed;
26076
- try {
26077
- parsed = new URL(raw);
26078
- } catch {
26079
- throw new HubBindingError("hub_url_invalid");
26080
- }
26081
- if (parsed.protocol !== "http:" && parsed.protocol !== "https:" || parsed.username !== "" || parsed.password !== "" || parsed.search !== "" || parsed.hash !== "" || raw.includes("?") || raw.includes("#")) {
26082
- throw new HubBindingError("hub_url_invalid");
26083
- }
26084
- return parsed.href.replace(/\/$/, "");
26085
- }
26086
- function hubBindingScope(url) {
26087
- let host;
26088
- try {
26089
- host = new URL(url).hostname.toLowerCase();
26090
- } catch {
26091
- return "remote";
26092
- }
26093
- if (host === "localhost" || host === "::1" || host === "[::1]" || host.endsWith(".localhost")) return "loopback";
26094
- const v4 = /^127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/.exec(host);
26095
- return v4 && [v4[1], v4[2], v4[3]].every((part) => Number(part) <= 255) ? "loopback" : "remote";
26096
- }
26097
- function isIsoTimestamp(value) {
26098
- if (Number.isNaN(Date.parse(value))) return false;
26099
- return value === new Date(value).toISOString();
26100
- }
26101
- function isAbortError(error) {
26102
- return Boolean(
26103
- error && typeof error === "object" && ("name" in error && error.name === "AbortError" || "code" in error && error.code === "ABORT_ERR")
26104
- );
26105
- }
26106
- function readHubBinding(env = process.env) {
26107
- const file = hubBindingFile(env);
26108
- if (!existsSync13(file)) return void 0;
26109
- let parsed;
26110
- try {
26111
- parsed = JSON.parse(readFileSync13(file, "utf8"));
26112
- } catch {
26113
- throw new HubBindingError(`malformed hub binding at ${file}`);
26114
- }
26115
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
26116
- throw new HubBindingError(`malformed hub binding at ${file}`);
26117
- }
26118
- const row = parsed;
26119
- const keys = Object.keys(row);
26120
- if (keys.length !== 3 || row.schema !== HUB_BINDING_SCHEMA || typeof row.url !== "string" || typeof row.boundAt !== "string" || !isIsoTimestamp(row.boundAt)) {
26121
- throw new HubBindingError(`malformed hub binding at ${file}`);
26122
- }
26123
- let url;
26124
- try {
26125
- url = validateHubUrl(row.url);
26126
- } catch {
26127
- throw new HubBindingError(`malformed hub binding at ${file}`);
26128
- }
26129
- return { schema: HUB_BINDING_SCHEMA, url, boundAt: row.boundAt };
26130
- }
26131
- function writeHubBinding(record, env = process.env) {
26132
- const file = hubBindingFile(env);
26133
- mkdirSync10(dirname10(file), { recursive: true, mode: 448 });
26134
- const temporary = join14(dirname10(file), `.hub-binding-${process.pid}.tmp`);
26135
- try {
26136
- writeFileSync9(temporary, `${JSON.stringify(record, null, 2)}
26137
- `, { encoding: "utf8", mode: 384 });
26138
- renameSync4(temporary, file);
26139
- } finally {
26140
- rmSync4(temporary, { force: true });
26141
- }
26142
- return file;
26143
- }
26144
- function removeHubBinding(env = process.env) {
26145
- const file = hubBindingFile(env);
26146
- try {
26147
- rmSync4(file);
26148
- return true;
26149
- } catch (error) {
26150
- if (error.code === "ENOENT") return false;
26151
- throw error;
26152
- }
26153
- }
26154
- async function probeHubHealth(url, fetchImpl, timeoutMs = HUB_HEALTH_PROBE_MS) {
26155
- const started = Date.now();
26156
- const controller = new AbortController();
26157
- const timer = setTimeout(() => controller.abort(), timeoutMs);
26158
- try {
26159
- const response = await fetchImpl(`${url}/health`, { signal: controller.signal });
26160
- if (!response.ok) return { health: "unknown", probeMs: Date.now() - started };
26161
- let body;
26162
- try {
26163
- body = await response.json();
26164
- } catch {
26165
- return { health: "unknown", probeMs: Date.now() - started };
26166
- }
26167
- if (body && typeof body === "object" && body.ok === true) {
26168
- return { health: "on", probeMs: Date.now() - started };
26169
- }
26170
- return { health: "unknown", probeMs: Date.now() - started };
26171
- } catch (error) {
26172
- return { health: isAbortError(error) ? "unknown" : "off", probeMs: Date.now() - started };
26173
- } finally {
26174
- clearTimeout(timer);
26175
- }
26176
- }
26177
-
26178
26250
  // plugins/kxm/src/cli/types.ts
26179
26251
  function spawnScript(scriptName, extraEnv = {}) {
26180
26252
  return new Promise((resolveExit) => {
@@ -29956,7 +30028,7 @@ import { dirname as dirname15, isAbsolute as isAbsolute7, join as join24, relati
29956
30028
 
29957
30029
  // plugins/kxm/src/permission.ts
29958
30030
  import { spawnSync as spawnSync4 } from "node:child_process";
29959
- import { createHash as createHash12 } from "node:crypto";
30031
+ import { createHash as createHash13 } from "node:crypto";
29960
30032
  import { existsSync as existsSync20, mkdtempSync, mkdirSync as mkdirSync17, readFileSync as readFileSync20, rmSync as rmSync7, writeFileSync as writeFileSync16 } from "node:fs";
29961
30033
  import { tmpdir } from "node:os";
29962
30034
  import { dirname as dirname14, join as join23, resolve as resolve17, sep as sep3 } from "node:path";
@@ -30162,7 +30234,7 @@ function kxmProseEntries(resource) {
30162
30234
  return entries;
30163
30235
  }
30164
30236
  function valueHash(canonicalValue) {
30165
- return `sha256:${createHash12("sha256").update(canonicalValue, "utf8").digest("hex")}`;
30237
+ return `sha256:${createHash13("sha256").update(canonicalValue, "utf8").digest("hex")}`;
30166
30238
  }
30167
30239
  function rankDirection(rank, baseValue, candidateValue) {
30168
30240
  const base = JSON.parse(baseValue);
@@ -30482,7 +30554,7 @@ function loadKxmProjectAtRevision(root, revision, options = {}) {
30482
30554
  const paths = listing.split("\0").filter((line) => line.length > 0 && (line.startsWith(".kxm/") || line.includes("/.kxm/")));
30483
30555
  const shadow = mkdtempSync(join23(tmpdir(), "kxm-permission-base-"));
30484
30556
  const shadowResolved = resolve17(shadow);
30485
- const shadowMembersDir = `.kxm-shadow-members-${createHash12("sha256").update(shadowResolved, "utf8").digest("hex").slice(0, 8)}`;
30557
+ const shadowMembersDir = `.kxm-shadow-members-${createHash13("sha256").update(shadowResolved, "utf8").digest("hex").slice(0, 8)}`;
30486
30558
  try {
30487
30559
  for (const path4 of paths) {
30488
30560
  const segments = path4.split("/");
@@ -33379,7 +33451,7 @@ remains Grok.
33379
33451
 
33380
33452
  // plugins/kxm/src/skills.ts
33381
33453
  var import_yaml14 = __toESM(require_dist(), 1);
33382
- import { createHash as createHash13 } from "node:crypto";
33454
+ import { createHash as createHash14 } from "node:crypto";
33383
33455
  import { existsSync as existsSync25, mkdirSync as mkdirSync20, readdirSync as readdirSync10, readFileSync as readFileSync24, renameSync as renameSync7, rmSync as rmSync9, statSync as statSync3, writeFileSync as writeFileSync19 } from "node:fs";
33384
33456
  import { join as join29 } from "node:path";
33385
33457
  var SKILL_CANDIDATE_SCHEMA = "kxm.skill-candidate.v1";
@@ -33404,7 +33476,7 @@ var SkillLifecycleError = class extends Error {
33404
33476
  }
33405
33477
  };
33406
33478
  function skillContentSha256(content) {
33407
- return createHash13("sha256").update(content, "utf8").digest("hex");
33479
+ return createHash14("sha256").update(content, "utf8").digest("hex");
33408
33480
  }
33409
33481
  function skillIdFor(name, contentSha256) {
33410
33482
  const slug = name.toLowerCase().replaceAll(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 40);
@@ -45044,14 +45116,14 @@ async function cmdSessionStart(runtime, options) {
45044
45116
 
45045
45117
  // plugins/kxm/src/cli/system.ts
45046
45118
  import { spawnSync as spawnSync8 } from "node:child_process";
45047
- import { createHash as createHash15 } from "node:crypto";
45119
+ import { createHash as createHash16 } from "node:crypto";
45048
45120
  import { existsSync as existsSync37, mkdtempSync as mkdtempSync2, readFileSync as readFileSync36, rmSync as rmSync12 } from "node:fs";
45049
45121
  import { tmpdir as tmpdir2 } from "node:os";
45050
45122
  import { join as join47, resolve as resolve28 } from "node:path";
45051
45123
  import { createInterface as createInterface3 } from "node:readline";
45052
45124
 
45053
45125
  // plugins/kxm/src/improve.ts
45054
- import { createHash as createHash14 } from "node:crypto";
45126
+ import { createHash as createHash15 } from "node:crypto";
45055
45127
  import { existsSync as existsSync32, mkdirSync as mkdirSync26, writeFileSync as writeFileSync24 } from "node:fs";
45056
45128
  import { join as join42, relative as relative6, resolve as resolve25 } from "node:path";
45057
45129
  var CANDIDATE_SCHEMA = "kxm.candidate.v1";
@@ -45199,7 +45271,7 @@ function groupRoutingRecords(records, options = {}) {
45199
45271
  const isCandidate = recurrence >= minRecurrence && verifyPassRate >= minPassRate;
45200
45272
  const candidateKind = isCandidate ? classifyCandidateKind(group.stepId, group.agentRole) : void 0;
45201
45273
  const safeSlug = group.stepId.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 16) || "step";
45202
- const keyHash = createHash14("sha256").update(`${group.workflowHash}:${group.stepId}:${group.agentRole}:${group.promptHash}`).digest("hex").slice(0, 10);
45274
+ const keyHash = createHash15("sha256").update(`${group.workflowHash}:${group.stepId}:${group.agentRole}:${group.promptHash}`).digest("hex").slice(0, 10);
45203
45275
  const candidateId = isCandidate && candidateKind ? `cand_${candidateKind.replace(/-/g, "_")}_${safeSlug}_${keyHash}` : void 0;
45204
45276
  rows.push({
45205
45277
  workflowHash: group.workflowHash,
@@ -46874,7 +46946,7 @@ function applyKxmPackageUpdate(runtime, notice) {
46874
46946
  for (const step of planned) {
46875
46947
  if (step.kind === "verify") {
46876
46948
  if (!verifyReleaseAssetDigest(step.path, step.sha256)) {
46877
- const actual = existsSync37(step.path) ? createHash15("sha256").update(readFileSync36(step.path)).digest("hex") : "missing";
46949
+ const actual = existsSync37(step.path) ? createHash16("sha256").update(readFileSync36(step.path)).digest("hex") : "missing";
46878
46950
  return {
46879
46951
  ok: false,
46880
46952
  error: "release_digest_mismatch",