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.
Files changed (79) hide show
  1. package/.claude-plugin/marketplace.json +2 -1
  2. package/README.md +11 -0
  3. package/bin/hs-vault-binding.mjs +157 -0
  4. package/bin/hs.mjs +83 -79
  5. package/bin/spexcode.mjs +91 -0
  6. package/dev-factory/engine/worktree.mjs +36 -7
  7. package/dev-factory/lib/epic-detect.mjs +2 -2
  8. package/dev-factory/lib/fleet-readiness.mjs +3 -5
  9. package/dev-factory/lib/fleet-state.mjs +2 -2
  10. package/dev-factory/lib/sufficiency-score.mjs +3 -5
  11. package/dist/cli/hs-check.mjs +76 -46
  12. package/dist/cli/hs-claim.mjs +63 -33
  13. package/dist/cli/hs-connect.mjs +520 -214
  14. package/dist/cli/hs-defer.mjs +161 -19
  15. package/dist/cli/hs-dev.mjs +11 -5
  16. package/dist/cli/hs-env.mjs +187 -161
  17. package/dist/cli/hs-index-rebuild.mjs +123 -78
  18. package/dist/cli/hs-index-reconcile.mjs +203 -107
  19. package/dist/cli/hs-init.mjs +426 -179
  20. package/dist/cli/hs-install.mjs +759 -437
  21. package/dist/cli/hs-join.mjs +590 -383
  22. package/dist/cli/hs-vault-pull.mjs +359 -254
  23. package/dist/cli/hs-vault-push.mjs +151 -113
  24. package/dist/cli/hs-vault.mjs +271 -104
  25. package/dist/cli/hs-workspace.mjs +90 -57
  26. package/dist/cli-templates/customer-vault/specs/protocols/session-close-protocol.md +178 -91
  27. package/docs/copilot-plugin-install.md +200 -177
  28. package/docs/driving-heyspex-from-copilot.md +174 -165
  29. package/docs/mcp-client-config.md +93 -25
  30. package/package.json +257 -250
  31. package/plugins/heyspex/.claude-plugin/plugin.json +13 -12
  32. package/plugins/heyspex/.cursor-plugin/plugin.json +16 -15
  33. package/plugins/heyspex/.mcp.json +3 -4
  34. package/plugins/heyspex/README.md +323 -312
  35. package/plugins/heyspex/assets/heyspex-glyph-128.png +0 -0
  36. package/plugins/heyspex/assets/heyspex-glyph-256.png +0 -0
  37. package/plugins/heyspex/assets/heyspex-glyph.svg +12 -0
  38. package/plugins/heyspex/bin/launch-mcp.mjs +21 -7
  39. package/plugins/heyspex/mcp.json +12 -13
  40. package/scripts/check-mcp-freshness.mjs +6 -4
  41. package/scripts/claude-hooks/_intent-classifier-router.mjs +518 -456
  42. package/scripts/claude-hooks/intent-classifier-trigger.mjs +305 -279
  43. package/scripts/claude-hooks/research-method-guard.mjs +2 -2
  44. package/scripts/claude-hooks/wip-checkpoint.mjs +33 -9
  45. package/scripts/claude-statusline/fonts/HeySpexIcons.ttf +0 -0
  46. package/scripts/claude-statusline/statusline-command.mjs +1073 -0
  47. package/scripts/copilot-statusline.mjs +130 -0
  48. package/scripts/dev-server-status.mjs +3 -2
  49. package/scripts/dev-server-stop.mjs +3 -2
  50. package/scripts/hs-capture-cli.mjs +2 -2
  51. package/scripts/hs-settings.mjs +2 -2
  52. package/scripts/hs-view.mjs +3 -2
  53. package/scripts/install-copilot-hooks.mjs +152 -36
  54. package/scripts/lib/copilot-cli.mjs +108 -0
  55. package/scripts/lib/customer-kit.mjs +223 -30
  56. package/scripts/lib/dev-mode.mjs +28 -2
  57. package/scripts/lib/shared-path-helpers.mjs +32 -0
  58. package/scripts/lib/standalone-doctor.mjs +131 -32
  59. package/scripts/wip-ledger-health.mjs +3 -2
  60. package/spexharness/src/gates/vault-mirror-catchup.mjs +113 -24
  61. package/spexharness/src/gates/vault-mirror-catchup.runner.mjs +52 -0
  62. package/spexharness/src/intent-directive.mjs +839 -626
  63. package/spexharness/src/rule-table.mjs +1 -1
  64. package/vendor/heyspex-mcp/cli-verbs.mjs +16 -2
  65. package/vendor/heyspex-mcp/cli.mjs +20 -4
  66. package/vendor/heyspex-mcp/console-fetch.mjs +15 -3
  67. package/vendor/heyspex-mcp/dev-tools.mjs +11 -4
  68. package/vendor/heyspex-mcp/events-tools.mjs +1 -1
  69. package/vendor/heyspex-mcp/factory-run-status.mjs +42 -0
  70. package/vendor/heyspex-mcp/http-transport.mjs +6 -1
  71. package/vendor/heyspex-mcp/mcp-config.mjs +4 -2
  72. package/vendor/heyspex-mcp/server-identity.mjs +13 -0
  73. package/vendor/heyspex-mcp/spec-edit-tools.mjs +26 -1
  74. package/vendor/heyspex-mcp/test-helpers.mjs +5 -2
  75. package/vendor/heyspex-mcp/tool-catalog.mjs +12 -0
  76. package/vendor/heyspex-mcp/tool-dispatch.mjs +63 -23
  77. package/vendor/heyspex-mcp/usable-dir-env.mjs +82 -0
  78. package/vendor/heyspex-mcp/vault-binding.mjs +839 -0
  79. package/vendor/heyspex-mcp/vault-resolve.mjs +353 -245
