heyspex 0.2.2 → 0.2.3

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.
Files changed (70) hide show
  1. package/README.md +10 -0
  2. package/bin/hs-vault-binding.mjs +157 -0
  3. package/bin/hs.mjs +81 -77
  4. package/bin/spexcode.mjs +91 -0
  5. package/dev-factory/engine/worktree.mjs +36 -7
  6. package/dev-factory/lib/epic-detect.mjs +2 -2
  7. package/dev-factory/lib/fleet-readiness.mjs +3 -5
  8. package/dev-factory/lib/fleet-state.mjs +2 -2
  9. package/dev-factory/lib/sufficiency-score.mjs +3 -5
  10. package/dist/cli/hs-check.mjs +76 -46
  11. package/dist/cli/hs-claim.mjs +63 -33
  12. package/dist/cli/hs-connect.mjs +520 -214
  13. package/dist/cli/hs-defer.mjs +161 -19
  14. package/dist/cli/hs-dev.mjs +11 -5
  15. package/dist/cli/hs-env.mjs +187 -161
  16. package/dist/cli/hs-index-rebuild.mjs +123 -78
  17. package/dist/cli/hs-index-reconcile.mjs +203 -107
  18. package/dist/cli/hs-init.mjs +426 -179
  19. package/dist/cli/hs-install.mjs +759 -437
  20. package/dist/cli/hs-join.mjs +590 -383
  21. package/dist/cli/hs-vault-pull.mjs +359 -254
  22. package/dist/cli/hs-vault-push.mjs +151 -113
  23. package/dist/cli/hs-vault.mjs +271 -104
  24. package/dist/cli/hs-workspace.mjs +90 -57
  25. package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +178 -91
  26. package/docs/copilot-plugin-install.md +189 -177
  27. package/docs/driving-heyspex-from-copilot.md +174 -165
  28. package/docs/mcp-client-config.md +93 -25
  29. package/package.json +255 -250
  30. package/plugins/heyspex/.mcp.json +3 -4
  31. package/plugins/heyspex/README.md +323 -312
  32. package/plugins/heyspex/bin/launch-mcp.mjs +21 -7
  33. package/plugins/heyspex/mcp.json +12 -13
  34. package/scripts/check-mcp-freshness.mjs +6 -4
  35. package/scripts/claude-hooks/_intent-classifier-router.mjs +518 -456
  36. package/scripts/claude-hooks/intent-classifier-trigger.mjs +305 -279
  37. package/scripts/claude-hooks/research-method-guard.mjs +2 -2
  38. package/scripts/claude-hooks/wip-checkpoint.mjs +33 -9
  39. package/scripts/claude-statusline/fonts/HeySpexIcons.ttf +0 -0
  40. package/scripts/claude-statusline/statusline-command.mjs +1058 -0
  41. package/scripts/dev-server-status.mjs +3 -2
  42. package/scripts/dev-server-stop.mjs +3 -2
  43. package/scripts/hs-capture-cli.mjs +2 -2
  44. package/scripts/hs-settings.mjs +2 -2
  45. package/scripts/hs-view.mjs +3 -2
  46. package/scripts/install-copilot-hooks.mjs +64 -34
  47. package/scripts/lib/copilot-cli.mjs +108 -0
  48. package/scripts/lib/customer-kit.mjs +223 -30
  49. package/scripts/lib/dev-mode.mjs +28 -2
  50. package/scripts/lib/shared-path-helpers.mjs +32 -0
  51. package/scripts/lib/standalone-doctor.mjs +131 -32
  52. package/scripts/wip-ledger-health.mjs +3 -2
  53. package/spexharness/src/gates/vault-mirror-catchup.mjs +113 -24
  54. package/spexharness/src/gates/vault-mirror-catchup.runner.mjs +52 -0
  55. package/spexharness/src/intent-directive.mjs +839 -626
  56. package/spexharness/src/rule-table.mjs +1 -1
  57. package/vendor/heyspex-mcp/cli-verbs.mjs +16 -2
  58. package/vendor/heyspex-mcp/cli.mjs +20 -4
  59. package/vendor/heyspex-mcp/console-fetch.mjs +15 -3
  60. package/vendor/heyspex-mcp/dev-tools.mjs +11 -4
  61. package/vendor/heyspex-mcp/events-tools.mjs +1 -1
  62. package/vendor/heyspex-mcp/factory-run-status.mjs +42 -0
  63. package/vendor/heyspex-mcp/mcp-config.mjs +4 -2
  64. package/vendor/heyspex-mcp/spec-edit-tools.mjs +26 -1
  65. package/vendor/heyspex-mcp/test-helpers.mjs +5 -2
  66. package/vendor/heyspex-mcp/tool-catalog.mjs +12 -0
  67. package/vendor/heyspex-mcp/tool-dispatch.mjs +59 -23
  68. package/vendor/heyspex-mcp/usable-dir-env.mjs +82 -0
  69. package/vendor/heyspex-mcp/vault-binding.mjs +839 -0
  70. package/vendor/heyspex-mcp/vault-resolve.mjs +353 -245
@@ -161,9 +161,9 @@ function parseCredentialsStore(raw) {
161
161
  accounts
162
162
  };
163
163
  }
