heyspex 0.2.2 → 0.2.4
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.
- package/.claude-plugin/marketplace.json +2 -1
- package/README.md +11 -0
- package/bin/hs-vault-binding.mjs +157 -0
- package/bin/hs.mjs +83 -79
- package/bin/spexcode.mjs +91 -0
- package/dev-factory/engine/worktree.mjs +36 -7
- package/dev-factory/lib/epic-detect.mjs +2 -2
- package/dev-factory/lib/fleet-readiness.mjs +3 -5
- package/dev-factory/lib/fleet-state.mjs +2 -2
- package/dev-factory/lib/sufficiency-score.mjs +3 -5
- package/dist/cli/hs-check.mjs +76 -46
- package/dist/cli/hs-claim.mjs +63 -33
- package/dist/cli/hs-connect.mjs +520 -214
- package/dist/cli/hs-defer.mjs +161 -19
- package/dist/cli/hs-dev.mjs +11 -5
- package/dist/cli/hs-env.mjs +187 -161
- package/dist/cli/hs-index-rebuild.mjs +123 -78
- package/dist/cli/hs-index-reconcile.mjs +203 -107
- package/dist/cli/hs-init.mjs +426 -179
- package/dist/cli/hs-install.mjs +759 -437
- package/dist/cli/hs-join.mjs +590 -383
- package/dist/cli/hs-vault-pull.mjs +359 -254
- package/dist/cli/hs-vault-push.mjs +151 -113
- package/dist/cli/hs-vault.mjs +271 -104
- package/dist/cli/hs-workspace.mjs +90 -57
- package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +178 -91
- package/docs/copilot-plugin-install.md +200 -177
- package/docs/driving-heyspex-from-copilot.md +174 -165
- package/docs/mcp-client-config.md +93 -25
- package/package.json +257 -250
- package/plugins/heyspex/.claude-plugin/plugin.json +13 -12
- package/plugins/heyspex/.cursor-plugin/plugin.json +16 -15
- package/plugins/heyspex/.mcp.json +3 -4
- package/plugins/heyspex/README.md +323 -312
- package/plugins/heyspex/assets/heyspex-glyph-128.png +0 -0
- package/plugins/heyspex/assets/heyspex-glyph-256.png +0 -0
- package/plugins/heyspex/assets/heyspex-glyph.svg +12 -0
- package/plugins/heyspex/bin/launch-mcp.mjs +21 -7
- package/plugins/heyspex/mcp.json +12 -13
- package/scripts/check-mcp-freshness.mjs +6 -4
- package/scripts/claude-hooks/_intent-classifier-router.mjs +518 -456
- package/scripts/claude-hooks/intent-classifier-trigger.mjs +305 -279
- package/scripts/claude-hooks/research-method-guard.mjs +2 -2
- package/scripts/claude-hooks/wip-checkpoint.mjs +33 -9
- package/scripts/claude-statusline/fonts/HeySpexIcons.ttf +0 -0
- package/scripts/claude-statusline/statusline-command.mjs +1073 -0
- package/scripts/copilot-statusline.mjs +130 -0
- package/scripts/dev-server-status.mjs +3 -2
- package/scripts/dev-server-stop.mjs +3 -2
- package/scripts/hs-capture-cli.mjs +2 -2
- package/scripts/hs-settings.mjs +2 -2
- package/scripts/hs-view.mjs +3 -2
- package/scripts/install-copilot-hooks.mjs +152 -36
- package/scripts/lib/copilot-cli.mjs +108 -0
- package/scripts/lib/customer-kit.mjs +223 -30
- package/scripts/lib/dev-mode.mjs +28 -2
- package/scripts/lib/shared-path-helpers.mjs +32 -0
- package/scripts/lib/standalone-doctor.mjs +131 -32
- package/scripts/wip-ledger-health.mjs +3 -2
- package/spexharness/src/gates/vault-mirror-catchup.mjs +113 -24
- package/spexharness/src/gates/vault-mirror-catchup.runner.mjs +52 -0
- package/spexharness/src/intent-directive.mjs +839 -626
- package/spexharness/src/rule-table.mjs +1 -1
- package/vendor/heyspex-mcp/cli-verbs.mjs +16 -2
- package/vendor/heyspex-mcp/cli.mjs +20 -4
- package/vendor/heyspex-mcp/console-fetch.mjs +15 -3
- package/vendor/heyspex-mcp/dev-tools.mjs +11 -4
- package/vendor/heyspex-mcp/events-tools.mjs +1 -1
- package/vendor/heyspex-mcp/factory-run-status.mjs +42 -0
- package/vendor/heyspex-mcp/http-transport.mjs +6 -1
- package/vendor/heyspex-mcp/mcp-config.mjs +4 -2
- package/vendor/heyspex-mcp/server-identity.mjs +13 -0
- package/vendor/heyspex-mcp/spec-edit-tools.mjs +26 -1
- package/vendor/heyspex-mcp/test-helpers.mjs +5 -2
- package/vendor/heyspex-mcp/tool-catalog.mjs +12 -0
- package/vendor/heyspex-mcp/tool-dispatch.mjs +63 -23
- package/vendor/heyspex-mcp/usable-dir-env.mjs +82 -0
- package/vendor/heyspex-mcp/vault-binding.mjs +839 -0
- 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,
|
|
164
|
+
function readTextOrNull(read, path16) {
|
|
165
165
|
try {
|
|
166
|
-
const raw = read(
|
|
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(
|
|
219
|
-
const raw = String(
|
|
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,
|
|
223
|
+
function isVaultLessEndpoint(method, path16) {
|
|
224
224
|
const m = String(method || "GET").toUpperCase();
|
|
225
|
-
const pathname = pathnameOf(
|
|
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
|
|
275
|
-
import { homedir as
|
|
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
|
|
286
|
-
import { homedir as
|
|
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
|
|
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
|
|
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
|
|
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 (!
|
|
483
|
+
if (!existsSync5(filePath)) return { kind: "missing" };
|
|
450
484
|
try {
|
|
451
|
-
const raw =
|
|
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
|
|
488
|
-
import { homedir as
|
|
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) =>
|
|
654
|
+
defaultReadFile = (p) => readFileSync8(p, "utf8");
|
|
614
655
|
}
|
|
615
656
|
});
|
|
616
657
|
|
|
617
658
|
// scripts/lib/console-url-resolver.mjs
|
|
618
|
-
import { readFileSync as
|
|
619
|
-
import { homedir as
|
|
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
|
|
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
|
|
770
|
+
import path3 from "node:path";
|
|
730
771
|
function normalizeRepoRoot(p) {
|
|
731
|
-
let resolved =
|
|
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 (
|
|
741
|
-
const parent =
|
|
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
|
|
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) =>
|
|
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,
|
|
779
|
-
const scopeHeaders = http.scope ? http.scope.headersFor(method,
|
|
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}${
|
|
822
|
+
const res = await http.fetchImpl(`${http.consoleUrl}${path16}`, {
|
|
782
823
|
method,
|
|
783
824
|
headers: {
|
|
784
825
|
"content-type": "application/json",
|
|
@@ -1589,13 +1630,13 @@ function bareFileKeyOf(input) {
|
|
|
1589
1630
|
if (KNOWN_TYPE_LABELS.has(token)) return null;
|
|
1590
1631
|
return FILE_KEY_RE.test(token) ? token : null;
|
|
1591
1632
|
}
|
|
1592
|
-
function isEra3SpecId(id,
|
|
1633
|
+
function isEra3SpecId(id, basename3) {
|
|
1593
1634
|
const raw = String(id ?? "").trim();
|
|
1594
1635
|
if (!raw) return false;
|
|
1595
1636
|
if (parseSpecId(raw)?.era === 3) return true;
|
|
1596
1637
|
const fileKey = bareFileKeyOf(raw);
|
|
1597
1638
|
if (!fileKey) return false;
|
|
1598
|
-
const parsed = parseSpecId(
|
|
1639
|
+
const parsed = parseSpecId(basename3 ?? "");
|
|
1599
1640
|
return parsed?.era === 3 && (parsed.fileKey ?? "").toUpperCase() === fileKey;
|
|
1600
1641
|
}
|
|
1601
1642
|
var FILE_KEY_RE, KNOWN_TYPE_LABELS, RULED_FAMILY_SURNAMES, FAMILY_KEYED_TYPE_LABELS, FAMILY_KEY_SHAPE_RE;
|
|
@@ -1669,7 +1710,7 @@ var init_vault_shared = __esm({
|
|
|
1669
1710
|
// spex-console/src/lib/indexer/parser.ts
|
|
1670
1711
|
import { createHash } from "node:crypto";
|
|
1671
1712
|
import { promises as fs2 } from "node:fs";
|
|
1672
|
-
import
|
|
1713
|
+
import path5 from "node:path";
|
|
1673
1714
|
function normalizeWikilink2(raw) {
|
|
1674
1715
|
let t = raw.trim();
|
|
1675
1716
|
if (t.startsWith("[[") && t.endsWith("]]")) {
|
|
@@ -4568,9 +4609,9 @@ var init_satellite = __esm({
|
|
|
4568
4609
|
});
|
|
4569
4610
|
|
|
4570
4611
|
// spex-console/src/lib/vault-resolve/index.ts
|
|
4571
|
-
import { existsSync as
|
|
4612
|
+
import { existsSync as existsSync6, readFileSync as readFileSync12, realpathSync as realpathSync4, statSync as statSync4 } from "node:fs";
|
|
4572
4613
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
4573
|
-
import
|
|
4614
|
+
import path6 from "node:path";
|
|
4574
4615
|
var init_vault_resolve2 = __esm({
|
|
4575
4616
|
"spex-console/src/lib/vault-resolve/index.ts"() {
|
|
4576
4617
|
"use strict";
|
|
@@ -4607,8 +4648,8 @@ var init_resolve_status = __esm({
|
|
|
4607
4648
|
});
|
|
4608
4649
|
|
|
4609
4650
|
// spex-console/src/lib/vault-resolve/active.ts
|
|
4610
|
-
import { existsSync as
|
|
4611
|
-
import
|
|
4651
|
+
import { existsSync as existsSync7 } from "node:fs";
|
|
4652
|
+
import path7 from "node:path";
|
|
4612
4653
|
var ACTIVE_VAULT_CACHE_KEY, cacheStore;
|
|
4613
4654
|
var init_active = __esm({
|
|
4614
4655
|
"spex-console/src/lib/vault-resolve/active.ts"() {
|
|
@@ -4630,7 +4671,7 @@ var init_active = __esm({
|
|
|
4630
4671
|
|
|
4631
4672
|
// spex-console/src/lib/control-plane/statusline-focus-cache.ts
|
|
4632
4673
|
import fs3 from "node:fs";
|
|
4633
|
-
import
|
|
4674
|
+
import path8 from "node:path";
|
|
4634
4675
|
var init_statusline_focus_cache = __esm({
|
|
4635
4676
|
"spex-console/src/lib/control-plane/statusline-focus-cache.ts"() {
|
|
4636
4677
|
"use strict";
|
|
@@ -5247,10 +5288,10 @@ function trashPathFor(relPath, now) {
|
|
|
5247
5288
|
const normalized = relPath.split("\\").join("/");
|
|
5248
5289
|
const slashIdx = normalized.lastIndexOf("/");
|
|
5249
5290
|
const folder = slashIdx === -1 ? "" : normalized.slice(0, slashIdx);
|
|
5250
|
-
const
|
|
5291
|
+
const basename3 = slashIdx === -1 ? normalized : normalized.slice(slashIdx + 1);
|
|
5251
5292
|
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
5252
5293
|
const trashDir = folder ? `${folder}/.trash` : ".trash";
|
|
5253
|
-
return `${trashDir}/${stamp}-${
|
|
5294
|
+
return `${trashDir}/${stamp}-${basename3}`;
|
|
5254
5295
|
}
|
|
5255
5296
|
function materializeSpecMarkdown(bundle) {
|
|
5256
5297
|
return stringifySpecMarkdown(bundle.bodyText, bundle.frontmatter);
|
|
@@ -5372,10 +5413,10 @@ var init_export_status = __esm({
|
|
|
5372
5413
|
function isGitHubFailure(value) {
|
|
5373
5414
|
return typeof value === "object" && value !== null && "status" in value;
|
|
5374
5415
|
}
|
|
5375
|
-
async function githubJson(
|
|
5416
|
+
async function githubJson(path16, target, fetchImpl, init) {
|
|
5376
5417
|
let response;
|
|
5377
5418
|
try {
|
|
5378
|
-
response = await fetchImpl(`${GITHUB_API_BASE2}${
|
|
5419
|
+
response = await fetchImpl(`${GITHUB_API_BASE2}${path16}`, {
|
|
5379
5420
|
...init,
|
|
5380
5421
|
headers: {
|
|
5381
5422
|
...githubHeaders(target.token),
|
|
@@ -6104,7 +6145,7 @@ var init_diagnose_spawned = __esm({
|
|
|
6104
6145
|
|
|
6105
6146
|
// spex-console/src/lib/guardrail-naming.ts
|
|
6106
6147
|
import fs4 from "node:fs";
|
|
6107
|
-
import
|
|
6148
|
+
import path9 from "node:path";
|
|
6108
6149
|
var init_guardrail_naming = __esm({
|
|
6109
6150
|
"spex-console/src/lib/guardrail-naming.ts"() {
|
|
6110
6151
|
"use strict";
|
|
@@ -6114,7 +6155,7 @@ var init_guardrail_naming = __esm({
|
|
|
6114
6155
|
// spex-console/src/lib/indexer/indexer-service.ts
|
|
6115
6156
|
import { spawnSync } from "node:child_process";
|
|
6116
6157
|
import { promises as fs5 } from "node:fs";
|
|
6117
|
-
import
|
|
6158
|
+
import path10 from "node:path";
|
|
6118
6159
|
var init_indexer_service = __esm({
|
|
6119
6160
|
"spex-console/src/lib/indexer/indexer-service.ts"() {
|
|
6120
6161
|
"use strict";
|
|
@@ -6133,7 +6174,7 @@ var init_indexer_service = __esm({
|
|
|
6133
6174
|
|
|
6134
6175
|
// spex-console/src/lib/indexer/outbox-index-feeder.ts
|
|
6135
6176
|
import { promises as fs6 } from "node:fs";
|
|
6136
|
-
import
|
|
6177
|
+
import path11 from "node:path";
|
|
6137
6178
|
var init_outbox_index_feeder = __esm({
|
|
6138
6179
|
"spex-console/src/lib/indexer/outbox-index-feeder.ts"() {
|
|
6139
6180
|
"use strict";
|
|
@@ -6331,7 +6372,7 @@ var init_list_filter = __esm({
|
|
|
6331
6372
|
});
|
|
6332
6373
|
|
|
6333
6374
|
// spex-console/src/lib/specs/list-query.ts
|
|
6334
|
-
import
|
|
6375
|
+
import path12 from "node:path";
|
|
6335
6376
|
var init_list_query = __esm({
|
|
6336
6377
|
"spex-console/src/lib/specs/list-query.ts"() {
|
|
6337
6378
|
"use strict";
|
|
@@ -6374,7 +6415,7 @@ var init_pipeline_neighborhood = __esm({
|
|
|
6374
6415
|
});
|
|
6375
6416
|
|
|
6376
6417
|
// spex-console/src/lib/specs/spec-by-id.ts
|
|
6377
|
-
import
|
|
6418
|
+
import path13 from "node:path";
|
|
6378
6419
|
var init_spec_by_id = __esm({
|
|
6379
6420
|
"spex-console/src/lib/specs/spec-by-id.ts"() {
|
|
6380
6421
|
"use strict";
|
|
@@ -6431,9 +6472,9 @@ var init_search_body_hit = __esm({
|
|
|
6431
6472
|
|
|
6432
6473
|
// spex-console/src/lib/vault.ts
|
|
6433
6474
|
import { spawn } from "node:child_process";
|
|
6434
|
-
import { readdirSync as readdirSync2, readFileSync as
|
|
6475
|
+
import { readdirSync as readdirSync2, readFileSync as readFileSync13, statSync as statSync5 } from "node:fs";
|
|
6435
6476
|
import { promises as fs7 } from "node:fs";
|
|
6436
|
-
import
|
|
6477
|
+
import path14 from "node:path";
|
|
6437
6478
|
import yaml3 from "js-yaml";
|
|
6438
6479
|
var import_gray_matter3, VAULT_CACHE_TTL_WATCHED_MS, VAULT_CACHE_KEY, vaultCacheStore, VAULT_CACHE_DELTA_LISTENERS_KEY, vaultCacheDeltaListeners, SEARCH_TEXT_KEY, searchTextStore, VAULT_SNAPSHOT_KEY, vaultSnapshotStore;
|
|
6439
6480
|
var init_vault = __esm({
|
|
@@ -6551,9 +6592,9 @@ var init_vault = __esm({
|
|
|
6551
6592
|
|
|
6552
6593
|
// spex-console/bin/hs-index-rebuild.ts
|
|
6553
6594
|
import { execSync } from "node:child_process";
|
|
6554
|
-
import { appendFileSync, mkdirSync as
|
|
6595
|
+
import { appendFileSync, mkdirSync as mkdirSync7, readFileSync as readFileSync15 } from "node:fs";
|
|
6555
6596
|
import { promises as fs10 } from "node:fs";
|
|
6556
|
-
import
|
|
6597
|
+
import path15 from "node:path";
|
|
6557
6598
|
import process4 from "node:process";
|
|
6558
6599
|
|
|
6559
6600
|
// spex-console/src/lib/cli/control-shared.ts
|
|
@@ -6563,14 +6604,14 @@ init_credentials();
|
|
|
6563
6604
|
init_session_owner();
|
|
6564
6605
|
init_vault_less_endpoints();
|
|
6565
6606
|
init_registry_file();
|
|
6566
|
-
import
|
|
6607
|
+
import path2 from "node:path";
|
|
6567
6608
|
var VAULT_ID_HEADER = "x-heyspex-vault-id";
|
|
6568
6609
|
var ACCOUNT_ID_HEADER = "x-heyspex-account-id";
|
|
6569
|
-
function scopeHeadersFor(scope, method,
|
|
6610
|
+
function scopeHeadersFor(scope, method, path16) {
|
|
6570
6611
|
if (scope === "none") {
|
|
6571
|
-
if (!isVaultLessEndpoint(method,
|
|
6612
|
+
if (!isVaultLessEndpoint(method, path16)) {
|
|
6572
6613
|
throw new Error(
|
|
6573
|
-
`controlRequest: scope "none" is only allowed for the vault-less endpoints (${VAULT_LESS_ENDPOINTS.join(", ")}); ${method.toUpperCase()} ${
|
|
6614
|
+
`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 }.`
|
|
6574
6615
|
);
|
|
6575
6616
|
}
|
|
6576
6617
|
return {};
|
|
@@ -6581,7 +6622,7 @@ function cloudRequestScope(scope) {
|
|
|
6581
6622
|
const named = { accountId: scope.accountId, vaultId: scope.vaultId };
|
|
6582
6623
|
return {
|
|
6583
6624
|
...named,
|
|
6584
|
-
headersFor: (method,
|
|
6625
|
+
headersFor: (method, path16) => isVaultLessEndpoint(method, path16) ? {} : scopeHeadersFor(named, method, path16)
|
|
6585
6626
|
};
|
|
6586
6627
|
}
|
|
6587
6628
|
|
|
@@ -6624,7 +6665,7 @@ init_console_fetch();
|
|
|
6624
6665
|
init_registry_file();
|
|
6625
6666
|
init_repo_identity();
|
|
6626
6667
|
import { promises as fs } from "node:fs";
|
|
6627
|
-
import
|
|
6668
|
+
import path4 from "node:path";
|
|
6628
6669
|
|
|
6629
6670
|
// spex-console/src/lib/cli/init.ts
|
|
6630
6671
|
init_console_url_resolver();
|
|
@@ -6661,12 +6702,15 @@ var HELP2 = [
|
|
|
6661
6702
|
"(spex-console/src/lib/cli/template-manifest.ts) \u2014 universal docs",
|
|
6662
6703
|
"copied verbatim, template-shape docs written as author-prompt skeletons \u2014",
|
|
6663
6704
|
"plus a generated CLAUDE.md, the kept-principles index, and the template_version",
|
|
6664
|
-
"pin; with --git, one initial `git init` + commit.
|
|
6665
|
-
"holds heyspex.yaml
|
|
6666
|
-
"
|
|
6667
|
-
"
|
|
6668
|
-
"
|
|
6669
|
-
"
|
|
6705
|
+
"pin; with --git, one initial `git init` + commit. On an EXISTING vault (<dir>",
|
|
6706
|
+
"holds heyspex.yaml with a vault_id) it is a REFRESH \u2014 the repair `hs doctor`'s",
|
|
6707
|
+
"vault-template row names: only missing shipped files are added, template_version",
|
|
6708
|
+
"is written/updated in heyspex.yaml (every other byte and the vault_id kept),",
|
|
6709
|
+
"nothing existing is ever overwritten (an existing CLAUDE.md gets a",
|
|
6710
|
+
"CLAUDE.md.template beside it), the result lists each manifest row as created or",
|
|
6711
|
+
"kept, and a second run writes nothing. <dir> may be any path (a satellite repo",
|
|
6712
|
+
"names its vault, e.g. `hs init --customer-vault ../my-specs`). Refuses only a",
|
|
6713
|
+
"non-empty <dir> that has no heyspex.yaml. See init.customer-vault.ts.",
|
|
6670
6714
|
"",
|
|
6671
6715
|
"Flags:",
|
|
6672
6716
|
" --console-url <url> console_url value (default: the mode-aware console --",
|
|
@@ -6739,7 +6783,7 @@ async function resolveSyncVaultTargetFromEnv(deps) {
|
|
|
6739
6783
|
let markerVaultId = null;
|
|
6740
6784
|
try {
|
|
6741
6785
|
markerVaultId = parseVaultId(
|
|
6742
|
-
await fs.readFile(
|
|
6786
|
+
await fs.readFile(path4.join(deps.vaultRoot, "heyspex.yaml"), "utf8")
|
|
6743
6787
|
);
|
|
6744
6788
|
} catch {
|
|
6745
6789
|
markerVaultId = null;
|
|
@@ -6941,16 +6985,17 @@ async function runReindex(input) {
|
|
|
6941
6985
|
init_validator();
|
|
6942
6986
|
|
|
6943
6987
|
// spex-console/src/lib/vault-sync/pull-io.ts
|
|
6944
|
-
import { promises as fs9 } from "node:fs";
|
|
6988
|
+
import { promises as fs9, readFileSync as readFileSync14 } from "node:fs";
|
|
6989
|
+
import { EOL } from "node:os";
|
|
6945
6990
|
import nodePath2 from "node:path";
|
|
6946
6991
|
|
|
6947
6992
|
// spex-console/src/lib/dev-mode.ts
|
|
6948
6993
|
init_heyspex_home2();
|
|
6949
6994
|
init_credentials();
|
|
6950
|
-
import { mkdirSync as
|
|
6995
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "node:fs";
|
|
6951
6996
|
import { join as join10 } from "node:path";
|
|
6952
6997
|
var CLOUD_CONSOLE_URL2 = "https://app.heyspex.com";
|
|
6953
|
-
var defaultReadFile3 = (p) =>
|
|
6998
|
+
var defaultReadFile3 = (p) => readFileSync11(p, "utf8");
|
|
6954
6999
|
function readCredentialsMcpToken({
|
|
6955
7000
|
homeDir = heyspexHome2(),
|
|
6956
7001
|
readFile = defaultReadFile3
|
|
@@ -7100,16 +7145,16 @@ function currentGitHead(vaultRoot2) {
|
|
|
7100
7145
|
}
|
|
7101
7146
|
}
|
|
7102
7147
|
function appendJournal(vaultRoot2, message) {
|
|
7103
|
-
const heyspexDir =
|
|
7104
|
-
|
|
7105
|
-
const logPath =
|
|
7148
|
+
const heyspexDir = path15.join(vaultRoot2, ".heyspex");
|
|
7149
|
+
mkdirSync7(heyspexDir, { recursive: true });
|
|
7150
|
+
const logPath = path15.join(heyspexDir, "index-rebuild.log");
|
|
7106
7151
|
const ts = (/* @__PURE__ */ new Date()).toISOString();
|
|
7107
7152
|
appendFileSync(logPath, `[${ts}] ${message}
|
|
7108
7153
|
`, "utf-8");
|
|
7109
7154
|
}
|
|
7110
7155
|
function readDiscovery(p) {
|
|
7111
7156
|
try {
|
|
7112
|
-
return
|
|
7157
|
+
return readFileSync15(p, "utf-8");
|
|
7113
7158
|
} catch {
|
|
7114
7159
|
return null;
|
|
7115
7160
|
}
|
|
@@ -7121,7 +7166,7 @@ function resolveConsole(args) {
|
|
|
7121
7166
|
}
|
|
7122
7167
|
async function loadCrosswalk(vaultRoot2) {
|
|
7123
7168
|
try {
|
|
7124
|
-
const raw = await fs10.readFile(
|
|
7169
|
+
const raw = await fs10.readFile(path15.join(vaultRoot2, ".heyspex", "id-crosswalk.json"), "utf8");
|
|
7125
7170
|
const parsed = JSON.parse(raw);
|
|
7126
7171
|
return Array.isArray(parsed) ? parsed : [];
|
|
7127
7172
|
} catch {
|
|
@@ -7129,10 +7174,10 @@ async function loadCrosswalk(vaultRoot2) {
|
|
|
7129
7174
|
}
|
|
7130
7175
|
}
|
|
7131
7176
|
async function walkLocal(args) {
|
|
7132
|
-
const specsDir =
|
|
7177
|
+
const specsDir = path15.join(args.vaultRoot, "specs");
|
|
7133
7178
|
const files = [];
|
|
7134
7179
|
for await (const file of fs10.glob("**/*.md", { cwd: specsDir })) {
|
|
7135
|
-
files.push(
|
|
7180
|
+
files.push(path15.join(specsDir, file));
|
|
7136
7181
|
}
|
|
7137
7182
|
files.sort();
|
|
7138
7183
|
const specs2 = [];
|
|
@@ -7140,10 +7185,10 @@ async function walkLocal(args) {
|
|
|
7140
7185
|
for (const abs of files) {
|
|
7141
7186
|
try {
|
|
7142
7187
|
const content = await fs10.readFile(abs, "utf8");
|
|
7143
|
-
const relPath =
|
|
7188
|
+
const relPath = path15.relative(args.vaultRoot, abs).split(path15.sep).join("/");
|
|
7144
7189
|
const parsed = parseSpecFromContent(content, {
|
|
7145
7190
|
relPath,
|
|
7146
|
-
basenameFallback:
|
|
7191
|
+
basenameFallback: path15.basename(abs).replace(/\.md$/i, "")
|
|
7147
7192
|
});
|
|
7148
7193
|
specs2.push({ relPath, content, parsed });
|
|
7149
7194
|
if (args.verbose) say(args, ` parsed ${relPath}
|