@@ -1,177 +1,200 @@
1
- # Installing the HeySpex (SpexCode) plugin in GitHub Copilot CLI
2
-
3
- Instructions written to be handed verbatim to a GitHub Copilot CLI agent. Follow the steps in
4
- order and stop at any step that fails, reporting the exact output.
5
-
6
- This guide is for a team that installs only the `heyspex` npm package. The heyspex-app repository
7
- is not needed and is not available to customers.
8
-
9
- Source of truth for the Copilot commands and file layout:
10
- <https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference>.
11
- Hook behaviour under Copilot: <https://docs.github.com/en/copilot/reference/hooks-configuration>.
12
- Both pages were read on 2026-10-16. The plugin itself is documented in `node_modules/heyspex/plugins/heyspex/README.md`.
13
-
14
- ## 0. The short version
15
-
16
- From the root of your repo, after `npm install heyspex`:
17
-
18
- ```bash
19
- npx heyspex setup copilot # plugin route (Copilot CLI): registers the marketplace and installs the plugin
20
- npx heyspex setup copilot --hooks # hooks route (Copilot cloud agent / no plugin): writes .github/hooks/heyspex.json
21
- npx heyspex setup copilot --check # which route is active; warns if both are
22
- npx heyspex setup copilot --uninstall
23
- ```
24
-
25
- To have an agent do it, paste it the output of `npx heyspex setup copilot --print` (this document,
26
- preceded by the exact next command). If `copilot` is not on PATH, the plugin route prints the two
27
- commands to run instead. Pick ONE route, never both. The manual commands below remain the fallback.
28
-
29
- ## 1. Prerequisites
30
-
31
- The heyspex-app repository is not required and is not available to customers. Everything below
32
- works from the published npm package `heyspex` (or a tarball your HeySpex contact hands you), which
33
- carries the plugin, the marketplace manifest, the hooks and the MCP server.
34
-
35
- - Node.js 20 or newer on PATH (`node --version`).
36
- - GitHub Copilot CLI installed and signed in (`copilot --version`).
37
- - A git repo of your own (the one you want governed). From its root, install the package:
38
-
39
- ```bash
40
- npm install heyspex
41
- # or, from a tarball you were given:
42
- npm install ./heyspex-0.2.0.tgz
43
- ```
44
-
45
- - Sign the machine in to the HeySpex console so hooks and MCP tools can reach the vault:
46
-
47
- ```bash
48
- npx hs login
49
- ```
50
-
51
- ## 2. Pick ONE: the plugin or the repo hooks (never both)
52
-
53
- Copilot reads hooks from an installed plugin and from `.github/hooks/` in the repo. With both,
54
- every hook runs twice. Choose one.
55
-
56
- **Option A: the plugin (recommended).** One command registers the marketplace shipped inside the
57
- package and installs the plugin:
58
-
59
- ```bash
60
- npx heyspex setup copilot
61
- ```
62
-
63
- (`npx hs install --target . --copilot-plugin-apply` does the same.) By hand, the equivalent Copilot commands are:
64
-
65
- ```bash
66
- copilot plugin marketplace add ./node_modules/heyspex
67
- copilot plugin install heyspex@heyspex-marketplace
68
- copilot plugin list
69
- ```
70
-
71
- `./node_modules/heyspex/.claude-plugin/marketplace.json` is a Claude-format marketplace named
72
- `heyspex-marketplace`; its plugin `source` (`./plugins/heyspex`) resolves inside the package.
73
- `npx hs install --target . --copilot-plugin` (no `-apply`) only prints these commands.
74
-
75
- **Option B: repo hooks, for teammates and the Copilot cloud agent.** Writes
76
- `.github/hooks/heyspex.json` into your repo; commit it. Each command runs
77
- `node_modules/heyspex/scripts/claude-hooks/_run.mjs` and exits 0 if the package is not installed,
78
- so a checkout without `npm install` is never blocked.
79
-
80
- ```bash
81
- npx heyspex setup copilot --hooks
82
- ```
83
-
84
- (`npx hs install --target . --copilot-hooks` does the same.) `setup copilot --hooks` refuses when the plugin is already installed. If you pass `--copilot-hooks` together with `--copilot-plugin[-apply]`, the installer warns and
85
- skips the hooks file.
86
-
87
- Then restart the Copilot session (`/restart`) so hooks load, and verify:
88
-
89
- ```bash
90
- copilot plugin list # Option A: heyspex is enabled
91
- npx hs doctor # MCP, hooks and account surfaces healthy
92
- ```
93
-
94
- ## 3. What the plugin loads
95
-
96
- | Component | Source | Behaviour under Copilot |
97
- | --- | --- | --- |
98
- | Hooks | `node_modules/heyspex/plugins/heyspex/hooks/hooks.json` | PreToolUse, PostToolUse, Stop, UserPromptSubmit and SessionStart gates. Every command locates the runtime itself and exits 0 if it cannot, so a missing variable never denies a tool call. A real deny arrives as a top-level `permissionDecision` with a reason. |
99
- | MCP server | `node_modules/heyspex/plugins/heyspex/.mcp.json` | The `heyspex_*` vault tools and `hs-*` prompts. |
100
- | Slash commands | not loaded | Claude Code commands are not a Copilot component. Use MCP prompts or the `hs` CLI. |
101
-
102
- ## 4. Verify the install
103
-
104
- 1. In a Copilot session inside any repo, run a harmless tool call, for example read a file. It
105
- must succeed. A message containing "Denied by preToolUse hook" means a hook failed; go to
106
- section 7.
107
- 2. Confirm the MCP server is up by listing MCP servers in Copilot (`/mcp`) and calling
108
- `heyspex_recall_memories` with `{ "limit": 3 }`. If the server is missing, go to section 7.
109
- 3. Confirm the gates work: send a prompt that contains a new product idea of more than 60
110
- characters, then try to edit a source file without capturing. The edit should be refused with a
111
- reason that names `directive-obligation-gate`. Call `heyspex_update_capture` with the prompt
112
- text, then retry the edit. It should pass.
113
-
114
- ## 5. Turning HeySpex off and on
115
-
116
- Run from the repo you are working in:
117
-
118
- ```bash
119
- hs mode status # on | off, and why
120
- hs mode off # every hook exits 0 immediately, no restart needed
121
- hs mode on
122
- hs mode toggle
123
- ```
124
-
125
- Use `npx hs mode off` when `hs` is not on PATH. The switch writes
126
- `.heyspex/mode.json` in the project and is git-ignored.
127
-
128
- Per-shell variants that touch no files:
129
-
130
- | Variable | Effect |
131
- | --- | --- |
132
- | `HEYSPEX_MODE=off` | Silences hooks for every harness in that shell |
133
- | `HEYSPEX_COPILOT_HOOKS_OFF=1` | Silences hooks only when the caller is Copilot; Claude Code and Cursor keep theirs |
134
-
135
- The config twin of the Copilot switch is `agent_behaviors.harness_hooks.copilot.enabled: false` in
136
- the vault's `.heyspex/config.yaml`.
137
-
138
- Four security gates ignore all of these by design: `env-vault-guard`, `research-method-guard`,
139
- `research-protocol-gate` and `git-identity-guard`. They only act on secret writes, built-in
140
- deep-research skills, unprotocolled web research and git identity changes.
141
-
142
- ## 6. Everyday loop
143
-
144
- With MCP available: `heyspex_next_on_deck`, `heyspex_claim_spec`, `heyspex_report_progress`,
145
- `heyspex_submit_for_review`. Without MCP, the `hs` CLI (`npx hs`) covers the same loop; see
146
- `docs/driving-heyspex-from-copilot.md`.
147
-
148
- ## 7. Troubleshooting
149
-
150
- - **Every tool call is denied.** Run `hs mode off` to unblock immediately, then capture the exact
151
- deny text and the hook command it names. If the command still starts with
152
- `node "$CLAUDE_PROJECT_DIR/...`, the package is old; run `npm install heyspex@latest` and reinstall the plugin.
153
- - **MCP server does not start.** Copilot documents `${PLUGIN_ROOT}` for its own plugin format, and
154
- whether it expands `${CLAUDE_PLUGIN_ROOT}` in a Claude-format plugin is unverified. Register the
155
- server explicitly:
156
-
157
- ```bash
158
- copilot mcp add heyspex -- node ./node_modules/heyspex/plugins/heyspex/bin/launch-mcp.mjs
159
- ```
160
-
161
- - **A hook denies with no reason shown.** That is a hook exiting 2 the old way. Report the hook
162
- name; it should be answering in Copilot's JSON format.
163
- - **Hooks run twice.** The repo you are in also carries HeySpex rows in its own
164
- `.claude/settings.json` from `hs install`. Use either the plugin or the install kit (or `.github/hooks`) in one repo,
165
- not both.
166
-
167
- ## 8. Report back
168
-
169
- State the Copilot CLI version, the output of `copilot plugin list`, the result of the three checks
170
- in section 4, and the exact text of any deny or MCP error.
171
-
172
- ## Status of this document
173
-
174
- The install commands come from GitHub's plugin reference, and the hook behaviour was verified by
175
- replaying Copilot-shaped payloads through the registered commands, not by a live Copilot session.
176
- The first agent that completes section 4 is the real test. Fix history: diagnose HS-20SW and
177
- capture HS-HNO1 (2026-10-16).
1
+ # Installing the HeySpex (SpexCode) plugin in GitHub Copilot CLI
2
+
3
+ Instructions written to be handed verbatim to a GitHub Copilot CLI agent. Follow the steps in
4
+ order and stop at any step that fails, reporting the exact output.
5
+
6
+ This guide is for a team that installs only the `heyspex` npm package. The heyspex-app repository
7
+ is not needed and is not available to customers.
8
+
9
+ Source of truth for the Copilot commands and file layout:
10
+ <https://docs.github.com/en/copilot/reference/copilot-cli-reference/cli-plugin-reference>.
11
+ Hook behaviour under Copilot: <https://docs.github.com/en/copilot/reference/hooks-configuration>.
12
+ Both pages were read on 2026-10-16. The plugin itself is documented in `node_modules/heyspex/plugins/heyspex/README.md`.
13
+
14
+ ## 0. The short version
15
+
16
+ From the root of your repo, after `npm install heyspex`:
17
+
18
+ ```bash
19
+ npx heyspex setup copilot # plugin route (Copilot CLI): registers the marketplace and installs the plugin
20
+ npx heyspex setup copilot --hooks # hooks route (Copilot cloud agent / no plugin): writes .github/hooks/heyspex.json
21
+ npx heyspex setup copilot --check # which route is active; warns if both are
22
+ npx heyspex setup copilot --uninstall
23
+ ```
24
+
25
+ To have an agent do it, paste it the output of `npx heyspex setup copilot --print` (this document,
26
+ preceded by the exact next command). If no Copilot CLI can be found (PATH, then the Copilot app's bundled copy), the plugin route
27
+ installs nothing, prints the prerequisite and the two commands, and exits 1. Pick ONE route, never both. The manual commands below remain the fallback.
28
+
29
+ ## 1. Prerequisites
30
+
31
+ The heyspex-app repository is not required and is not available to customers. Everything below
32
+ works from the published npm package `heyspex` (or a tarball your HeySpex contact hands you), which
33
+ carries the plugin, the marketplace manifest, the hooks and the MCP server.
34
+
35
+ - Node.js 20 or newer on PATH (`node --version`).
36
+ - GitHub Copilot CLI installed and signed in. Any one of: the GitHub Copilot app (its bundled
37
+ `%LOCALAPPDATA%\github-copilot-sdk\cli\<version>\copilot.exe` is auto-detected, newest version
38
+ wins, no PATH entry needed), `npm install -g @github/copilot`, or `winget install GitHub.Copilot`.
39
+ `npx heyspex setup copilot` looks on PATH first, then for the app copy; if neither exists it
40
+ installs nothing and exits non-zero. `COPILOT_HOME` (Copilot's settings-dir override) is honoured.
41
+ - A git repo of your own (the one you want governed). From its root, install the package:
42
+
43
+ ```bash
44
+ npm install heyspex
45
+ # or, from a tarball you were given:
46
+ npm install ./heyspex-0.2.0.tgz
47
+ ```
48
+
49
+ - Sign the machine in to the HeySpex console so hooks and MCP tools can reach the vault:
50
+
51
+ ```bash
52
+ npx hs login
53
+ ```
54
+
55
+ ## 2. Pick ONE: the plugin or the repo hooks (never both)
56
+
57
+ Copilot reads hooks from an installed plugin and from `.github/hooks/` in the repo. With both,
58
+ every hook runs twice. Choose one.
59
+
60
+ The `.claude/settings.json` rows `hs install` commits are the exception that needs no choice: they
61
+ route through the committed launcher `.claude/heyspex/run-hook.mjs` (marker `// yields-to-plugin: v1`),
62
+ which exits 0 silently when a heyspex plugin is enabled on the machine running it, so the plugin's
63
+ copy of the hook is the only one that fires. The launcher reads the same plugin evidence `hs doctor`'s
64
+ `hook-double-fire` check does; `enabledPlugins["heyspex@..."] === false` keeps the repo rows running,
65
+ and `HEYSPEX_REPO_HOOKS=1` forces them. `.github/hooks/*.json` rows do not use the launcher, so for
66
+ those the plugin-or-hooks choice below stands.
67
+
68
+ **Option A: the plugin (recommended).** One command registers the marketplace shipped inside the
69
+ package and installs the plugin:
70
+
71
+ ```bash
72
+ npx heyspex setup copilot
73
+ ```
74
+
75
+ (`npx hs install --target . --copilot-plugin-apply` does the same.) By hand, the equivalent Copilot commands are:
76
+
77
+ ```bash
78
+ copilot plugin marketplace add ./node_modules/heyspex
79
+ copilot plugin install heyspex@heyspex-marketplace
80
+ copilot plugin list
81
+ ```
82
+
83
+ `./node_modules/heyspex/.claude-plugin/marketplace.json` is a Claude-format marketplace named
84
+ `heyspex-marketplace`; its plugin `source` (`./plugins/heyspex`) resolves inside the package.
85
+ `npx hs install --target . --copilot-plugin` (no `-apply`) only prints these commands.
86
+
87
+ **Option B: repo hooks, for teammates and the Copilot cloud agent.** Writes
88
+ `.github/hooks/heyspex.json` into your repo; commit it. Each command runs
89
+ `node_modules/heyspex/scripts/claude-hooks/_run.mjs` and exits 0 if the package is not installed,
90
+ so a checkout without `npm install` is never blocked.
91
+
92
+ ```bash
93
+ npx heyspex setup copilot --hooks
94
+ ```
95
+
96
+ (`npx hs install --target . --copilot-hooks` does the same.) `setup copilot --hooks` refuses when the plugin is already installed. If you pass `--copilot-hooks` together with `--copilot-plugin[-apply]`, the installer warns and
97
+ skips the hooks file.
98
+
99
+ Then restart the Copilot session (`/restart`) so hooks load, and verify:
100
+
101
+ ```bash
102
+ copilot plugin list # Option A: heyspex is enabled
103
+ npx hs doctor # MCP, hooks and account surfaces healthy
104
+ ```
105
+
106
+ ## 3. What the plugin loads
107
+
108
+ | Component | Source | Behaviour under Copilot |
109
+ | --- | --- | --- |
110
+ | Hooks | `node_modules/heyspex/plugins/heyspex/hooks/hooks.json` | PreToolUse, PostToolUse, Stop, UserPromptSubmit and SessionStart gates. Every command locates the runtime itself and exits 0 if it cannot, so a missing variable never denies a tool call. A real deny arrives as a top-level `permissionDecision` with a reason. |
111
+ | MCP server | `node_modules/heyspex/plugins/heyspex/.mcp.json` | The `heyspex_*` vault tools and `hs-*` prompts. |
112
+ | Slash commands | not loaded | Claude Code commands are not a Copilot component. Use MCP prompts or the `hs` CLI. |
113
+
114
+ ## 4. Verify the install
115
+
116
+ 1. In a Copilot session inside any repo, run a harmless tool call, for example read a file. It
117
+ must succeed. A message containing "Denied by preToolUse hook" means a hook failed; go to
118
+ section 7.
119
+ 2. Confirm the MCP server is up by listing MCP servers in Copilot (`/mcp`) and calling
120
+ `heyspex_recall_memories` with `{ "limit": 3 }`. If the server is missing, go to section 7.
121
+ 3. Confirm the gates work: send a prompt that contains a new product idea of more than 60
122
+ characters, then try to edit a source file without capturing. The edit should be refused with a
123
+ reason that names `directive-obligation-gate`. Call `heyspex_update_capture` with the prompt
124
+ text, then retry the edit. It should pass.
125
+
126
+ ## 5. Turning HeySpex off and on
127
+
128
+ Run from the repo you are working in:
129
+
130
+ ```bash
131
+ hs mode status # on | off, and why
132
+ hs mode off # every hook exits 0 immediately, no restart needed
133
+ hs mode on
134
+ hs mode toggle
135
+ ```
136
+
137
+ Use `npx hs mode off` when `hs` is not on PATH. The switch writes
138
+ `.heyspex/mode.json` in the project and is git-ignored.
139
+
140
+ Per-shell variants that touch no files:
141
+
142
+ | Variable | Effect |
143
+ | --- | --- |
144
+ | `HEYSPEX_MODE=off` | Silences hooks for every harness in that shell |
145
+ | `HEYSPEX_COPILOT_HOOKS_OFF=1` | Silences hooks only when the caller is Copilot; Claude Code and Cursor keep theirs |
146
+
147
+ The config twin of the Copilot switch is `agent_behaviors.harness_hooks.copilot.enabled: false` in
148
+ the vault's `.heyspex/config.yaml`.
149
+
150
+ Four security gates ignore all of these by design: `env-vault-guard`, `research-method-guard`,
151
+ `research-protocol-gate` and `git-identity-guard`. They only act on secret writes, built-in
152
+ deep-research skills, unprotocolled web research and git identity changes.
153
+
154
+ ## 6. Everyday loop
155
+
156
+ With MCP available: `heyspex_next_on_deck`, `heyspex_claim_spec`, `heyspex_report_progress`,
157
+ `heyspex_submit_for_review`. Without MCP, the `hs` CLI (`npx hs`) covers the same loop; see
158
+ `docs/driving-heyspex-from-copilot.md`.
159
+
160
+ ## 7. Troubleshooting
161
+
162
+ - **Every tool call is denied.** Run `hs mode off` to unblock immediately, then capture the exact
163
+ deny text and the hook command it names. If the command still starts with
164
+ `node "$CLAUDE_PROJECT_DIR/...`, the package is old; run `npm install heyspex@latest` and reinstall the plugin.
165
+ - **MCP server does not start.** Copilot documents `${PLUGIN_ROOT}` for its own plugin format, and
166
+ whether it expands `${CLAUDE_PLUGIN_ROOT}` in a Claude-format plugin is unverified. Register the
167
+ server explicitly:
168
+
169
+ ```bash
170
+ copilot mcp add heyspex -- node ./node_modules/heyspex/plugins/heyspex/bin/launch-mcp.mjs
171
+ ```
172
+
173
+ - **A hook denies with no reason shown.** That is a hook exiting 2 the old way. Report the hook
174
+ name; it should be answering in Copilot's JSON format.
175
+ - **Hooks run twice.** The repo you are in also carries HeySpex rows in its own
176
+ `.claude/settings.json` from `hs install`. Use either the plugin or the install kit (or `.github/hooks`) in one repo,
177
+ not both.
178
+
179
+ ## 8. Report back
180
+
181
+ State the Copilot CLI version, the output of `copilot plugin list`, the result of the three checks
182
+ in section 4, and the exact text of any deny or MCP error.
183
+
184
+ ## Status of this document
185
+
186
+ The install commands come from GitHub's plugin reference, and the hook behaviour was verified by
187
+ replaying Copilot-shaped payloads through the registered commands, not by a live Copilot session.
188
+ The first agent that completes section 4 is the real test. Fix history: diagnose HS-20SW and
189
+ capture HS-HNO1 (2026-10-16).
190
+
191
+ ## Optional: HeySpex status line
192
+
193
+ Opt in with `npx heyspex setup copilot --statusline`. It merges a `statusLine` block into `<COPILOT_HOME or ~/.copilot>/settings.json`
194
+ (other keys are kept; the first change leaves `settings.json.heyspex-bak`). The command is `node "<installed heyspex>/scripts/copilot-statusline.mjs"`,
195
+ so run it from a project that has `heyspex` installed, not from the npx cache. A non-HeySpex `statusLine` is never overwritten unless you pass `--force`.
196
+ `npx heyspex setup copilot --statusline --uninstall` removes only the HeySpex one; `--check` reports its state.
197
+
198
+ The line shows `Auto · 12% used | repo > branch | [HS] <pinned epic> | [HS] <pillar> > <claimed spec>`, reusing the Claude Code renderer.
199
+ It is plain text (no font needed), refreshes every 30 s (`refreshInterval`) plus on Copilot events, never waits on the network, and prints a bare `HeySpex`
200
+ if anything fails. `hs mode off` / `HEYSPEX_MODE=off` blanks it. Copilot renders it in interactive sessions only.