heyspex 0.2.0 → 0.2.1

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 (145) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/bin/hs.mjs +163 -11
  3. package/dist/cli/hs-check.mjs +88 -46
  4. package/dist/cli/hs-claim.mjs +84 -39
  5. package/dist/cli/hs-connect.mjs +583 -129
  6. package/dist/cli/hs-defer.mjs +251 -30
  7. package/dist/cli/hs-dev.mjs +20 -8
  8. package/dist/cli/hs-env.mjs +62 -34
  9. package/dist/cli/hs-index-rebuild.mjs +288 -83
  10. package/dist/cli/hs-index-reconcile.mjs +397 -111
  11. package/dist/cli/hs-init.mjs +2143 -91
  12. package/dist/cli/hs-install.mjs +628 -106
  13. package/dist/cli/hs-join.mjs +686 -236
  14. package/dist/cli/hs-vault-pull.mjs +3189 -179
  15. package/dist/cli/hs-vault-push.mjs +6433 -0
  16. package/dist/cli/hs-vault.mjs +396 -178
  17. package/dist/cli/hs-workspace.mjs +289 -151
  18. package/dist/cli-templates/harness-commands/claude/hs-backfill.md +28 -28
  19. package/dist/cli-templates/harness-commands/claude/hs-capture.md +62 -62
  20. package/dist/cli-templates/harness-commands/claude/hs-defer.md +29 -29
  21. package/dist/cli-templates/harness-commands/claude/hs-ground.md +30 -28
  22. package/dist/cli-templates/harness-commands/claude/hs-next.md +29 -29
  23. package/dist/cli-templates/harness-commands/claude/hs-promote.md +70 -70
  24. package/dist/cli-templates/harness-commands/claude/hs-push.md +35 -35
  25. package/dist/cli-templates/harness-commands/claude/hs-qc.md +27 -27
  26. package/dist/cli-templates/harness-commands/claude/hs-resolve.md +23 -23
  27. package/dist/cli-templates/harness-commands/claude/hs-review.md +23 -23
  28. package/dist/cli-templates/harness-commands/claude/hs-view.md +28 -26
  29. package/dist/cli-templates/harness-commands/claude/kill-ports.md +32 -32
  30. package/dist/cli-templates/harness-commands/claude/prototype.md +91 -91
  31. package/dist/cli-templates/harness-commands/cursor/hs-backfill.md +22 -22
  32. package/dist/cli-templates/harness-commands/cursor/hs-capture.md +56 -56
  33. package/dist/cli-templates/harness-commands/cursor/hs-defer.md +23 -23
  34. package/dist/cli-templates/harness-commands/cursor/hs-ground.md +24 -22
  35. package/dist/cli-templates/harness-commands/cursor/hs-next.md +23 -23
  36. package/dist/cli-templates/harness-commands/cursor/hs-promote.md +64 -64
  37. package/dist/cli-templates/harness-commands/cursor/hs-push.md +29 -29
  38. package/dist/cli-templates/harness-commands/cursor/hs-qc.md +21 -21
  39. package/dist/cli-templates/harness-commands/cursor/hs-resolve.md +17 -17
  40. package/dist/cli-templates/harness-commands/cursor/hs-review.md +17 -17
  41. package/dist/cli-templates/harness-commands/cursor/hs-view.md +24 -22
  42. package/dist/cli-templates/harness-commands/cursor/kill-ports.md +26 -26
  43. package/dist/cli-templates/harness-commands/cursor/prototype.md +86 -86
  44. package/docs/copilot-plugin-install.md +162 -0
  45. package/docs/driving-heyspex-from-copilot.md +165 -0
  46. package/package.json +20 -2
  47. package/plugins/heyspex/.claude-plugin/plugin.json +12 -12
  48. package/plugins/heyspex/.cursor-plugin/plugin.json +15 -15
  49. package/plugins/heyspex/README.md +309 -0
  50. package/plugins/heyspex/bin/run-hook.mjs +20 -2
  51. package/plugins/heyspex/hooks/cursor-hooks.json +81 -0
  52. package/plugins/heyspex/hooks/hooks.json +94 -37
  53. package/scripts/claude-hooks/_intent-classifier-router.mjs +456 -410
  54. package/scripts/claude-hooks/_intent-classifier-semantic.mjs +5 -0
  55. package/scripts/claude-hooks/_run.mjs +316 -23
  56. package/scripts/claude-hooks/capture-execution-gate.mjs +51 -0
  57. package/scripts/claude-hooks/claim-liveness-shared.mjs +2 -0
  58. package/scripts/claude-hooks/diagnose-capture-reminder.mjs +11 -0
  59. package/scripts/claude-hooks/directive-obligation-gate.mjs +11 -0
  60. package/scripts/claude-hooks/inject-communication-style.mjs +20 -0
  61. package/scripts/claude-hooks/intent-classifier-trigger.mjs +279 -247
  62. package/scripts/claude-hooks/session-end.mjs +2 -0
  63. package/scripts/claude-hooks/vault-mirror-catchup.mjs +11 -0
  64. package/scripts/claude-hooks/vault-write-tier-guard.mjs +11 -0
  65. package/scripts/claude-hooks/wip-checkpoint.mjs +5 -1
  66. package/scripts/cursor-hooks/manifest.mjs +46 -0
  67. package/scripts/heyspex-mode.mjs +20 -0
  68. package/scripts/hs-mode.mjs +1 -1
  69. package/scripts/hs-view.mjs +180 -17
  70. package/scripts/install-claude-code-hooks.mjs +3 -1
  71. package/scripts/lib/console-url-resolver.mjs +3 -2
  72. package/scripts/lib/customer-kit.mjs +327 -10
  73. package/scripts/lib/dev-mode.mjs +7 -6
  74. package/scripts/lib/directive-obligations.mjs +349 -0
  75. package/scripts/lib/hook-dispositions.mjs +210 -0
  76. package/scripts/lib/hook-vault-header.mjs +30 -0
  77. package/scripts/lib/hs-source-branch.mjs +196 -0
  78. package/scripts/lib/hs-source-log.mjs +2 -1
  79. package/scripts/lib/hs-source-preflight.mjs +18 -4
  80. package/scripts/lib/hs-source-push.mjs +386 -356
  81. package/scripts/lib/window-placement.mjs +109 -0
  82. package/spexharness/src/adapters/claude-code.mjs +11 -3
  83. package/spexharness/src/adapters/copilot.mjs +236 -0
  84. package/spexharness/src/adapters/detect-harness.mjs +34 -0
  85. package/spexharness/src/gates/_shell-write-targets.mjs +77 -0
  86. package/spexharness/src/gates/deep-research-cost-gate.mjs +4 -3
  87. package/spexharness/src/gates/diagnose-capture-reminder.mjs +112 -0
  88. package/spexharness/src/gates/directive-obligation-gate.decide.mjs +132 -0
  89. package/spexharness/src/gates/directive-obligation-gate.mjs +183 -0
  90. package/spexharness/src/gates/vault-mirror-catchup.mjs +124 -0
  91. package/spexharness/src/gates/vault-write-tier-guard.decide.mjs +125 -0
  92. package/spexharness/src/gates/vault-write-tier-guard.mjs +42 -0
  93. package/spexharness/src/intent-classifier.mjs +4 -2
  94. package/spexharness/src/intent-directive.mjs +626 -541
  95. package/spexharness/src/rule-table.mjs +31 -1
  96. package/vendor/heyspex-mcp/account-switch.mjs +6 -5
  97. package/vendor/heyspex-mcp/capture-buffer-patches.mjs +31 -3
  98. package/vendor/heyspex-mcp/capture-console-client.mjs +37 -2
  99. package/vendor/heyspex-mcp/capture-focus.mjs +26 -2
  100. package/vendor/heyspex-mcp/capture-outbox.mjs +10 -4
  101. package/vendor/heyspex-mcp/capture-sources.mjs +195 -0
  102. package/vendor/heyspex-mcp/capture-tools.mjs +56 -11
  103. package/vendor/heyspex-mcp/claim-tools.mjs +25 -2
  104. package/vendor/heyspex-mcp/cli-verbs.mjs +19 -21
  105. package/vendor/heyspex-mcp/cli.mjs +7 -1
  106. package/vendor/heyspex-mcp/close-branch-report.mjs +102 -0
  107. package/vendor/heyspex-mcp/cloud-vault-writes.mjs +197 -7
  108. package/vendor/heyspex-mcp/console-fetch.mjs +192 -28
  109. package/vendor/heyspex-mcp/console-transport.mjs +7 -1
  110. package/vendor/heyspex-mcp/credentials.mjs +9 -8
  111. package/vendor/heyspex-mcp/dev-tools.mjs +7 -0
  112. package/vendor/heyspex-mcp/filing-tools.mjs +35 -0
  113. package/vendor/heyspex-mcp/fleet-queue-tools.mjs +2 -1
  114. package/vendor/heyspex-mcp/folder-trust-store.mjs +2 -1
  115. package/vendor/heyspex-mcp/http-transport.mjs +2 -0
  116. package/vendor/heyspex-mcp/list-tools.mjs +1 -1
  117. package/vendor/heyspex-mcp/mcp-config.mjs +14 -1
  118. package/vendor/heyspex-mcp/memory-tools.mjs +523 -523
  119. package/vendor/heyspex-mcp/obligation-backstop.mjs +103 -0
  120. package/vendor/heyspex-mcp/occupied-keys.mjs +1 -0
  121. package/vendor/heyspex-mcp/on-deck-brief.mjs +19 -2
  122. package/vendor/heyspex-mcp/on-deck-scheduler.mjs +1708 -1708
  123. package/vendor/heyspex-mcp/plan-push.mjs +3 -2
  124. package/vendor/heyspex-mcp/preflight-gate.mjs +1 -0
  125. package/vendor/heyspex-mcp/procedure-handlers.mjs +327 -325
  126. package/vendor/heyspex-mcp/procedure-tools.mjs +1181 -1159
  127. package/vendor/heyspex-mcp/promote-capture.mjs +2 -0
  128. package/vendor/heyspex-mcp/promote-research.mjs +6 -0
  129. package/vendor/heyspex-mcp/read-path.mjs +162 -6
  130. package/vendor/heyspex-mcp/request-context.mjs +25 -1
  131. package/vendor/heyspex-mcp/research-handlers.mjs +6 -4
  132. package/vendor/heyspex-mcp/roadmap-default.mjs +70 -0
  133. package/vendor/heyspex-mcp/session-owner.mjs +3 -2
  134. package/vendor/heyspex-mcp/session-tools.mjs +10 -0
  135. package/vendor/heyspex-mcp/spec-edit-tools.mjs +8 -1
  136. package/vendor/heyspex-mcp/split-research.mjs +3 -0
  137. package/vendor/heyspex-mcp/submit-for-review.mjs +18 -1
  138. package/vendor/heyspex-mcp/summary-write-tools.mjs +5 -1
  139. package/vendor/heyspex-mcp/test-helpers.mjs +18 -3
  140. package/vendor/heyspex-mcp/tool-catalog.mjs +7 -1
  141. package/vendor/heyspex-mcp/tool-dispatch.mjs +18 -0
  142. package/vendor/heyspex-mcp/vault-io.mjs +720 -724
  143. package/vendor/heyspex-mcp/vault-resolve.mjs +197 -9
  144. package/vendor/heyspex-mcp/whoami.mjs +2 -1
  145. package/vendor/heyspex-mcp/write-outbox.mjs +512 -0
