@davesheffer/hunch 1.32.7 → 1.32.8
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/README.md +96 -206
- package/dist/cli/integrations.js +4 -1
- package/dist/cli/update.js +6 -2
- package/dist/integrations/health.d.ts +2 -1
- package/dist/integrations/health.js +53 -16
- package/package.json +2 -2
- package/server.json +3 -3
package/README.md
CHANGED
|
@@ -1,289 +1,179 @@
|
|
|
1
1
|
# Hunch
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## A shared record for AI agents: what was decided, what happened, and what still needs doing.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@davesheffer/hunch)
|
|
6
6
|
[](https://github.com/davesheffer/hunch)
|
|
7
7
|
[](LICENSE)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
A new agent session should not mean explaining the project all over again. A second agent should be able to check a recorded decision, see the evidence behind completed work, and find an outstanding commitment.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Hunch keeps that record in Git and makes the relevant parts available to your agents. It started with **engineering memory**: why code exists, which approach failed before, and which rules a change must preserve. It also ships a **state server** for sharing decisions, action records, and commitments across authorized organization, team, user, and repository scopes.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
The goal is simple: agents working from the same maintained record, with sources they can inspect. Hunch supplies memory and checks; the assistant still does the work.
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Start with your coding assistant
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **Git is the source of truth.** Every fact is a JSON file under `.hunch/`, every change a commit: diffable, PR-reviewable, revertable, mergeable, never locked in a vendor database. SQLite is only a derived index.
|
|
20
|
-
- **Refusal, not convergence.** One live decision per topic. A second contradicting record is refused at write time with the incumbent named, and a supersede target must still be open. Diverging writes are not merged later.
|
|
21
|
-
- **Organization drawers with a key per agent.** Repository, user, team and organization partitions; the bearer key resolves the principal and decides visibility before anything is looked up.
|
|
22
|
-
- **Receipts and commitments are facts.** What was actually done in an external system, verified or not, and who owes what by when, readable by any agent with the key.
|
|
23
|
-
- **Never Twice.** A human correction becomes an enforced rule, not a one-session memory. Nothing blocks until a human deliberately trusts a precise rule and opts into strict enforcement.
|
|
24
|
-
- **The code spoke.** Decisions, constraints and bug lineage are checked against the code deterministically, with no model in the block path. No state-layer peer has it.
|
|
25
|
-
|
|
26
|
-
## Start in five minutes
|
|
27
|
-
|
|
28
|
-
Requires Node 22.13+ and a Git repository.
|
|
17
|
+
Requires **Node 22.13+** and a Git repository.
|
|
29
18
|
|
|
30
19
|
```bash
|
|
31
20
|
npm i -g @davesheffer/hunch
|
|
32
21
|
cd your-repo
|
|
33
22
|
hunch init
|
|
34
|
-
hunch backfill --since 90d # optional:
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Reload your coding assistant, then ask a normal question:
|
|
38
|
-
|
|
39
|
-
> Why is this built this way?
|
|
40
|
-
|
|
41
|
-
`hunch init` indexes the repository, installs local lifecycle hooks and connects supported assistants without replacing their existing configuration. The next session receives the relevant story with its sources, not a giant transcript or generic prompt wall.
|
|
42
|
-
|
|
43
|
-
Lifecycle coverage depends on the harness; MCP connectivity alone does not establish automatic grounding or enforcement.
|
|
44
|
-
|
|
45
|
-
To update Hunch and configured harness pins for the current repository:
|
|
46
|
-
|
|
47
|
-
```sh
|
|
48
|
-
hunch update
|
|
23
|
+
hunch backfill --since 90d # optional: draft memory from recent history
|
|
49
24
|
```
|
|
50
25
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
Check integrations after upgrading Hunch or switching assistants:
|
|
26
|
+
Reload your assistant, then ask:
|
|
54
27
|
|
|
55
|
-
|
|
56
|
-
hunch integrations check
|
|
57
|
-
hunch integrations repair-pins
|
|
58
|
-
hunch integrations check --harness claude --probe --require mcp
|
|
59
|
-
hunch integrations check --harness codex --require context,edit-blocking
|
|
60
|
-
```
|
|
28
|
+
> Why is this built this way, and what should I preserve when changing it?
|
|
61
29
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
Codex CLI 0.153+ gets a native lifecycle adapter (`.codex/hooks.json`: session orientation, prompt task IDs from `turn_id`, `apply_patch` pre-edit grounding and strict denial, native `Bash`/`PowerShell` post-tool observation, Stop cards); project-layer hooks load only for a trusted project and must be trusted once in Codex with `/hooks`. Failure capture is certified only by an explicit failed-tool lifecycle event; a successful `PostToolUse` observation does not prove it. The opt-in `--probe` verifies a fresh MCP process, not whether an existing host session or model actually followed the memory.
|
|
65
|
-
|
|
66
|
-
Use `hunch integrations check` in CI to prevent pin drift; add `--require` for capabilities your workflow cannot operate without.
|
|
67
|
-
|
|
68
|
-
## One evidence loop, not another model
|
|
69
|
-
|
|
70
|
-
```text
|
|
71
|
-
Git history + ADRs + corrections + tests + repository conventions
|
|
72
|
-
│
|
|
73
|
-
▼
|
|
74
|
-
Hunch's evidence graph
|
|
75
|
-
/ │ \
|
|
76
|
-
engineering memory Project DNA reviewed landscape
|
|
77
|
-
\ │ /
|
|
78
|
-
▼
|
|
79
|
-
role-shaped, budgeted context delivery
|
|
80
|
-
│
|
|
81
|
-
▼
|
|
82
|
-
Claude / Codex / Cursor / any MCP agent
|
|
83
|
-
│
|
|
84
|
-
▼
|
|
85
|
-
deterministic change receipt
|
|
86
|
-
```
|
|
30
|
+
`hunch init` indexes the code, configures supported assistant integrations, and adds memory instructions while preserving existing settings. For Codex hooks, review and trust the commands in `/hooks`, then start a new session. **Memory is advisory by default.** Blocking requires an explicitly trusted rule and strict enforcement.
|
|
87
31
|
|
|
88
|
-
Hunch
|
|
32
|
+
Hunch works with Claude Code, Codex, Cursor, VS Code/Copilot, Windsurf, Antigravity, and other MCP clients. Automatic context and hook coverage vary by assistant; a connected MCP server alone does not prove they are running. [Check your integration](https://www.hunchmemory.com/docs#update).
|
|
89
33
|
|
|
90
|
-
## What
|
|
34
|
+
## What you get today
|
|
91
35
|
|
|
92
|
-
|
|
|
36
|
+
| Need | How Hunch helps |
|
|
93
37
|
| --- | --- |
|
|
94
|
-
|
|
|
95
|
-
|
|
|
96
|
-
|
|
|
97
|
-
|
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
|
|
|
101
|
-
|
|
102
|
-
Readable JSON in `.hunch/` is the repository-scoped source of truth. SQLite is a fast, rebuildable projection. Git keeps the state portable, reviewable and reversible.
|
|
38
|
+
| Stop explaining old decisions | Saves decisions, rejected alternatives, bug history, corrections, and open findings with their sources. |
|
|
39
|
+
| Understand a change before making it | Connects memory to code symbols and dependencies; shows affected code and recorded architectural intent. |
|
|
40
|
+
| Keep agents informed across sessions | Delivers a focused brief for a task through MCP and supported lifecycle hooks. |
|
|
41
|
+
| Check the rules your team chose | Evaluates supported constraints and code relationships without a model in the blocking path. |
|
|
42
|
+
| See what happened during a task | Separates delivered memory, the agent's reported use, rule results, and observed command results in a contribution report. |
|
|
43
|
+
| Share project memory with teammates | Keeps repository memory in Git, with an optional dedicated private memory repository. |
|
|
44
|
+
| Share work state across agents | Serves authorized records for decisions, actions, commitments, entities, and relationships through HTTP, MCP, and a typed client. |
|
|
103
45
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
Project DNA is Hunch's evidence-bound model of **how a repository communicates and works**. It is not a persona, does not impersonate a maintainer and does not turn frequent behavior into policy.
|
|
107
|
-
|
|
108
|
-
The deterministic baseline reads an exact Git revision, bounded commit history and committed convention files. The current release can also accept bounded, caller-authorized pull-request/review evidence. Every evidence batch is validated and sealed; raw collaboration text does not enter the profile.
|
|
109
|
-
|
|
110
|
-
Each trait keeps its category, confidence, freshness, repository revision and evidence hash. Hunch can include only the relevant DNA in normal context, explain how an artifact matches repository conventions and show profile change between revisions.
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
hunch dna inspect
|
|
114
|
-
hunch dna context
|
|
115
|
-
hunch dna diff <older-ref> <newer-ref>
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
DNA may shape orientation, terminology and advisory Project Match checks. It cannot create or override a decision, constraint, finding, conformance rule, policy or permission.
|
|
119
|
-
|
|
120
|
-
Read the [Project DNA contract](docs/project-dna.md) and broader [Project DNA vision](docs/project-dna-engine.md).
|
|
46
|
+
For example, a team fixes a logout bug by keeping sessions on the server. Months later, an agent proposes removing that code. Hunch can surface the original reason and rejected alternative before the edit. A supported, trusted rule can flag the conflict; strict mode can block it. Recording the lesson and configuring the integration are what make this possible.
|
|
121
47
|
|
|
122
48
|
## Day-to-day
|
|
123
49
|
|
|
124
50
|
| Command | Use it for |
|
|
125
51
|
| --- | --- |
|
|
126
|
-
| `hunch context "<task>" --profile builder` | Get a
|
|
127
|
-
| `hunch why <file-or-symbol>` |
|
|
128
|
-
| `hunch structure [target]` | Inspect indexed
|
|
129
|
-
| `hunch findings [scope]` |
|
|
130
|
-
| `hunch
|
|
131
|
-
| `hunch
|
|
132
|
-
| `hunch
|
|
133
|
-
| `hunch
|
|
134
|
-
| `hunch
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
| `hunch now` | See recent memory and live decision-backed roadmap |
|
|
138
|
-
| `hunch escalations` | See questions that genuinely require a human answer |
|
|
139
|
-
| `hunch doctor` | Diagnose setup, provider, index or overlay problems |
|
|
140
|
-
|
|
141
|
-
When you are ready for deterministic enforcement:
|
|
52
|
+
| `hunch context "<task>" --profile builder` | Get a focused brief before starting |
|
|
53
|
+
| `hunch why <file-or-symbol>` | Understand decisions and past bugs behind code |
|
|
54
|
+
| `hunch structure [target]` | Inspect indexed files and symbols |
|
|
55
|
+
| `hunch findings [scope]` | See known gaps that still need work |
|
|
56
|
+
| `hunch impact origin/main` | See what a branch could affect |
|
|
57
|
+
| `hunch check --working` | Check current changes against recorded rules |
|
|
58
|
+
| `hunch conform` | Check supported architectural relationships |
|
|
59
|
+
| `hunch now` | Read recent decisions and the recorded roadmap |
|
|
60
|
+
| `hunch doctor` | Diagnose setup and storage problems |
|
|
61
|
+
|
|
62
|
+
For enforcement after reviewing and trusting the relevant rules:
|
|
142
63
|
|
|
143
64
|
```bash
|
|
144
65
|
hunch firmness strict
|
|
145
66
|
hunch check --staged --strict
|
|
146
67
|
```
|
|
147
68
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
## Deterministic organizational state
|
|
151
|
-
|
|
152
|
-
Repository memory solves one version of a larger problem, and since 1.25.0 Hunch ships the larger one.
|
|
153
|
-
|
|
154
|
-
As organizations give every employee an agent that can work across CRM, email, messaging, repositories and other tools, the agents become probabilistic writers/readers of the same organization. If each one independently reconstructs what was decided, what was already done or what is still owed, the organization gets multiple conflicting realities.
|
|
155
|
-
|
|
156
|
-
Hunch is the deterministic state layer between those agents and the organization:
|
|
69
|
+
Generated notes, observed habits, and imported documents do not silently gain blocking authority.
|
|
157
70
|
|
|
158
|
-
|
|
71
|
+
## Update without losing your settings
|
|
159
72
|
|
|
160
|
-
|
|
73
|
+
From each repository that uses Hunch:
|
|
161
74
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
- decisions currently in force;
|
|
165
|
-
- verified action receipts / what was done;
|
|
166
|
-
- commitments and due-state;
|
|
167
|
-
- entities and relationships;
|
|
168
|
-
- code/system changes with proof;
|
|
169
|
-
- repository/user/team/org DNA;
|
|
170
|
-
- derived current state with exact dependencies/invalidation.
|
|
171
|
-
|
|
172
|
-
Agents continue to own live connector mechanics. Hunch must **not** become a managed proxy that fetches Gmail, CRM, WhatsApp or GitHub on an agent's behalf.
|
|
173
|
-
|
|
174
|
-
Instead:
|
|
175
|
-
|
|
176
|
-
```text
|
|
177
|
-
Hunch deterministic state
|
|
178
|
-
↑ ↓
|
|
179
|
-
agent -> deterministic action gate -> connector -> source system
|
|
75
|
+
```bash
|
|
76
|
+
hunch update
|
|
180
77
|
```
|
|
181
78
|
|
|
182
|
-
Hunch
|
|
79
|
+
Or ask your agent to **“update Hunch.”** The command installs the latest release, aligns configured integration pins, repairs known legacy launch commands, and refreshes Hunch instructions. It preserves unrelated settings and intentionally disabled hooks.
|
|
183
80
|
|
|
184
|
-
|
|
81
|
+
- A standalone npm project keeps Hunch in its existing dependency section at an exact version. Without a repository dependency, the global CLI is updated. Add `--global` to update both.
|
|
82
|
+
- For other package managers or workspaces, update the dependency with that package manager, then run `hunch integrations repair-pins`.
|
|
83
|
+
- Restart or reconnect active assistants. In Codex, open `/hooks` to review and trust changed commands, then start a new session. A changed version pin changes the command and requires renewed trust.
|
|
185
84
|
|
|
186
|
-
|
|
85
|
+
Verify the setup:
|
|
187
86
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
derived state that names what it rests on, external entities and their relationships. Ids are
|
|
194
|
-
derived from a record's facts, a replay returns the original, a second live decision on a topic is
|
|
195
|
-
refused with the incumbent named, and derived state without dependencies is not state. Each scope
|
|
196
|
-
keeps a git-native change ledger under `.hunch/changes/`; organization, team and user partitions
|
|
197
|
-
are homed in an overlay, never in a repository. The MCP server binds it as `nuryel_capabilities`,
|
|
198
|
-
`nuryel_read`, `nuryel_write` and `nuryel_subscribe`; every other transport will call the same
|
|
199
|
-
store binding. Contract and evidence: [docs/nuryel-state-contract.md](docs/nuryel-state-contract.md).
|
|
87
|
+
```bash
|
|
88
|
+
hunch integrations check
|
|
89
|
+
hunch integrations check --harness codex --probe --require mcp
|
|
90
|
+
hunch integrations check --harness codex --require context
|
|
91
|
+
```
|
|
200
92
|
|
|
201
|
-
|
|
202
|
-
team, user and repository partitions over HTTP on loopback with the same three verbs. A served
|
|
203
|
-
partition is a directory whose `.hunch/partition.json` names the scope it is; the bearer token
|
|
204
|
-
resolves the principal and grants come from the config only. `hunch serve init --partition
|
|
205
|
-
user:david --root <dir> --principal sofia@david` declares a partition and mints a token. The typed
|
|
206
|
-
client is `import { createStateClient } from "@davesheffer/hunch/state"`. This folds the separate
|
|
207
|
-
Hunch Memory service into Hunch.
|
|
93
|
+
The first command checks configuration. The probe starts a fresh MCP process and reads memory. The context check requires observed hook delivery on the expected version, so run it after the new assistant session begins. `--require` fails when the named capability is not verified; none of these checks proves that a model followed the advice.
|
|
208
94
|
|
|
209
|
-
|
|
95
|
+
## See what Hunch contributed
|
|
210
96
|
|
|
211
|
-
|
|
97
|
+
Task reports answer: what memory reached this task, what did the agent say it used, and what checks actually ran?
|
|
212
98
|
|
|
213
|
-
|
|
99
|
+
The normal agent instructions request a completion card with a link to a local evidence report. You can also inspect reports directly:
|
|
214
100
|
|
|
215
|
-
|
|
101
|
+
```bash
|
|
102
|
+
hunch task list
|
|
103
|
+
hunch report <task-id> --html
|
|
104
|
+
```
|
|
216
105
|
|
|
217
|
-
|
|
106
|
+
A delivered lesson, an agent's claim, and a passing test are different evidence. Hunch keeps them separate. Automatic presentation depends on the host following the task lifecycle; missing evidence stays unverified. [Read the reporting guide](docs/task-reports.md).
|
|
218
107
|
|
|
219
108
|
## Share one living repository memory with your team
|
|
220
109
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
Today Hunch does not host that shared Git repository; teammates/CI use normal Git access and one maintainer connects it:
|
|
110
|
+
One maintainer connects a dedicated private Git repository:
|
|
224
111
|
|
|
225
112
|
```bash
|
|
226
|
-
npm i -g @davesheffer/hunch@1.32.2
|
|
227
113
|
hunch shared --repo git@github.com:acme/project-hunch-memory.git
|
|
228
114
|
git add .gitignore .hunch/team.json
|
|
229
115
|
git commit -m "chore: connect shared Hunch memory"
|
|
230
116
|
git push
|
|
231
117
|
```
|
|
232
118
|
|
|
233
|
-
Teammates
|
|
119
|
+
Teammates install Hunch, pull the code, and run `hunch init`. Normal Git access controls the shared repository. Credentials, local clone paths, and private overlays stay out of the committed pointer. Use `hunch shared --sync` to retry synchronization; add `--no-auto-commit` when captures should wait for explicit sync.
|
|
234
120
|
|
|
235
|
-
|
|
236
|
-
npm i -g @davesheffer/hunch@1.32.2
|
|
237
|
-
git pull
|
|
238
|
-
hunch init
|
|
239
|
-
hunch doctor
|
|
240
|
-
```
|
|
121
|
+
This shares a project's engineering memory. The state server below adds authenticated access across multiple scopes.
|
|
241
122
|
|
|
242
|
-
|
|
123
|
+
## Deterministic organizational state
|
|
124
|
+
|
|
125
|
+
A coding agent needs to know why a module exists. An operations agent may need to know whether a customer action was completed or who owes the next follow-up. Both need a maintained record they can check.
|
|
126
|
+
|
|
127
|
+
Hunch already ships `hunch serve`: a self-hosted HTTP service for organization, team, user, and repository records. A configured identity determines which scopes an agent may access. The same state contract is available through MCP and the `@davesheffer/hunch/state` client.
|
|
128
|
+
|
|
129
|
+
Records can describe decisions, action outcomes, commitments, entities, relationships, and summaries that name their dependencies. Actions retain their status, including unknown or unverified outcomes. Repeated writes have stable identities, conflicting current decisions are refused, and confirmed human records receive protections against agent overwrites. These are defined checks on structured records; Hunch cannot establish every fact in the outside world on its own.
|
|
243
130
|
|
|
244
|
-
|
|
131
|
+
This is what **deterministic state** means here: explicit rules govern the stored record, rather than having each agent reconstruct it from scratch. Git holds the durable data; SQLite is a rebuildable index. The server binds to loopback and requires deployment and agent integration by its operator. Hunch does not provide a managed CRM or email connector service.
|
|
245
132
|
|
|
246
|
-
|
|
133
|
+
[Set up and understand the state server](docs/deterministic-state.md) · [State contract and client reference](docs/nuryel-state-contract.md)
|
|
247
134
|
|
|
248
|
-
|
|
135
|
+
### The vision, and what is still being tested
|
|
249
136
|
|
|
250
|
-
|
|
251
|
-
- **Hosted state is a roadmap extension, not a shipped claim.** Organization/team/user state will require authenticated scope/visibility, idempotency and durability while preserving git-native truth.
|
|
252
|
-
- **Private when needed.** `hunch private --repo <url>` keeps sensitive repository reasoning in a separate overlay; public CI/documentation remain public-only.
|
|
253
|
-
- **Human authority.** Observations, generated drafts, imported ADRs, discovered landscape records and proved policy candidates do not silently become trusted truth.
|
|
254
|
-
- **Deterministic core.** Indexing, retrieval receipts, currentness, conformance, Project DNA discovery and policy evaluation do not require a model.
|
|
255
|
-
- **Agents own execution.** Hunch state does not silently grant connector permissions, send messages or become a source-system proxy.
|
|
256
|
-
- **No surprise synthesis bill.** Optional drafting can use a selected Claude Code, Codex or Cursor subscription CLI, a local OpenAI-compatible endpoint or deterministic fallback. Public remote endpoints require explicit opt-in.
|
|
257
|
-
- **Traceable releases.** npm packages and the VS Code extension are content-addressed, verified against public registries and tied back to exact source tags.
|
|
137
|
+
The vision is continuity across people, tools, and agents: an operations agent records a customer issue, a coding agent finds the relevant decision and fixes the cause, and the operations agent closes the commitment using evidence of the fix.
|
|
258
138
|
|
|
259
|
-
|
|
139
|
+
The underlying memory and state tools ship today. The broader claim—that different agents reliably use that shared state and avoid contradictory work—is still being measured in the Sofia pilot. Simulated results and a limited live pilot are not proof of that outcome across organizations. The [roadmap](ROADMAP.md) tracks the remaining acceptance gates.
|
|
260
140
|
|
|
261
|
-
The
|
|
141
|
+
**Hunch remains the product name.** The `nuryel.state/1` protocol and `nuryel_*` tool names are existing technical identifiers; a possible future rename is undecided.
|
|
262
142
|
|
|
263
|
-
|
|
264
|
-
- **v1.21 — Project DNA.** Hunch gained deterministic, revision-specific repository profiles, bounded DNA context delivery, explainable Project Match checks and auditable profile deltas.
|
|
265
|
-
- **v1.22 — authorized collaboration evidence.** Hosts can contribute bounded PR/review evidence to Project DNA through a typed, sealed contract without raw collaboration persistence or policy-authority change.
|
|
266
|
-
- **v1.23 — native change proof and proof-carrying evidence work.** Exact Git change identity, graph before/after, decisions/constraints, blast radius and Change Gate result can be bound into a sealed evidence artifact without granting authority.
|
|
267
|
-
- **v1.25 – v1.30 — the state layer.** `nuryel.state/1` as code, `hunch serve` partitions, union reads, subject identity by external reference, replay determinism, human corrections outranking agent writes.
|
|
268
|
-
- **v1.32 — see what Hunch contributed.** Task contribution reports: what was delivered, what the agent reports it applied, what a rule verified, what a command observed; concise card, local evidence view.
|
|
143
|
+
## Project DNA: help the agent understand how the project works
|
|
269
144
|
|
|
270
|
-
|
|
145
|
+
Project DNA describes observed repository conventions: terminology, contribution habits, review expectations, and engineering patterns. Engineering memory records decisions and their reasons. Both can inform a task, but frequent behavior does not become policy.
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
hunch dna inspect
|
|
149
|
+
hunch dna context
|
|
150
|
+
hunch dna diff <older-ref> <newer-ref>
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Profiles retain their revision, sources, confidence, and freshness. [Project DNA contract](docs/project-dna.md) · [Broader DNA vision](docs/project-dna-engine.md)
|
|
154
|
+
|
|
155
|
+
## Your data and your authority
|
|
156
|
+
|
|
157
|
+
- Repository use is local-first and needs no hosted Hunch account. Shared memory uses Git access; the optional state server uses configured identities and grants.
|
|
158
|
+
- `hunch private --repo <url>` keeps sensitive project reasoning in a private overlay. Public exports and CI should use public-only views.
|
|
159
|
+
- Drafting can use a selected coding-assistant subscription, a local endpoint, or the deterministic fallback. Public metered endpoints require explicit opt-in. [Synthesis and billing](https://www.hunchmemory.com/docs#synthesis).
|
|
160
|
+
- Agents keep responsibility for external actions and connector permissions. A stored record does not authorize an email, deployment, or CRM change.
|
|
161
|
+
- npm and editor releases use separate publication gates with package integrity and provenance checks.
|
|
271
162
|
|
|
272
163
|
## Learn more
|
|
273
164
|
|
|
274
165
|
- [Full documentation](https://www.hunchmemory.com/docs)
|
|
275
166
|
- [Copy-paste cookbook](https://www.hunchmemory.com/cookbook)
|
|
276
|
-
- [
|
|
277
|
-
- [Keep agent launches with the initiating provider](docs/agent-origin.md)
|
|
167
|
+
- [Task contribution reports](docs/task-reports.md)
|
|
278
168
|
- [Deterministic organizational state](docs/deterministic-state.md)
|
|
279
169
|
- [Project DNA](docs/project-dna.md)
|
|
280
170
|
- [Native change proof](docs/change-proof.md)
|
|
281
|
-
- [
|
|
282
|
-
- [
|
|
171
|
+
- [Engineering Landscape](docs/engineering-landscape.md)
|
|
172
|
+
- [Review memory](docs/review-memory.md)
|
|
173
|
+
- [Agent-origin handling](docs/agent-origin.md)
|
|
174
|
+
- [Autonomy ladder](docs/autonomy-ladder.md)
|
|
283
175
|
- [Autonomous development](docs/autonomous-development.md)
|
|
284
|
-
- [
|
|
285
|
-
- [Engineering Landscape Graph](docs/engineering-landscape.md)
|
|
286
|
-
- [Hunch roadmap](ROADMAP.md)
|
|
176
|
+
- [Changelog](CHANGELOG.md) · [Roadmap](ROADMAP.md)
|
|
287
177
|
- [VS Code extension](vscode-extension/README.md)
|
|
288
178
|
- [Architecture benchmark](bench/architectural-conformance.md)
|
|
289
179
|
- [Contributing](CONTRIBUTING.md)
|
package/dist/cli/integrations.js
CHANGED
|
@@ -26,11 +26,14 @@ export function registerIntegrationCommands(program, refreshGrounding) {
|
|
|
26
26
|
process.exitCode = 1;
|
|
27
27
|
});
|
|
28
28
|
integrations.command("repair-pins")
|
|
29
|
-
.description("Align
|
|
29
|
+
.description("Align pins, repair known Hunch launch commands and refresh instructions; preserves other settings and does not enable hooks")
|
|
30
30
|
.action(() => {
|
|
31
31
|
const root = findRoot();
|
|
32
32
|
const files = repairIntegrationPins(root);
|
|
33
33
|
console.log(files.length ? `Updated ${files.length} integration file(s): ${files.join(", ")}. Reconnect active MCP sessions.` : "Integration pins already aligned.");
|
|
34
|
+
if (files.includes(".codex/hooks.json")) {
|
|
35
|
+
console.log("Codex: open /hooks to review and trust the changed commands, then start a new session. Command changes require renewed trust; Hunch does not grant it automatically.");
|
|
36
|
+
}
|
|
34
37
|
const grounding = refreshGrounding();
|
|
35
38
|
if (grounding.length)
|
|
36
39
|
console.log(`Updated Hunch instructions: ${grounding.join(", ")}. Reconnect the agent to load task reporting instructions.`);
|
package/dist/cli/update.js
CHANGED
|
@@ -59,8 +59,12 @@ export function updateHunch(root, opts = {}, run = (args, capture) => runNpm(roo
|
|
|
59
59
|
if (!opts.dryRun)
|
|
60
60
|
run(args);
|
|
61
61
|
}
|
|
62
|
-
if (!opts.dryRun)
|
|
63
|
-
log("Hunch updated; repository
|
|
62
|
+
if (!opts.dryRun) {
|
|
63
|
+
log("Hunch updated; repository configuration check passed. Restart or reconnect active harnesses to load the new MCP version. Runtime hook delivery is not verified by this check.");
|
|
64
|
+
if (existsSync(join(root, ".codex", "hooks.json"))) {
|
|
65
|
+
log("Codex: open /hooks to review and trust any changed commands, then start a new session. Command changes require renewed trust; Hunch does not grant it automatically.");
|
|
66
|
+
}
|
|
67
|
+
}
|
|
64
68
|
}
|
|
65
69
|
export function registerUpdateCommand(program) {
|
|
66
70
|
program.command("update")
|
|
@@ -75,7 +75,8 @@ export declare function inspectIntegrations(root: string, selected?: Harness): I
|
|
|
75
75
|
* tooling/sync-version-pins.mjs) so hooks and MCP never point at a version npm
|
|
76
76
|
* cannot serve. Unknown git state yields [] — callers then treat nothing as local. */
|
|
77
77
|
export declare function machineLocalIntegrationFiles(root: string): string[];
|
|
78
|
-
/** Repair
|
|
78
|
+
/** Repair exact published pins and the known misplaced MCP hook subcommand.
|
|
79
|
+
* Preserve formatting and all other values, including disabled hook settings.
|
|
79
80
|
* Preflight every affected file before writing any; reject malformed JSON/TOML.
|
|
80
81
|
* `skip` leaves a file untouched (used to keep machine-local pins on a version
|
|
81
82
|
* npm can actually serve while a release is still publishing). */
|
|
@@ -54,18 +54,33 @@ function strings(value) {
|
|
|
54
54
|
return Object.values(value).flatMap(strings);
|
|
55
55
|
return [];
|
|
56
56
|
}
|
|
57
|
-
function hookCommands(value) {
|
|
57
|
+
function hookCommands(value, includeDisabled = false) {
|
|
58
58
|
if (Array.isArray(value))
|
|
59
|
-
return value.flatMap(hookCommands);
|
|
59
|
+
return value.flatMap(v => hookCommands(v, includeDisabled));
|
|
60
60
|
if (!value || typeof value !== "object")
|
|
61
61
|
return [];
|
|
62
62
|
const obj = value;
|
|
63
|
-
if (obj.enabled === false || (obj.type !== undefined && obj.type !== "command"))
|
|
63
|
+
if ((!includeDisabled && obj.enabled === false) || (obj.type !== undefined && obj.type !== "command"))
|
|
64
64
|
return [];
|
|
65
65
|
const command = typeof obj.command === "string" ? obj.command : "";
|
|
66
|
-
const own = /(
|
|
66
|
+
const own = publishedHookCommand(command) !== undefined || /(?:dist|src)[\\/]+cli[\\/]+index\.(?:js|ts)/.test(command)
|
|
67
67
|
&& /\s"?hook"?(?:\s+"?--provider"?\s+"?[a-z]+"?)?\s*$/.test(command);
|
|
68
|
-
return [...(own ? [command] : []), ...(obj.hooks ? hookCommands(obj.hooks) : [])];
|
|
68
|
+
return [...(own ? [command] : []), ...(obj.hooks ? hookCommands(obj.hooks, includeDisabled) : [])];
|
|
69
|
+
}
|
|
70
|
+
/** Recognize only generated npm commands, including their legacy quoted form.
|
|
71
|
+
* Never normalize a wrapper, shell expression, or another program's arguments. */
|
|
72
|
+
function publishedHookCommand(command) {
|
|
73
|
+
const parts = command.trim().match(/"[^"\\]*"|'[^']*'|[^\s"'\\]+/g);
|
|
74
|
+
if (!parts || parts.join(" ") !== command.trim().replace(/\s+/g, " "))
|
|
75
|
+
return undefined;
|
|
76
|
+
const tokens = parts.map(p => /^["']/.test(p) ? p.slice(1, -1) : p);
|
|
77
|
+
if (tokens.some(token => /\s/.test(token)))
|
|
78
|
+
return undefined;
|
|
79
|
+
const bare = tokens.join(" ");
|
|
80
|
+
return /^npx(?:\.cmd)? (?:-y|--yes) --package=(?:hunch-exact@npm:)?@davesheffer\/hunch@[0-9A-Za-z.+-]+ (?:-- )?hunch (?:mcp )?hook(?: --provider [a-z]+)?$/.test(bare) ? bare : undefined;
|
|
81
|
+
}
|
|
82
|
+
function misroutedHook(command) {
|
|
83
|
+
return publishedHookCommand(command)?.includes(" hunch mcp hook") ?? false;
|
|
69
84
|
}
|
|
70
85
|
/** Pin repair is restricted to Hunch's marker-owned TOML block. */
|
|
71
86
|
function codexBlock(raw) {
|
|
@@ -169,7 +184,13 @@ export function inspectIntegrations(root, selected) {
|
|
|
169
184
|
const config = object(parseJsonc(readFileSync(join(root, spec.hooks), "utf8")));
|
|
170
185
|
disabled = config.disableAllHooks === true;
|
|
171
186
|
events = object(harness === "antigravity" ? config.hunch : config.hooks);
|
|
172
|
-
|
|
187
|
+
const commands = Object.values(events).flatMap(v => hookCommands(v));
|
|
188
|
+
recordPins(spec.hooks, commands);
|
|
189
|
+
if (commands.some(misroutedHook))
|
|
190
|
+
report.issues.push({
|
|
191
|
+
file: spec.hooks, code: "hook-command",
|
|
192
|
+
detail: "Hunch hooks invoke the MCP subcommand instead of the hook handler; run hunch integrations repair-pins",
|
|
193
|
+
});
|
|
173
194
|
}
|
|
174
195
|
catch (e) {
|
|
175
196
|
report.issues.push({ file: spec.hooks, code: "hook-config", detail: e.message });
|
|
@@ -178,6 +199,12 @@ export function inspectIntegrations(root, selected) {
|
|
|
178
199
|
for (const [i, capability] of ["context", "edit-blocking", "failure-capture", "compaction"].entries()) {
|
|
179
200
|
const event = spec.events[i];
|
|
180
201
|
const status = capabilities[capability];
|
|
202
|
+
const matchesProvider = (command) => {
|
|
203
|
+
if (misroutedHook(command))
|
|
204
|
+
return false;
|
|
205
|
+
const dialect = (publishedHookCommand(command) ?? command).match(/"?--provider"?\s+"?([a-z]+)"?/i)?.[1]?.toLowerCase() ?? "claude";
|
|
206
|
+
return dialect === harness;
|
|
207
|
+
};
|
|
181
208
|
if (!event) {
|
|
182
209
|
status.status = capability === "context" ? "advisory-only" : "unsupported";
|
|
183
210
|
status.detail = capability === "context" ? "Hunch relies on instructions and voluntary MCP calls on this adapter" : "No Hunch lifecycle adapter for this capability";
|
|
@@ -189,12 +216,15 @@ export function inspectIntegrations(root, selected) {
|
|
|
189
216
|
status.status = "unsupported";
|
|
190
217
|
status.detail = "Disabled by local hook settings, firmness, or HUNCH_PIPELINE";
|
|
191
218
|
}
|
|
192
|
-
else if (!hookCommands(events[event]).some(
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
219
|
+
else if (!hookCommands(events[event]).some(matchesProvider)) {
|
|
220
|
+
if (hookCommands(events[event], true).some(matchesProvider)) {
|
|
221
|
+
status.status = "unsupported";
|
|
222
|
+
status.detail = `Hunch ${event} handler disabled by local hook settings`;
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
status.detail = `Missing Hunch ${event} handler`;
|
|
226
|
+
report.issues.push({ file: spec.hooks, code: "missing-hook", detail: status.detail });
|
|
227
|
+
}
|
|
198
228
|
}
|
|
199
229
|
else if (capability === "edit-blocking" && firmness !== "strict") {
|
|
200
230
|
status.status = "advisory-only";
|
|
@@ -238,7 +268,8 @@ export function machineLocalIntegrationFiles(root) {
|
|
|
238
268
|
return [];
|
|
239
269
|
return (r.stdout ?? "").split(/\r?\n/).map(l => l.trim()).filter(Boolean);
|
|
240
270
|
}
|
|
241
|
-
/** Repair
|
|
271
|
+
/** Repair exact published pins and the known misplaced MCP hook subcommand.
|
|
272
|
+
* Preserve formatting and all other values, including disabled hook settings.
|
|
242
273
|
* Preflight every affected file before writing any; reject malformed JSON/TOML.
|
|
243
274
|
* `skip` leaves a file untouched (used to keep machine-local pins on a version
|
|
244
275
|
* npm can actually serve while a release is still publishing). */
|
|
@@ -262,7 +293,7 @@ export function repairIntegrationPins(root, opts = {}) {
|
|
|
262
293
|
if (!exactVersion.test(old))
|
|
263
294
|
throw new Error(`refusing non-exact Hunch pin in ${file}`);
|
|
264
295
|
return `@davesheffer/hunch@${version}`;
|
|
265
|
-
});
|
|
296
|
+
}).replace(/--package=@davesheffer\/hunch@/g, "--package=hunch-exact@npm:@davesheffer/hunch@");
|
|
266
297
|
let after;
|
|
267
298
|
if (name === "codex" && file === spec.mcp) {
|
|
268
299
|
readLauncher(root, "codex");
|
|
@@ -282,8 +313,14 @@ export function repairIntegrationPins(root, opts = {}) {
|
|
|
282
313
|
const config = object(parseJsonc(before));
|
|
283
314
|
const values = file === spec.mcp
|
|
284
315
|
? strings(object(object(config[spec.key]).hunch).args)
|
|
285
|
-
: Object.values(object(name === "antigravity" ? config.hunch : config.hooks)).flatMap(hookCommands);
|
|
286
|
-
const replacements = new Map(values.map(v =>
|
|
316
|
+
: Object.values(object(name === "antigravity" ? config.hunch : config.hooks)).flatMap(v => hookCommands(v, true));
|
|
317
|
+
const replacements = new Map(values.map(v => {
|
|
318
|
+
// Every recognized npm token is shell-safe. Bare tokens also repair
|
|
319
|
+
// the legacy quoted executable, which PowerShell treats as a string.
|
|
320
|
+
const published = file === spec.hooks ? publishedHookCommand(v) : undefined;
|
|
321
|
+
const repaired = published?.replace(" hunch mcp hook", " hunch hook") ?? v;
|
|
322
|
+
return [v, replace(repaired)];
|
|
323
|
+
}).filter(([a, b]) => a !== b));
|
|
287
324
|
const counts = new Map();
|
|
288
325
|
// Tokenize comments too, so a quoted command in a comment is untouched.
|
|
289
326
|
after = before.replace(/\/\/[^\n]*|\/\*[\s\S]*?\*\/|"(?:[^"\\]|\\.)*"/g, token => {
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davesheffer/hunch",
|
|
3
|
-
"version": "1.32.
|
|
3
|
+
"version": "1.32.8",
|
|
4
4
|
"mcpName": "io.github.davesheffer/hunch",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Dave Sheffer <dave.sheffer1@gmail.com>",
|
|
7
|
-
"description": "
|
|
7
|
+
"description": "A shared record for AI agents: decisions, completed work, and commitments, with sources. Git-native engineering memory and a self-hosted state server.",
|
|
8
8
|
"homepage": "https://www.hunchmemory.com",
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
package/server.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.davesheffer/hunch",
|
|
4
|
-
"description": "
|
|
4
|
+
"description": "Shared records for AI agents: engineering decisions, bug history, rules, and work state through MCP.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"url": "https://github.com/davesheffer/hunch",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
9
|
"websiteUrl": "https://www.hunchmemory.com",
|
|
10
|
-
"version": "1.32.
|
|
10
|
+
"version": "1.32.8",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "@davesheffer/hunch",
|
|
16
|
-
"version": "1.32.
|
|
16
|
+
"version": "1.32.8",
|
|
17
17
|
"runtimeHint": "npx",
|
|
18
18
|
"packageArguments": [
|
|
19
19
|
{
|