164
- function readTextOrNull(read, path15) {
164
+ function readTextOrNull(read, path16) {
165
165
  try {
166
- const raw = read(path15);
166
+ const raw = read(path16);
167
167
  return typeof raw === "string" ? raw : null;
168
168
  } catch {
169
169
  return null;
@@ -215,14 +215,14 @@ var init_session_owner = __esm({
215
215
  });
216
216
 
217
217
  // vendor/heyspex-mcp/vault-less-endpoints.mjs
218
- function pathnameOf(path15) {
219
- const raw = String(path15 ?? "").split("?")[0].split("#")[0];
218
+ function pathnameOf(path16) {
219
+ const raw = String(path16 ?? "").split("?")[0].split("#")[0];
220
220
  const noTrailing = raw.length > 1 ? raw.replace(/\/+$/, "") : raw;
221
221
  return noTrailing || "/";
222
222
  }
223
- function isVaultLessEndpoint(method, path15) {
223
+ function isVaultLessEndpoint(method, path16) {
224
224
  const m = String(method || "GET").toUpperCase();
225
- const pathname = pathnameOf(path15);
225
+ const pathname = pathnameOf(path16);
226
226
  return VAULT_LESS_ENDPOINTS.some((row) => {
227
227
  const [rowMethod, rowPath] = row.split(" ");
228
228
  return rowPath === pathname && (rowMethod === "*" || rowMethod === m);
@@ -245,7 +245,9 @@ var init_vault_less_endpoints = __esm({
245
245
  });
246
246
 
247
247
  // scripts/lib/shared-path-helpers.mjs
248
+ import { realpathSync } from "node:fs";
248
249
  import { isAbsolute, resolve as resolve2, sep } from "node:path";
250
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
249
251
  var init_shared_path_helpers = __esm({
250
252
  "scripts/lib/shared-path-helpers.mjs"() {
251
253
  "use strict";
@@ -270,20 +272,52 @@ var init_write_outbox = __esm({
270
272
  }
271
273
  });
272
274
 
275
+ // vendor/heyspex-mcp/usable-dir-env.mjs
276
+ import { statSync } from "node:fs";
277
+ import { isAbsolute as isAbsolute3 } from "node:path";
278
+ var init_usable_dir_env = __esm({
279
+ "vendor/heyspex-mcp/usable-dir-env.mjs"() {
280
+ "use strict";
281
+ }
282
+ });
283
+
284
+ // vendor/heyspex-mcp/vault-binding.mjs
285
+ import {
286
+ copyFileSync,
287
+ existsSync as existsSync3,
288
+ mkdirSync as mkdirSync3,
289
+ readFileSync as readFileSync4,
290
+ realpathSync as realpathSync2,
291
+ renameSync as renameSync3,
292
+ statSync as statSync2,
293
+ unlinkSync,
294
+ writeFileSync as writeFileSync3
295
+ } from "node:fs";
296
+ import { homedir as homedir4 } from "node:os";
297
+ import path from "node:path";
298
+ var init_vault_binding = __esm({
299
+ "vendor/heyspex-mcp/vault-binding.mjs"() {
300
+ "use strict";
301
+ }
302
+ });
303
+
273
304
  // vendor/heyspex-mcp/vault-resolve.mjs
274
- import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
275
- import { homedir as homedir4, tmpdir } from "node:os";
276
- import { dirname as dirname3, join as join5, resolve as resolve3 } from "node:path";
305
+ import { existsSync as existsSync4, readFileSync as readFileSync5, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
306
+ import { homedir as homedir5, tmpdir } from "node:os";
307
+ import { basename as basename2, dirname as dirname3, join as join5, resolve as resolve3 } from "node:path";
277
308
  var init_vault_resolve = __esm({
278
309
  "vendor/heyspex-mcp/vault-resolve.mjs"() {
279
310
  "use strict";
280
311
  init_heyspex_home();
312
+ init_usable_dir_env();
313
+ init_vault_binding();
314
+ init_vault_binding();
281
315
  }
282
316
  });
283
317
 
284
318
  // vendor/heyspex-mcp/console-fetch.mjs
285
- import { readFileSync as readFileSync5 } from "node:fs";
286
- import { homedir as homedir5 } from "node:os";
319
+ import { readFileSync as readFileSync6 } from "node:fs";
320
+ import { homedir as homedir6 } from "node:os";
287
321
  import { join as join6 } from "node:path";
288
322
  function isCloudVaultId(value) {
289
323
  return typeof value === "string" && CLOUD_VAULT_ID_RE.test(value.trim());
@@ -305,13 +339,13 @@ var init_console_fetch = __esm({
305
339
  });
306
340
 
307
341
  // spex-console/src/lib/heyspex-home.ts
308
- import { homedir as homedir6 } from "node:os";
342
+ import { homedir as homedir7 } from "node:os";
309
343
  function heyspexHome2(env = process.env) {
310
344
  const override = env?.HEYSPEX_HOME;
311
345
  if (typeof override === "string" && override.trim().length > 0) {
312
346
  return override.trim();
313
347
  }
314
- return homedir6();
348
+ return homedir7();
315
349
  }
316
350
  var init_heyspex_home2 = __esm({
317
351
  "spex-console/src/lib/heyspex-home.ts"() {
@@ -339,7 +373,7 @@ var init_types = __esm({
339
373
  });
340
374
 
341
375
  // spex-console/src/lib/vault-registry/registry-file.ts
342
- import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync6, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
376
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync7, renameSync as renameSync4, writeFileSync as writeFileSync4 } from "node:fs";
343
377
  import { dirname as dirname4, join as join7, resolve as resolve4 } from "node:path";
344
378
  function vaultRegistryDir(opts = {}) {
345
379
  return opts.registryDir ?? join7(heyspexHome2(), ".heyspex");
@@ -446,9 +480,9 @@ function parseVaultRegistryFile(json) {
446
480
  }
447
481
  function readRegistryJson(opts) {
448
482
  const filePath = vaultRegistryFilePath(opts);
449
- if (!existsSync4(filePath)) return { kind: "missing" };
483
+ if (!existsSync5(filePath)) return { kind: "missing" };
450
484
  try {
451
- const raw = readFileSync6(filePath, "utf8");
485
+ const raw = readFileSync7(filePath, "utf8");
452
486
  const json = JSON.parse(raw);
453
487
  if (registryFileSchemaOf(json) === null) return { kind: "unreadable" };
454
488
  return { kind: "ok", raw, json };
@@ -484,8 +518,8 @@ var init_registry_file = __esm({
484
518
  });
485
519
 
486
520
  // scripts/lib/dev-mode.mjs
487
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "node:fs";
488
- import { homedir as homedir7 } from "node:os";
521
+ import { mkdirSync as mkdirSync5, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "node:fs";
522
+ import { homedir as homedir8 } from "node:os";
489
523
  import { join as join8 } from "node:path";
490
524
  function devModeFilePath(homeDir = heyspexHome()) {
491
525
  return join8(homeDir, ".heyspex", DEV_MODE_FILENAME);
@@ -540,6 +574,11 @@ function readLocalDevModeRecord({ homeDir = heyspexHome(), readFile = defaultRea
540
574
  return { record: null, parseError: `unparseable dev-mode.json: ${String(err?.message ?? err)}` };
541
575
  }
542
576
  }
577
+ function overrideCloudCheck(source, cloudKnown, staleAgainstCloud) {
578
+ if (source !== "local-override") return "not-applicable";
579
+ if (!cloudKnown) return "unverified";
580
+ return staleAgainstCloud ? "stale" : "in-sync";
581
+ }
543
582
  function resolveDevMode({
544
583
  env = process.env,
545
584
  homeDir = heyspexHome(),
@@ -579,6 +618,7 @@ function resolveDevMode({
579
618
  const semantics = deriveSemantics(mode, reliance);
580
619
  const consoleUrl = source === "local-override" && local.record?.console_url ? local.record.console_url.replace(/\/+$/, "") : semantics.consoleUrl;
581
620
  const staleAgainstCloud = source === "local-override" && cloudValue !== null && (cloudValue.mode !== mode || mode === "dev" && cloudValue.reliance !== semantics.reliance);
621
+ const cloudCheck = overrideCloudCheck(source, cloudKnown, staleAgainstCloud);
582
622
  return {
583
623
  mode,
584
624
  reliance: semantics.reliance,
@@ -596,7 +636,8 @@ function resolveDevMode({
596
636
  present: local.record !== null,
597
637
  record: local.record,
598
638
  parseError: local.parseError,
599
- staleAgainstCloud
639
+ staleAgainstCloud,
640
+ cloudCheck
600
641
  },
601
642
  cloudSetting: { known: cloudKnown, value: cloudValue }
602
643
  };
@@ -610,13 +651,13 @@ var init_dev_mode = __esm({
610
651
  CLOUD_CONSOLE_URL = "https://app.heyspex.com";
611
652
  LOCAL_CONSOLE_URL = "http://localhost:3000";
612
653
  DEV_MODE_FILENAME = "dev-mode.json";
613
- defaultReadFile = (p) => readFileSync7(p, "utf8");
654
+ defaultReadFile = (p) => readFileSync8(p, "utf8");
614
655
  }
615
656
  });
616
657
 
617
658
  // scripts/lib/console-url-resolver.mjs
618
- import { readFileSync as readFileSync8 } from "node:fs";
619
- import { homedir as homedir8 } from "node:os";
659
+ import { readFileSync as readFileSync9 } from "node:fs";
660
+ import { homedir as homedir9 } from "node:os";
620
661
  import { join as join9 } from "node:path";
621
662
  function trimTrailingSlash(url) {
622
663
  return url.replace(/\/+$/, "");
@@ -651,7 +692,7 @@ function readCredentialsConsoleUrl({ homeDir = heyspexHome(), readFile = default
651
692
  }
652
693
  }
653
694
  function defaultReadFile2(p) {
654
- return readFileSync8(p, "utf8");
695
+ return readFileSync9(p, "utf8");
655
696
  }
656
697
  function readDiscoveryFileConsoleUrl(repoRoot, { readDiscovery: readDiscovery2 = defaultReadFile2 } = {}) {
657
698
  if (!repoRoot) return null;
@@ -726,9 +767,9 @@ var init_console_url_resolver = __esm({
726
767
  });
727
768
 
728
769
  // spex-console/src/lib/vault-registry/repo-identity.ts
729
- import path2 from "node:path";
770
+ import path3 from "node:path";
730
771
  function normalizeRepoRoot(p) {
731
- let resolved = path2.resolve(p);
772
+ let resolved = path3.resolve(p);
732
773
  while (resolved.length > 1 && (resolved.endsWith("/") || resolved.endsWith("\\"))) {
733
774
  resolved = resolved.slice(0, -1);
734
775
  }
@@ -737,8 +778,8 @@ function normalizeRepoRoot(p) {
737
778
  function repoRootCandidates(p) {
738
779
  const norm = normalizeRepoRoot(p);
739
780
  const candidates = [norm];
740
- if (path2.basename(norm) === "specs") {
741
- const parent = path2.dirname(norm);
781
+ if (path3.basename(norm) === "specs") {
782
+ const parent = path3.dirname(norm);
742
783
  if (parent !== norm) candidates.push(parent);
743
784
  }
744
785
  return candidates;
@@ -763,22 +804,22 @@ var init_default_workspace = __esm({
763
804
  });
764
805
 
765
806
  // spex-console/src/lib/cli/vault-workspace-shared.ts
766
- import { readFileSync as readFileSync9 } from "node:fs";
807
+ import { readFileSync as readFileSync10 } from "node:fs";
767
808
  function resolveConfiguredAccountId(opts = {}) {
768
809
  return resolveSessionOwnerUncached({
769
810
  env: opts.env ?? process.env,
770
811
  homeDir: opts.homeDir ?? heyspexHome2(),
771
- readFile: opts.readFile ?? ((p) => readFileSync9(p, "utf-8"))
812
+ readFile: opts.readFile ?? ((p) => readFileSync10(p, "utf-8"))
772
813
  });
773
814
  }
774
815
  function resolveCloudAccountIdOrRefuse(opts = {}) {
775
816
  const accountId = resolveConfiguredAccountId(opts);
776
817
  return accountId ? { ok: true, accountId } : { ok: false, message: CLOUD_ACCOUNT_ID_REQUIRED_MESSAGE };
777
818
  }
778
- async function cloudHttpRequest(http, method, path15, body) {
779
- const scopeHeaders = http.scope ? http.scope.headersFor(method, path15) : {};
819
+ async function cloudHttpRequest(http, method, path16, body) {
820
+ const scopeHeaders = http.scope ? http.scope.headersFor(method, path16) : {};
780
821
  try {
781
- const res = await http.fetchImpl(`${http.consoleUrl}${path15}`, {
822
+ const res = await http.fetchImpl(`${http.consoleUrl}${path16}`, {
782
823
  method,
783
824
  headers: {
784
825
  "content-type": "application/json",
@@ -1639,7 +1680,7 @@ var init_vault_shared = __esm({
1639
1680
  // spex-console/src/lib/indexer/parser.ts
1640
1681
  import { createHash } from "node:crypto";
1641
1682
  import { promises as fs2 } from "node:fs";
1642
- import path4 from "node:path";
1683
+ import path5 from "node:path";
1643
1684
  function normalizeWikilink2(raw) {
1644
1685
  let t = raw.trim();
1645
1686
  if (t.startsWith("[[") && t.endsWith("]]")) {
@@ -3812,9 +3853,9 @@ var init_satellite = __esm({
3812
3853
  });
3813
3854
 
3814
3855
  // spex-console/src/lib/vault-resolve/index.ts
3815
- import { existsSync as existsSync5, readFileSync as readFileSync11 } from "node:fs";
3856
+ import { existsSync as existsSync6, readFileSync as readFileSync12, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
3816
3857
  import { tmpdir as tmpdir2 } from "node:os";
3817
- import path5 from "node:path";
3858
+ import path6 from "node:path";
3818
3859
  var init_vault_resolve2 = __esm({
3819
3860
  "spex-console/src/lib/vault-resolve/index.ts"() {
3820
3861
  "use strict";
@@ -3851,12 +3892,12 @@ var init_resolve_status = __esm({
3851
3892
  });
3852
3893
 
3853
3894
  // spex-console/src/lib/vault-resolve/active.ts
3854
- import { existsSync as existsSync6 } from "node:fs";
3855
- import path6 from "node:path";
3895
+ import { existsSync as existsSync7 } from "node:fs";
3896
+ import path7 from "node:path";
3856
3897
  function fallbackSpecsDir() {
3857
3898
  const override = process.env.HEYSPEX_VAULT_DIR;
3858
- if (override) return path6.resolve(override);
3859
- return path6.resolve(process.cwd(), "..", "specs");
3899
+ if (override) return path7.resolve(override);
3900
+ return path7.resolve(process.cwd(), "..", "specs");
3860
3901
  }
3861
3902
  function getActiveSpecsDir() {
3862
3903
  return cacheStore.value ? cacheStore.value.specsDirAbs : fallbackSpecsDir();
@@ -3885,7 +3926,7 @@ var init_active = __esm({
3885
3926
 
3886
3927
  // spex-console/src/lib/control-plane/statusline-focus-cache.ts
3887
3928
  import fs3 from "node:fs";
3888
- import path7 from "node:path";
3929
+ import path8 from "node:path";
3889
3930
  var init_statusline_focus_cache = __esm({
3890
3931
  "spex-console/src/lib/control-plane/statusline-focus-cache.ts"() {
3891
3932
  "use strict";
@@ -4502,10 +4543,10 @@ function trashPathFor(relPath, now) {
4502
4543
  const normalized = relPath.split("\\").join("/");
4503
4544
  const slashIdx = normalized.lastIndexOf("/");
4504
4545
  const folder = slashIdx === -1 ? "" : normalized.slice(0, slashIdx);
4505
- const basename2 = slashIdx === -1 ? normalized : normalized.slice(slashIdx + 1);
4546
+ const basename3 = slashIdx === -1 ? normalized : normalized.slice(slashIdx + 1);
4506
4547
  const stamp = now.toISOString().replace(/[:.]/g, "-");
4507
4548
  const trashDir = folder ? `${folder}/.trash` : ".trash";
4508
- return `${trashDir}/${stamp}-${basename2}`;
4549
+ return `${trashDir}/${stamp}-${basename3}`;
4509
4550
  }
4510
4551
  function materializeSpecMarkdown(bundle) {
4511
4552
  return stringifySpecMarkdown(bundle.bodyText, bundle.frontmatter);
@@ -4627,10 +4668,10 @@ var init_export_status = __esm({
4627
4668
  function isGitHubFailure(value) {
4628
4669
  return typeof value === "object" && value !== null && "status" in value;
4629
4670
  }
4630
- async function githubJson(path15, target, fetchImpl, init) {
4671
+ async function githubJson(path16, target, fetchImpl, init) {
4631
4672
  let response;
4632
4673
  try {
4633
- response = await fetchImpl(`${GITHUB_API_BASE2}${path15}`, {
4674
+ response = await fetchImpl(`${GITHUB_API_BASE2}${path16}`, {
4634
4675
  ...init,
4635
4676
  headers: {
4636
4677
  ...githubHeaders(target.token),
@@ -5473,7 +5514,7 @@ var init_diagnose_spawned = __esm({
5473
5514
 
5474
5515
  // spex-console/src/lib/guardrail-naming.ts
5475
5516
  import fs4 from "node:fs";
5476
- import path8 from "node:path";
5517
+ import path9 from "node:path";
5477
5518
  var init_guardrail_naming = __esm({
5478
5519
  "spex-console/src/lib/guardrail-naming.ts"() {
5479
5520
  "use strict";
@@ -5576,7 +5617,7 @@ var init_scoped_context = __esm({
5576
5617
  // spex-console/src/lib/indexer/indexer-service.ts
5577
5618
  import { spawnSync } from "node:child_process";
5578
5619
  import { promises as fs5 } from "node:fs";
5579
- import path9 from "node:path";
5620
+ import path10 from "node:path";
5580
5621
  var init_indexer_service = __esm({
5581
5622
  "spex-console/src/lib/indexer/indexer-service.ts"() {
5582
5623
  "use strict";
@@ -5595,7 +5636,7 @@ var init_indexer_service = __esm({
5595
5636
 
5596
5637
  // spex-console/src/lib/indexer/outbox-index-feeder.ts
5597
5638
  import { promises as fs6 } from "node:fs";
5598
- import path10 from "node:path";
5639
+ import path11 from "node:path";
5599
5640
  var init_outbox_index_feeder = __esm({
5600
5641
  "spex-console/src/lib/indexer/outbox-index-feeder.ts"() {
5601
5642
  "use strict";
@@ -5874,7 +5915,7 @@ var init_list_filter = __esm({
5874
5915
  });
5875
5916
 
5876
5917
  // spex-console/src/lib/specs/list-query.ts
5877
- import path11 from "node:path";
5918
+ import path12 from "node:path";
5878
5919
  var init_list_query = __esm({
5879
5920
  "spex-console/src/lib/specs/list-query.ts"() {
5880
5921
  "use strict";
@@ -5917,7 +5958,7 @@ var init_pipeline_neighborhood = __esm({
5917
5958
  });
5918
5959
 
5919
5960
  // spex-console/src/lib/specs/spec-by-id.ts
5920
- import path12 from "node:path";
5961
+ import path13 from "node:path";
5921
5962
  var init_spec_by_id = __esm({
5922
5963
  "spex-console/src/lib/specs/spec-by-id.ts"() {
5923
5964
  "use strict";
@@ -5974,9 +6015,9 @@ var init_search_body_hit = __esm({
5974
6015
 
5975
6016
  // spex-console/src/lib/vault.ts
5976
6017
  import { spawn } from "node:child_process";
5977
- import { readdirSync as readdirSync2, readFileSync as readFileSync12, statSync } from "node:fs";
6018
+ import { readdirSync as readdirSync2, readFileSync as readFileSync13, statSync as statSync5 } from "node:fs";
5978
6019
  import { promises as fs7 } from "node:fs";
5979
- import path13 from "node:path";
6020
+ import path14 from "node:path";
5980
6021
  import yaml3 from "js-yaml";
5981
6022
  function normalizeDateField(value) {
5982
6023
  let d = null;
@@ -6017,18 +6058,18 @@ function extractBodyLinks(body) {
6017
6058
  return links;
6018
6059
  }
6019
6060
  function toSummary(absPath, root, fm, body) {
6020
- const basename2 = path13.basename(absPath).replace(/\.md$/i, "");
6021
- const relPath = path13.relative(root, absPath).split(path13.sep).join("/");
6061
+ const basename3 = path14.basename(absPath).replace(/\.md$/i, "");
6062
+ const relPath = path14.relative(root, absPath).split(path14.sep).join("/");
6022
6063
  return {
6023
- id: typeof fm.id === "string" && fm.id ? fm.id : basename2,
6024
- name: typeof fm.name === "string" && fm.name ? fm.name : basename2,
6064
+ id: typeof fm.id === "string" && fm.id ? fm.id : basename3,
6065
+ name: typeof fm.name === "string" && fm.name ? fm.name : basename3,
6025
6066
  type: typeof fm.type === "string" ? fm.type : "unknown",
6026
6067
  status: typeof fm.status === "string" ? fm.status : "unknown",
6027
6068
  effort: typeof fm.effort === "number" ? fm.effort : null,
6028
6069
  owner: typeof fm.owner === "string" ? fm.owner : null,
6029
6070
  tags: Array.isArray(fm.tags) ? fm.tags.map(String) : [],
6030
6071
  archived: fm.archived === true,
6031
- basename: basename2,
6072
+ basename: basename3,
6032
6073
  relPath,
6033
6074
  links: extractBodyLinks(body),
6034
6075
  created: normalizeDateField(fm.created),
@@ -6114,9 +6155,9 @@ function invalidateVaultCacheForFile(absPath) {
6114
6155
  else evictProcessVaultHotRows();
6115
6156
  }
6116
6157
  function specIdFromAbsPath(absPath) {
6117
- const basename2 = path13.basename(absPath).replace(/\.md$/i, "");
6118
- if (!basename2) return null;
6119
- const parsed = parseSpecId(basename2);
6158
+ const basename3 = path14.basename(absPath).replace(/\.md$/i, "");
6159
+ if (!basename3) return null;
6160
+ const parsed = parseSpecId(basename3);
6120
6161
  if (parsed?.era === 3 && parsed.fileKey) return `HS-${parsed.fileKey.toUpperCase()}`;
6121
6162
  return null;
6122
6163
  }
@@ -6205,8 +6246,8 @@ function isLocalVaultMode() {
6205
6246
  }
6206
6247
  async function writeSpecBytesToVault(relPath, content) {
6207
6248
  try {
6208
- const absPath = path13.join(vaultRoot(), relPath);
6209
- const dir = path13.dirname(absPath);
6249
+ const absPath = path14.join(vaultRoot(), relPath);
6250
+ const dir = path14.dirname(absPath);
6210
6251
  await fs7.mkdir(dir, { recursive: true });
6211
6252
  await fs7.writeFile(absPath, content, "utf8");
6212
6253
  } catch (err) {
@@ -6372,9 +6413,9 @@ var init_vault = __esm({
6372
6413
 
6373
6414
  // spex-console/bin/hs-index-reconcile.ts
6374
6415
  import { execFileSync } from "node:child_process";
6375
- import { appendFileSync, mkdirSync as mkdirSync6, readFileSync as readFileSync13, writeFileSync as writeFileSync6 } from "node:fs";
6416
+ import { appendFileSync, mkdirSync as mkdirSync7, readFileSync as readFileSync15, writeFileSync as writeFileSync7 } from "node:fs";
6376
6417
  import { promises as fs10 } from "node:fs";
6377
- import path14 from "node:path";
6418
+ import path15 from "node:path";
6378
6419
  import process4 from "node:process";
6379
6420
 
6380
6421
  // spex-console/src/lib/cli/control-shared.ts
@@ -6384,14 +6425,14 @@ init_credentials();
6384
6425
  init_session_owner();
6385
6426
  init_vault_less_endpoints();
6386
6427
  init_registry_file();
6387
- import path from "node:path";
6428
+ import path2 from "node:path";
6388
6429
  var VAULT_ID_HEADER = "x-heyspex-vault-id";
6389
6430
  var ACCOUNT_ID_HEADER = "x-heyspex-account-id";
6390
- function scopeHeadersFor(scope, method, path15) {
6431
+ function scopeHeadersFor(scope, method, path16) {
6391
6432
  if (scope === "none") {
6392
- if (!isVaultLessEndpoint(method, path15)) {
6433
+ if (!isVaultLessEndpoint(method, path16)) {
6393
6434
  throw new Error(
6394
- `controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${path15} is vault-scoped and must name { accountId, vaultId }.`
6435
+ `controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${path16} is vault-scoped and must name { accountId, vaultId }.`
6395
6436
  );
6396
6437
  }
6397
6438
  return {};
@@ -6402,7 +6443,7 @@ function cloudRequestScope(scope) {
6402
6443
  const named = { accountId: scope.accountId, vaultId: scope.vaultId };
6403
6444
  return {
6404
6445
  ...named,
6405
- headersFor: (method, path15) => isVaultLessEndpoint(method, path15) ? {} : scopeHeadersFor(named, method, path15)
6446
+ headersFor: (method, path16) => isVaultLessEndpoint(method, path16) ? {} : scopeHeadersFor(named, method, path16)
6406
6447
  };
6407
6448
  }
6408
6449
 
@@ -6475,12 +6516,15 @@ var HELP2 = [
6475
6516
  "(spex-console/src/lib/cli/template-manifest.ts) \u2014 universal docs",
6476
6517
  "copied verbatim, template-shape docs written as author-prompt skeletons \u2014",
6477
6518
  "plus a generated CLAUDE.md, the kept-principles index, and the template_version",
6478
- "pin; with --git, one initial `git init` + commit. Rerunnable: a <dir> that already",
6479
- "holds heyspex.yaml and an empty/placeholder-only specs/ is accepted, existing",
6480
- "files are never overwritten (an existing CLAUDE.md gets a CLAUDE.md.template",
6481
- "beside it), and the result lists each manifest row as created or kept. Refuses a",
6482
- "non-empty <dir> without heyspex.yaml, or a specs/ holding managed specs.",
6483
- "See init.customer-vault.ts.",
6519
+ "pin; with --git, one initial `git init` + commit. On an EXISTING vault (<dir>",
6520
+ "holds heyspex.yaml with a vault_id) it is a REFRESH \u2014 the repair `hs doctor`'s",
6521
+ "vault-template row names: only missing shipped files are added, template_version",
6522
+ "is written/updated in heyspex.yaml (every other byte and the vault_id kept),",
6523
+ "nothing existing is ever overwritten (an existing CLAUDE.md gets a",
6524
+ "CLAUDE.md.template beside it), the result lists each manifest row as created or",
6525
+ "kept, and a second run writes nothing. <dir> may be any path (a satellite repo",
6526
+ "names its vault, e.g. `hs init --customer-vault ../my-specs`). Refuses only a",
6527
+ "non-empty <dir> that has no heyspex.yaml. See init.customer-vault.ts.",
6484
6528
  "",
6485
6529
  "Flags:",
6486
6530
  " --console-url <url> console_url value (default: the mode-aware console --",
@@ -6507,7 +6551,7 @@ init_console_fetch();
6507
6551
  init_registry_file();
6508
6552
  init_repo_identity();
6509
6553
  import { promises as fs } from "node:fs";
6510
- import path3 from "node:path";
6554
+ import path4 from "node:path";
6511
6555
  init_vault_workspace_shared();
6512
6556
  var SYNC_VAULT_EXIT_UNRESOLVED = 11;
6513
6557
  function refuse(message) {
@@ -6558,7 +6602,7 @@ async function resolveSyncVaultTargetFromEnv(deps) {
6558
6602
  let markerVaultId = null;
6559
6603
  try {
6560
6604
  markerVaultId = parseVaultId(
6561
- await fs.readFile(path3.join(deps.vaultRoot, "heyspex.yaml"), "utf8")
6605
+ await fs.readFile(path4.join(deps.vaultRoot, "heyspex.yaml"), "utf8")
6562
6606
  );
6563
6607
  } catch {
6564
6608
  markerVaultId = null;
@@ -6608,6 +6652,25 @@ init_vault_workspace_shared();
6608
6652
  init_parser();
6609
6653
 
6610
6654
  // spex-console/src/lib/vault-sync/pull.ts
6655
+ function detectEol(text2) {
6656
+ const crlf = (text2.match(/\r\n/g) ?? []).length;
6657
+ const all = (text2.match(/\n/g) ?? []).length;
6658
+ if (all === 0) return null;
6659
+ return crlf * 2 >= all ? "\r\n" : "\n";
6660
+ }
6661
+ function classifyHeyspexYaml(text2) {
6662
+ if (text2 === null) return "none";
6663
+ if (/^vault_path:[ \t]*[^\s#]/m.test(text2)) return "satellite";
6664
+ if (/^kind:[ \t]*["']?repo-binding["']?[ \t]*$/m.test(text2)) return "repo-binding";
6665
+ const markerKey = /^(vault_id|vault_root):/m.test(text2);
6666
+ if (!markerKey && /^vault:/m.test(text2)) return "repo-binding";
6667
+ return "vault";
6668
+ }
6669
+ function pullTargetRefusal(repoRoot, markerText) {
6670
+ const kind = classifyHeyspexYaml(markerText);
6671
+ if (kind !== "satellite" && kind !== "repo-binding") return null;
6672
+ return `refusing to write specs/ into ${repoRoot}: its heyspex.yaml is a ${kind} marker (a code repo that names its vault elsewhere), not a vault checkout. Nothing was written. Run \`hs pull\` inside the vault's own checkout (\`hs vault resolve\` shows which one this repo is bound to).`;
6673
+ }
6611
6674
  function normalizeSpecRelPath(raw) {
6612
6675
  if (typeof raw !== "string") return null;
6613
6676
  let p = raw.trim();
@@ -6702,9 +6765,9 @@ function isRoutableStatus(status, type) {
6702
6765
  if (ROUTE_SETTABLE_STATUSES.has(status)) return true;
6703
6766
  return (type ?? "").toLowerCase() === "adr" && ADR_SETTABLE_STATUSES.has(status);
6704
6767
  }
6705
- function matchesSelector(id, basename2, selectors) {
6768
+ function matchesSelector(id, basename3, selectors) {
6706
6769
  const i = id.toLowerCase();
6707
- const b = basename2.toLowerCase();
6770
+ const b = basename3.toLowerCase();
6708
6771
  return selectors.some((raw) => {
6709
6772
  const s = raw.trim().toLowerCase();
6710
6773
  return s.length > 0 && (i === s || b === s || i.startsWith(`${s}-`) || b.startsWith(`${s}-`));
@@ -6744,20 +6807,20 @@ function decideReconcilePlan({
6744
6807
  const c = cloudById.get(id) ?? null;
6745
6808
  const primary = d ?? c;
6746
6809
  const relPath = reconcileRelPath(primary.relPath);
6747
- const basename2 = primary.basename || basenameOfRelPath(relPath);
6810
+ const basename3 = primary.basename || basenameOfRelPath(relPath);
6748
6811
  const type = d?.type ?? c?.type ?? null;
6749
6812
  const base = {
6750
6813
  id,
6751
6814
  type,
6752
- basename: basename2,
6815
+ basename: basename3,
6753
6816
  relPath,
6754
6817
  disk: view(d),
6755
6818
  cloud: view(c),
6756
6819
  ...d?.closeReason ? { closeReason: d.closeReason } : {}
6757
6820
  };
6758
6821
  if (d && isCapabilityDoc(d.relPath)) capDocsOnDisk += 1;
6759
- if (only.length > 0 && !matchesSelector(id, basename2, only)) continue;
6760
- if (skip.length > 0 && matchesSelector(id, basename2, skip)) {
6822
+ if (only.length > 0 && !matchesSelector(id, basename3, only)) continue;
6823
+ if (skip.length > 0 && matchesSelector(id, basename3, skip)) {
6761
6824
  rows.push(hold({ ...base, winner: "none" }, "skipped", "held by --skip"));
6762
6825
  continue;
6763
6826
  }
@@ -7025,10 +7088,10 @@ async function applyReconcilePlan(deps, plan) {
7025
7088
  }
7026
7089
  return summarizeResult(rows, plan, sideEffects);
7027
7090
  }
7028
- function interpretPatch(requested, res, basename2, sideEffects) {
7091
+ function interpretPatch(requested, res, basename3, sideEffects) {
7029
7092
  const json = rec(res.json);
7030
7093
  if (res.status >= 200 && res.status < 300) {
7031
- pushSideEffects(sideEffects, basename2, json);
7094
+ pushSideEffects(sideEffects, basename3, json);
7032
7095
  const coercedTo = str2(json.coerced_to) ?? str2(json.coercedTo);
7033
7096
  if (coercedTo && coercedTo !== requested) {
7034
7097
  return {
@@ -7307,16 +7370,17 @@ async function postEdgesChunk(input, specs2) {
7307
7370
  }
7308
7371
 
7309
7372
  // spex-console/src/lib/vault-sync/pull-io.ts
7310
- import { promises as fs9 } from "node:fs";
7373
+ import { promises as fs9, readFileSync as readFileSync14 } from "node:fs";
7374
+ import { EOL } from "node:os";
7311
7375
  import nodePath2 from "node:path";
7312
7376
 
7313
7377
  // spex-console/src/lib/dev-mode.ts
7314
7378
  init_heyspex_home2();
7315
7379
  init_credentials();
7316
- import { mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "node:fs";
7380
+ import { mkdirSync as mkdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
7317
7381
  import { join as join10 } from "node:path";
7318
7382
  var CLOUD_CONSOLE_URL2 = "https://app.heyspex.com";
7319
- var defaultReadFile3 = (p) => readFileSync10(p, "utf8");
7383
+ var defaultReadFile3 = (p) => readFileSync11(p, "utf8");
7320
7384
  function readCredentialsMcpToken({
7321
7385
  homeDir = heyspexHome2(),
7322
7386
  readFile = defaultReadFile3
@@ -7344,6 +7408,30 @@ function hashContent(content) {
7344
7408
  }
7345
7409
 
7346
7410
  // spex-console/src/lib/vault-sync/pull-io.ts
7411
+ var DEFAULT_PULL_EOL = EOL === "\r\n" ? "\r\n" : "\n";
7412
+ async function eolForPath(abs, fallback = DEFAULT_PULL_EOL) {
7413
+ try {
7414
+ return detectEol(await fs9.readFile(abs, "utf8")) ?? fallback;
7415
+ } catch {
7416
+ return fallback;
7417
+ }
7418
+ }
7419
+ var PullTargetNotVaultError = class extends Error {
7420
+ constructor(message) {
7421
+ super(message);
7422
+ this.name = "PullTargetNotVaultError";
7423
+ }
7424
+ };
7425
+ function assertPullTargetIsVault(repoRoot) {
7426
+ let text2;
7427
+ try {
7428
+ text2 = readFileSync14(nodePath2.join(repoRoot, "heyspex.yaml"), "utf8");
7429
+ } catch {
7430
+ text2 = null;
7431
+ }
7432
+ const refusal = pullTargetRefusal(repoRoot, text2);
7433
+ if (refusal) throw new PullTargetNotVaultError(refusal);
7434
+ }
7347
7435
  var LIST_FIELDS = "id,basename,relPath,type,status,updated,updatedAt";
7348
7436
  var PULL_LIST_PAGE_LIMIT = 500;
7349
7437
  var PULL_LIST_MAX_PAGES = 2e3;
@@ -7367,10 +7455,10 @@ function resolvePullSourceUrl(explicit) {
7367
7455
  const raw = explicit?.trim() || process.env.HEYSPEX_PULL_SOURCE_URL?.trim() || CLOUD_CONSOLE_URL2;
7368
7456
  return raw.replace(/\/+$/, "");
7369
7457
  }
7370
- async function getJson({ baseUrl, token, fetchImpl = fetch, scopeHeaders = {} }, path15) {
7458
+ async function getJson({ baseUrl, token, fetchImpl = fetch, scopeHeaders = {} }, path16) {
7371
7459
  const headers = { Accept: "application/json", ...scopeHeaders };
7372
7460
  if (token) headers.Authorization = `Bearer ${token}`;
7373
- const res = await fetchImpl(`${baseUrl}/${path15.replace(/^\/+/, "")}`, { headers });
7461
+ const res = await fetchImpl(`${baseUrl}/${path16.replace(/^\/+/, "")}`, { headers });
7374
7462
  const text2 = await res.text();
7375
7463
  let json = null;
7376
7464
  try {
@@ -7535,6 +7623,12 @@ function createVaultPullDeps({
7535
7623
  }) {
7536
7624
  const http = { baseUrl, token, fetchImpl, scopeHeaders };
7537
7625
  const prefetched = /* @__PURE__ */ new Map();
7626
+ let targetChecked = false;
7627
+ const guardTarget = () => {
7628
+ if (!localRoot || targetChecked) return;
7629
+ assertPullTargetIsVault(nodePath2.dirname(localRoot));
7630
+ targetChecked = true;
7631
+ };
7538
7632
  return {
7539
7633
  listRemote: () => listRemoteSpecs(http),
7540
7634
  getRemoteRef: async (selector) => {
@@ -7556,7 +7650,9 @@ function createVaultPullDeps({
7556
7650
  finish: ledger ? () => ledger.flush() : void 0,
7557
7651
  listLocal: () => listLocalSpecRelPaths(localRoot ?? vaultRoot()),
7558
7652
  serialize: stringifySpecMarkdown,
7653
+ eolFor: (relPath) => eolForPath(nodePath2.join(localRoot ?? vaultRoot(), relPath)),
7559
7654
  writeSpec: localRoot ? async (relPath, content, opts) => {
7655
+ guardTarget();
7560
7656
  const abs = nodePath2.join(localRoot, relPath);
7561
7657
  await fs9.mkdir(nodePath2.dirname(abs), { recursive: true });
7562
7658
  onLocalWrite?.(relPath);
@@ -7733,7 +7829,7 @@ function say(args, text2) {
7733
7829
  }
7734
7830
  function readDiscovery(p) {
7735
7831
  try {
7736
- return readFileSync13(p, "utf-8");
7832
+ return readFileSync15(p, "utf-8");
7737
7833
  } catch {
7738
7834
  return null;
7739
7835
  }
@@ -7745,7 +7841,7 @@ function resolveConsole(args) {
7745
7841
  }
7746
7842
  function readMarkerVaultId(vaultRoot2) {
7747
7843
  try {
7748
- return parseVaultId(readFileSync13(path14.join(vaultRoot2, "heyspex.yaml"), "utf8"));
7844
+ return parseVaultId(readFileSync15(path15.join(vaultRoot2, "heyspex.yaml"), "utf8"));
7749
7845
  } catch {
7750
7846
  return null;
7751
7847
  }
@@ -7760,7 +7856,7 @@ function rosterSizeOf(fm, type) {
7760
7856
  return Array.isArray(list) ? list.filter((x) => x !== null && x !== void 0 && x !== "").length : 0;
7761
7857
  }
7762
7858
  async function walkLocal(args) {
7763
- const specsDir = path14.join(args.vaultRoot, "specs");
7859
+ const specsDir = path15.join(args.vaultRoot, "specs");
7764
7860
  const files = [];
7765
7861
  async function walk(dir) {
7766
7862
  let entries;
@@ -7770,7 +7866,7 @@ async function walkLocal(args) {
7770
7866
  return;
7771
7867
  }
7772
7868
  for (const entry of entries) {
7773
- const full = path14.join(dir, entry.name);
7869
+ const full = path15.join(dir, entry.name);
7774
7870
  if (entry.isDirectory()) {
7775
7871
  if (entry.name === "node_modules") continue;
7776
7872
  await walk(full);
@@ -7785,12 +7881,12 @@ async function walkLocal(args) {
7785
7881
  const contents = /* @__PURE__ */ new Map();
7786
7882
  let failed = 0;
7787
7883
  for (const abs of files) {
7788
- const relPath = path14.relative(specsDir, abs).split(path14.sep).join("/");
7884
+ const relPath = path15.relative(specsDir, abs).split(path15.sep).join("/");
7789
7885
  try {
7790
7886
  const content = await fs10.readFile(abs, "utf8");
7791
7887
  const parsed = parseSpecFromContent(content, {
7792
7888
  relPath: `specs/${relPath}`,
7793
- basenameFallback: path14.basename(abs).replace(/\.md$/i, "")
7889
+ basenameFallback: path15.basename(abs).replace(/\.md$/i, "")
7794
7890
  });
7795
7891
  const fm = parsed.rawFrontmatter ?? {};
7796
7892
  records.push({
@@ -7920,18 +8016,18 @@ function reportStamp() {
7920
8016
  return (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
7921
8017
  }
7922
8018
  function writeReport(vaultRoot2, payload) {
7923
- const dir = path14.join(vaultRoot2, ".heyspex", "index-reconcile");
7924
- mkdirSync6(dir, { recursive: true });
7925
- const file = path14.join(dir, `${reportStamp()}.json`);
7926
- writeFileSync6(file, `${JSON.stringify(payload, null, 2)}
8019
+ const dir = path15.join(vaultRoot2, ".heyspex", "index-reconcile");
8020
+ mkdirSync7(dir, { recursive: true });
8021
+ const file = path15.join(dir, `${reportStamp()}.json`);
8022
+ writeFileSync7(file, `${JSON.stringify(payload, null, 2)}
7927
8023
  `, "utf-8");
7928
8024
  return file;
7929
8025
  }
7930
8026
  function appendJournal(vaultRoot2, message) {
7931
- const heyspexDir = path14.join(vaultRoot2, ".heyspex");
7932
- mkdirSync6(heyspexDir, { recursive: true });
8027
+ const heyspexDir = path15.join(vaultRoot2, ".heyspex");
8028
+ mkdirSync7(heyspexDir, { recursive: true });
7933
8029
  appendFileSync(
7934
- path14.join(heyspexDir, "index-reconcile.log"),
8030
+ path15.join(heyspexDir, "index-reconcile.log"),
7935
8031
  `[${(/* @__PURE__ */ new Date()).toISOString()}] ${message}
7936
8032
  `,
7937
8033
  "utf-8"
@@ -7961,7 +8057,7 @@ async function main() {
7961
8057
  if (args.apply && markerVaultId && markerVaultId !== vaultId) {
7962
8058
  fail(
7963
8059
  RECONCILE_EXIT.VAULT_UNRESOLVED,
7964
- `refusing --apply: it would reconcile vault ${vaultId} against ${path14.join(args.vaultRoot, "specs")}, but that repo's heyspex.yaml names vault ${markerVaultId}. Nothing was written.`
8060
+ `refusing --apply: it would reconcile vault ${vaultId} against ${path15.join(args.vaultRoot, "specs")}, but that repo's heyspex.yaml names vault ${markerVaultId}. Nothing was written.`
7965
8061
  );
7966
8062
  }
7967
8063
  const account = resolveCloudAccountIdOrRefuse();
@@ -8023,11 +8119,11 @@ async function main() {
8023
8119
  baseUrl: consoleUrl,
8024
8120
  token,
8025
8121
  scopeHeaders: scope.headersFor("GET", "/api/specs"),
8026
- localRoot: path14.join(args.vaultRoot, "specs")
8122
+ localRoot: path15.join(args.vaultRoot, "specs")
8027
8123
  });
8028
8124
  const deps = {
8029
- patchStatus: async (basename2, body) => {
8030
- const route = `/api/specs/${encodeURIComponent(basename2)}/status`;
8125
+ patchStatus: async (basename3, body) => {
8126
+ const route = `/api/specs/${encodeURIComponent(basename3)}/status`;
8031
8127
  try {
8032
8128
  const res = await fetch(`${consoleUrl}${route}`, {
8033
8129
  method: "PATCH",
@@ -8116,7 +8212,7 @@ async function main() {
8116
8212
  rows: final.rows
8117
8213
  };
8118
8214
  const reportPath = writeReport(args.vaultRoot, payload);
8119
- const reportRel = path14.relative(args.vaultRoot, reportPath).split(path14.sep).join("/");
8215
+ const reportRel = path15.relative(args.vaultRoot, reportPath).split(path15.sep).join("/");
8120
8216
  if (args.json) {
8121
8217
  process4.stdout.write(`${JSON.stringify({ ...payload, report: reportRel })}
8122
8218
  `);