@@ -5,11 +5,26 @@ var __esm = (fn, res) => function __init() {
5
5
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
6
6
  };
7
7
 
8
+ // scripts/lib/heyspex-home.mjs
9
+ import { homedir } from "node:os";
10
+ function heyspexHome(env = process.env) {
11
+ const override = env?.HEYSPEX_HOME;
12
+ if (typeof override === "string" && override.trim().length > 0) {
13
+ return override.trim();
14
+ }
15
+ return homedir();
16
+ }
17
+ var init_heyspex_home = __esm({
18
+ "scripts/lib/heyspex-home.mjs"() {
19
+ "use strict";
20
+ }
21
+ });
22
+
8
23
  // vendor/heyspex-mcp/credentials.mjs
9
24
  import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
10
- import os, { homedir } from "node:os";
25
+ import os, { homedir as homedir2 } from "node:os";
11
26
  import { dirname as dirname2, join as join2, resolve } from "node:path";
12
- function credentialsFilePath(homeDir = homedir()) {
27
+ function credentialsFilePath(homeDir = heyspexHome()) {
13
28
  return join2(homeDir, ".heyspex", "credentials.yaml");
14
29
  }
15
30
  function parseMcpToken(raw) {
@@ -122,14 +137,14 @@ function readLegacyConfigAccountId(read, homeDir) {
122
137
  const value = raw?.match(CONFIG_ACCOUNT_ID_RE)?.[1]?.trim() ?? "";
123
138
  return value || null;
124
139
  }
125
- function readBearer({ env = process.env, homeDir = homedir(), readFile, accountId } = {}) {
140
+ function readBearer({ env = process.env, homeDir = heyspexHome(), readFile, accountId } = {}) {
126
141
  const read = readFile ?? ((p) => readFileSync(p, "utf8"));
127
142
  const credentialsText = readTextOrNull(read, credentialsFilePath(homeDir));
128
143
  const named = typeof accountId === "string" && accountId.trim() ? accountId.trim() : null;
129
144
  const legacyAccountId = named && parseCredentialsStore(credentialsText).schemaVersion === 1 ? readLegacyConfigAccountId(read, homeDir) : null;
130
145
  return resolveBearer({ envToken: env?.[MCP_TOKEN_ENV], credentialsText, accountId: named, legacyAccountId });
131
146
  }
132
- function readCurrentAccountId({ homeDir = homedir(), readFile } = {}) {
147
+ function readCurrentAccountId({ homeDir = heyspexHome(), readFile } = {}) {
133
148
  const read = readFile ?? ((p) => readFileSync(p, "utf8"));
134
149
  const store = parseCredentialsStore(readTextOrNull(read, credentialsFilePath(homeDir)));
135
150
  if (store.schemaVersion === 2 && store.currentAccountId && store.currentAccountId !== LEGACY_ACCOUNT_ID) {
@@ -142,6 +157,7 @@ var MCP_TOKEN_ENV, MCP_TOKEN_LINE_RE, CREDENTIALS_SCHEMA_VERSION, LEGACY_ACCOUNT
142
157
  var init_credentials = __esm({
143
158
  "vendor/heyspex-mcp/credentials.mjs"() {
144
159
  "use strict";
160
+ init_heyspex_home();
145
161
  MCP_TOKEN_ENV = "HEYSPEX_MCP_TOKEN";
146
162
  MCP_TOKEN_LINE_RE = /^mcp_token:[ \t]*["']?([^"'\r\n#]+)/m;
147
163
  CREDENTIALS_SCHEMA_VERSION = 2;
@@ -153,11 +169,11 @@ var init_credentials = __esm({
153
169
  });
154
170
 
155
171
  // scripts/lib/dev-mode.mjs
156
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync6, writeFileSync as writeFileSync3 } from "node:fs";
157
- import { homedir as homedir6 } from "node:os";
158
- import { join as join7 } from "node:path";
159
- function devModeFilePath(homeDir = homedir6()) {
160
- return join7(homeDir, ".heyspex", DEV_MODE_FILENAME);
172
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync4 } from "node:fs";
173
+ import { homedir as homedir7 } from "node:os";
174
+ import { join as join8 } from "node:path";
175
+ function devModeFilePath(homeDir = heyspexHome()) {
176
+ return join8(homeDir, ".heyspex", DEV_MODE_FILENAME);
161
177
  }
162
178
  function normalizeMode(raw) {
163
179
  const v = String(raw ?? "").trim().toLowerCase();
@@ -181,7 +197,7 @@ function deriveSemantics(mode, reliance) {
181
197
  vaultWriteMode: local ? "local" : "cloud"
182
198
  };
183
199
  }
184
- function readLocalDevModeRecord({ homeDir = homedir6(), readFile = defaultReadFile } = {}) {
200
+ function readLocalDevModeRecord({ homeDir = heyspexHome(), readFile = defaultReadFile } = {}) {
185
201
  let raw;
186
202
  try {
187
203
  raw = readFile(devModeFilePath(homeDir));
@@ -211,7 +227,7 @@ function readLocalDevModeRecord({ homeDir = homedir6(), readFile = defaultReadFi
211
227
  }
212
228
  function resolveDevMode({
213
229
  env = process.env,
214
- homeDir = homedir6(),
230
+ homeDir = heyspexHome(),
215
231
  readFile = defaultReadFile,
216
232
  cloudSetting = void 0
217
233
  } = {}) {
@@ -274,16 +290,17 @@ var CLOUD_CONSOLE_URL, LOCAL_CONSOLE_URL, DEV_MODE_FILENAME, defaultReadFile;
274
290
  var init_dev_mode = __esm({
275
291
  "scripts/lib/dev-mode.mjs"() {
276
292
  "use strict";
293
+ init_heyspex_home();
277
294
  init_credentials();
278
295
  CLOUD_CONSOLE_URL = "https://app.heyspex.com";
279
296
  LOCAL_CONSOLE_URL = "http://localhost:3000";
280
297
  DEV_MODE_FILENAME = "dev-mode.json";
281
- defaultReadFile = (p) => readFileSync6(p, "utf8");
298
+ defaultReadFile = (p) => readFileSync7(p, "utf8");
282
299
  }
283
300
  });
284
301
 
285
302
  // spex-console/bin/hs-claim.ts
286
- import { readFileSync as readFileSync8 } from "node:fs";
303
+ import { readFileSync as readFileSync9 } from "node:fs";
287
304
  import process3 from "node:process";
288
305
 
289
306
  // spex-console/src/lib/work-stages.ts
@@ -415,17 +432,19 @@ function hsCommand(args = "", options = {}) {
415
432
  }
416
433
 
417
434
  // vendor/heyspex-mcp/console-fetch.mjs
435
+ init_heyspex_home();
418
436
  init_credentials();
419
- import { readFileSync as readFileSync4 } from "node:fs";
420
- import { homedir as homedir4 } from "node:os";
421
- import { join as join5 } from "node:path";
437
+ import { readFileSync as readFileSync5 } from "node:fs";
438
+ import { homedir as homedir5 } from "node:os";
439
+ import { join as join6 } from "node:path";
422
440
 
423
441
  // vendor/heyspex-mcp/session-owner.mjs
442
+ init_heyspex_home();
424
443
  init_credentials();
425
444
  import { readFileSync as readFileSync2 } from "node:fs";
426
- import { homedir as homedir2 } from "node:os";
445
+ import { homedir as homedir3 } from "node:os";
427
446
  import { join as join3 } from "node:path";
428
- function resolveSessionOwnerUncached({ env = process.env, homeDir = homedir2(), readFile } = {}) {
447
+ function resolveSessionOwnerUncached({ env = process.env, homeDir = heyspexHome(), readFile } = {}) {
429
448
  const fromEnv = typeof env?.HS_ACCOUNT_ID === "string" ? env.HS_ACCOUNT_ID.trim() : "";
430
449
  if (fromEnv) return fromEnv;
431
450
  return readCurrentAccountId({ homeDir, readFile });
@@ -455,10 +474,26 @@ function isVaultLessEndpoint(method, path2) {
455
474
  });
456
475
  }
457
476
 
477
+ // vendor/heyspex-mcp/write-outbox.mjs
478
+ import {
479
+ readdirSync,
480
+ readFileSync as readFileSync3,
481
+ writeFileSync as writeFileSync2,
482
+ mkdirSync as mkdirSync2,
483
+ existsSync as existsSync2,
484
+ renameSync as renameSync2,
485
+ rmSync
486
+ } from "node:fs";
487
+ import { basename, join as join4, isAbsolute as isAbsolute2 } from "node:path";
488
+
489
+ // scripts/lib/shared-path-helpers.mjs
490
+ import { isAbsolute, resolve as resolve2, sep } from "node:path";
491
+
458
492
  // vendor/heyspex-mcp/vault-resolve.mjs
459
- import { existsSync as existsSync2, readFileSync as readFileSync3 } from "node:fs";
460
- import { homedir as homedir3, tmpdir } from "node:os";
461
- import { dirname as dirname3, join as join4, resolve as resolve2 } from "node:path";
493
+ init_heyspex_home();
494
+ import { existsSync as existsSync3, readFileSync as readFileSync4 } from "node:fs";
495
+ import { homedir as homedir4, tmpdir } from "node:os";
496
+ import { dirname as dirname3, join as join5, resolve as resolve3 } from "node:path";
462
497
 
463
498
  // vendor/heyspex-mcp/console-fetch.mjs
464
499
  var VAULT_NOT_REGISTERED = "VAULT_NOT_REGISTERED";
@@ -490,9 +525,9 @@ function isCloudVaultId(value) {
490
525
  var MARKER_VAULT_ID_RE = /^vault_id:[ \t]*["']?([^"'\r\n#]+)/m;
491
526
  function readMarkerVaultId(repoRootAbs, { readFile } = {}) {
492
527
  if (typeof repoRootAbs !== "string" || !repoRootAbs.trim()) return null;
493
- const read = readFile ?? ((p) => readFileSync4(p, "utf8"));
528
+ const read = readFile ?? ((p) => readFileSync5(p, "utf8"));
494
529
  try {
495
- const raw = read(join5(repoRootAbs, "heyspex.yaml"));
530
+ const raw = read(join6(repoRootAbs, "heyspex.yaml"));
496
531
  const value = String(raw ?? "").match(MARKER_VAULT_ID_RE)?.[1]?.trim() ?? "";
497
532
  return value || null;
498
533
  } catch {
@@ -512,9 +547,18 @@ var SCOPE_REFUSAL_CODES = Object.freeze(["VAULT_SCOPE_MISMATCH", "ACCOUNT_MISMAT
512
547
  init_credentials();
513
548
 
514
549
  // spex-console/src/lib/vault-registry/registry-file.ts
515
- import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync5, renameSync as renameSync2, writeFileSync as writeFileSync2 } from "node:fs";
516
- import { homedir as homedir5 } from "node:os";
517
- import { dirname as dirname4, join as join6, resolve as resolve3 } from "node:path";
550
+ import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync6, renameSync as renameSync3, writeFileSync as writeFileSync3 } from "node:fs";
551
+ import { dirname as dirname4, join as join7, resolve as resolve4 } from "node:path";
552
+
553
+ // spex-console/src/lib/heyspex-home.ts
554
+ import { homedir as homedir6 } from "node:os";
555
+ function heyspexHome2(env = process.env) {
556
+ const override = env?.HEYSPEX_HOME;
557
+ if (typeof override === "string" && override.trim().length > 0) {
558
+ return override.trim();
559
+ }
560
+ return homedir6();
561
+ }
518
562
 
519
563
  // spex-console/src/lib/vault-registry/types.ts
520
564
  var LEGACY_REGISTRY_ACCOUNT_ID = "legacy";
@@ -531,10 +575,10 @@ function emptyVaultRegistry() {
531
575
 
532
576
  // spex-console/src/lib/vault-registry/registry-file.ts
533
577
  function vaultRegistryDir(opts = {}) {
534
- return opts.registryDir ?? join6(homedir5(), ".heyspex");
578
+ return opts.registryDir ?? join7(heyspexHome2(), ".heyspex");
535
579
  }
536
580
  function vaultRegistryFilePath(opts = {}) {
537
- return join6(vaultRegistryDir(opts), "registry.json");
581
+ return join7(vaultRegistryDir(opts), "registry.json");
538
582
  }
539
583
  function isNonEmptyString(v) {
540
584
  return typeof v === "string" && v.trim().length > 0;
@@ -635,9 +679,9 @@ function parseVaultRegistryFile(json) {
635
679
  }
636
680
  function readRegistryJson(opts) {
637
681
  const filePath = vaultRegistryFilePath(opts);
638
- if (!existsSync3(filePath)) return { kind: "missing" };
682
+ if (!existsSync4(filePath)) return { kind: "missing" };
639
683
  try {
640
- const raw = readFileSync5(filePath, "utf8");
684
+ const raw = readFileSync6(filePath, "utf8");
641
685
  const json = JSON.parse(raw);
642
686
  if (registryFileSchemaOf(json) === null) return { kind: "unreadable" };
643
687
  return { kind: "ok", raw, json };
@@ -1199,10 +1243,11 @@ var HELP = [
1199
1243
  ].join("\n");
1200
1244
 
1201
1245
  // scripts/lib/console-url-resolver.mjs
1246
+ init_heyspex_home();
1202
1247
  init_dev_mode();
1203
- import { readFileSync as readFileSync7 } from "node:fs";
1204
- import { homedir as homedir7 } from "node:os";
1205
- import { join as join8 } from "node:path";
1248
+ import { readFileSync as readFileSync8 } from "node:fs";
1249
+ import { homedir as homedir8 } from "node:os";
1250
+ import { join as join9 } from "node:path";
1206
1251
  var DEFAULT_CONSOLE_URL = LOCAL_CONSOLE_URL;
1207
1252
  function trimTrailingSlash(url) {
1208
1253
  return url.replace(/\/+$/, "");
@@ -1228,9 +1273,9 @@ function warnStaleLoopbackCredentialsOnce(credentialsUrl, derivedUrl, { log }) {
1228
1273
  } catch {
1229
1274
  }
1230
1275
  }
1231
- function readCredentialsConsoleUrl({ homeDir = homedir7(), readFile = defaultReadFile2 } = {}) {
1276
+ function readCredentialsConsoleUrl({ homeDir = heyspexHome(), readFile = defaultReadFile2 } = {}) {
1232
1277
  try {
1233
- const raw = readFile(join8(homeDir, ".heyspex", "credentials.yaml"));
1278
+ const raw = readFile(join9(homeDir, ".heyspex", "credentials.yaml"));
1234
1279
  const match = String(raw ?? "").match(/^console_url:\s*["']?([^"'\r\n#]+)/m);
1235
1280
  const value = match?.[1]?.trim();
1236
1281
  return value && value.length > 0 ? trimTrailingSlash(value) : null;
@@ -1239,12 +1284,12 @@ function readCredentialsConsoleUrl({ homeDir = homedir7(), readFile = defaultRea
1239
1284
  }
1240
1285
  }
1241
1286
  function defaultReadFile2(p) {
1242
- return readFileSync7(p, "utf8");
1287
+ return readFileSync8(p, "utf8");
1243
1288
  }
1244
1289
  function readDiscoveryFileConsoleUrl(repoRoot, { readDiscovery: readDiscovery2 = defaultReadFile2 } = {}) {
1245
1290
  if (!repoRoot) return null;
1246
1291
  try {
1247
- const discovery = String(readDiscovery2(join8(repoRoot, ".heyspex", "console-url")) ?? "").trim();
1292
+ const discovery = String(readDiscovery2(join9(repoRoot, ".heyspex", "console-url")) ?? "").trim();
1248
1293
  if (discovery.length > 0) return trimTrailingSlash(discovery);
1249
1294
  } catch {
1250
1295
  }
@@ -1272,7 +1317,7 @@ function resolveModeEnvelope({ env, homeDir }) {
1272
1317
  function resolveConsoleUrl({
1273
1318
  repoRoot,
1274
1319
  env = process.env,
1275
- homeDir = homedir7(),
1320
+ homeDir = heyspexHome(),
1276
1321
  strict = false,
1277
1322
  devMode,
1278
1323
  log = (line) => process.stderr.write(line),
@@ -1366,7 +1411,7 @@ function runEntry(name, main2, options = {}) {
1366
1411
  // spex-console/bin/hs-claim.ts
1367
1412
  function readDiscovery(p) {
1368
1413
  try {
1369
- return readFileSync8(p, "utf-8");
1414
+ return readFileSync9(p, "utf-8");
1370
1415
  } catch {
1371
1416
  return null;
1372
1417
  }