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
@@ -83,13 +83,27 @@ if (!entry) {
83
83
  process.exit(1);
84
84
  }
85
85
 
86
- // The guessed "grandparent of vendor/heyspex-mcp" vault root only makes sense
87
- // for a source checkout, where that directory IS the vault. For the packaged
88
- // entry it resolves to node_modules/heyspex, which is never the customer's
89
- // vault — leave HEYSPEX_VAULT_ROOT alone in that case and let the server's own
90
- // multi-tier vault resolver (vault-resolve.mjs) find the real one.
91
- if (!process.env.HEYSPEX_VAULT_ROOT && entry !== packagedEntry) {
92
- process.env.HEYSPEX_VAULT_ROOT = resolve(entry, "../../..");
86
+ // No HEYSPEX_VAULT_ROOT guess here (HS-TYJA, owner ruling 2026-10-14). It used
87
+ // to pin the "grandparent of vendor/heyspex-mcp" for a source checkout, which
88
+ // since the repo split is the CODE repo, not a vault. HEYSPEX_VAULT_ROOT is now
89
+ // a true override above the cwd walk, so a guess would beat the repo's own
90
+ // heyspex.yaml `vault:` binding. The server's resolver (vault-resolve.mjs)
91
+ // finds the vault from the folder it was launched in.
92
+
93
+ // HS-C0NW: hosts that do not expand `${CLAUDE_PROJECT_DIR}` in a manifest `env` block (GitHub
94
+ // Copilot CLI) hand the server the literal text. Drop HEYSPEX_VAULT_ROOT / CLAUDE_PROJECT_DIR /
95
+ // CURSOR_PROJECT_DIR when they hold an unexpanded placeholder, a relative path or a missing dir,
96
+ // so the server's resolver falls through to the folder it was launched in. The check lives in
97
+ // the server tree (one helper shared with vault-resolve.mjs), next to the entry we just found.
98
+ // A HEYSPEX_VAULT_ROOT naming an absolute path that does not exist locally is kept: it may be a
99
+ // registered cloud-reliance vault, which the resolver validates itself.
100
+ try {
101
+ const { scrubUnusableDirEnv } = await import(
102
+ pathToFileURL(resolve(dirname(entry), "usable-dir-env.mjs")).href
103
+ );
104
+ scrubUnusableDirEnv(process.env, { requireExisting: { HEYSPEX_VAULT_ROOT: false } });
105
+ } catch {
106
+ // Older server tree without the helper: its own resolver is the only line of defence.
93
107
  }
94
108
 
95
109
  await import(pathToFileURL(entry).href);
@@ -1,13 +1,12 @@
1
- {
2
- "_comment": "Cursor plugin MCP declaration (HS-2HII). Boots through the plugin's own bin/launch-mcp.mjs, the same launcher .mcp.json uses for Claude Code. Cursor expands ${CURSOR_PLUGIN_ROOT} to the plugin's install path in command/args/env/cwd (cursor.com/docs/reference/plugins), so this works from a plain `npm install heyspex`: the launcher resolves node_modules/heyspex first, then CURSOR_PROJECT_DIR and the other source-checkout fallbacks. Never point this at vendor/heyspex-mcp/cli.mjs directly: that path exists only inside the platform checkout.",
3
- "mcpServers": {
4
- "heyspex": {
5
- "type": "stdio",
6
- "command": "node",
7
- "args": ["${CURSOR_PLUGIN_ROOT}/bin/launch-mcp.mjs"],
8
- "env": {
9
- "HEYSPEX_VAULT_ROOT": "${workspaceFolder}"
10
- }
11
- }
12
- }
13
- }
1
+ {
2
+ "_comment": "Cursor plugin MCP declaration (HS-2HII). Boots through the plugin's own bin/launch-mcp.mjs, the same launcher .mcp.json uses for Claude Code. Cursor expands ${CURSOR_PLUGIN_ROOT} to the plugin's install path in command/args/env/cwd (cursor.com/docs/reference/plugins), so this works from a plain `npm install heyspex`: the launcher resolves node_modules/heyspex first, then CURSOR_PROJECT_DIR and the other source-checkout fallbacks. Never point this at vendor/heyspex-mcp/cli.mjs directly: that path exists only inside the platform checkout. No HEYSPEX_VAULT_ROOT pin (HS-TYJA, owner ruling 2026-10-14): the server resolves its vault from the folder it is launched in (a heyspex.yaml vault: binding or a vault checkout); a pin here would override every repo binding.",
3
+ "mcpServers": {
4
+ "heyspex": {
5
+ "type": "stdio",
6
+ "command": "node",
7
+ "args": [
8
+ "${CURSOR_PLUGIN_ROOT}/bin/launch-mcp.mjs"
9
+ ]
10
+ }
11
+ }
12
+ }
@@ -48,7 +48,8 @@
48
48
  import { createHash } from 'node:crypto';
49
49
  import fs from 'node:fs';
50
50
  import path from 'node:path';
51
- import { fileURLToPath, pathToFileURL } from 'node:url';
51
+ import { fileURLToPath } from 'node:url';
52
+ import { isMainModule } from './lib/shared-path-helpers.mjs';
52
53
 
53
54
  function defaultVaultRoot() {
54
55
  // Honor the same override the hs CLI / dev-server-status.mjs use; otherwise
@@ -342,8 +343,9 @@ export function checkFreshness({ vaultRoot, vendorDir, buildFile, buildsDir, pid
342
343
  status: 'unknown',
343
344
  message:
344
345
  'heyspex MCP server freshness: unknown freshness (no build record at ' +
345
- '.heyspex/mcp-server-build.json — the running server predates the freshness ' +
346
- 'handshake, or the file is missing/corrupt). Restart the server to establish one.',
346
+ '.heyspex/mcp-server-build.json — no HeySpex MCP server has started for this vault yet; ' +
347
+ 'the record is written at server start. If one is running, it predates the freshness ' +
348
+ 'handshake or the file is missing/corrupt — restart it to establish one).',
347
349
  scope,
348
350
  current,
349
351
  recorded: null,
@@ -366,7 +368,7 @@ export function checkFreshness({ vaultRoot, vendorDir, buildFile, buildsDir, pid
366
368
 
367
369
  // ---- CLI entrypoint --------------------------------------------------------
368
370
 
369
- const invokedDirectly = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;
371
+ const invokedDirectly = isMainModule(import.meta.url);
370
372
  if (invokedDirectly) {
371
373
  const argv = process.argv.slice(2);
372
374
  const asJson = argv.includes('--json');