@davesheffer/hunch 1.2.2 โ 1.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.
- package/README.md +2 -0
- package/dist/cli/index.js +9 -3
- package/dist/extractors/indexer.js +5 -1
- package/dist/integrations/scaffold.js +15 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,8 @@ guards, troubleshooting. This README is the tour. Jump to:
|
|
|
44
44
|
[CLI reference](https://hunch-pi.vercel.app/docs#cli) ยท
|
|
45
45
|
[Troubleshooting](https://hunch-pi.vercel.app/docs#doctor)
|
|
46
46
|
|
|
47
|
+
> ๐ **v1.2.2** โ the [component wiki + specs ledger](https://hunch-pi.vercel.app/docs#wiki): Hunch takes over your stale docs โ graded deterministically, adopted into a graph-healed wiki copy, never rewriting your originals โ with staleness drift-gated in CI. Plus honest auto-commit reporting, a friendly Node < 22.13 gate, and churn-free reindexing. [Full changelog โ](https://hunch-pi.vercel.app/changelog)
|
|
48
|
+
|
|
47
49
|
## The problem
|
|
48
50
|
|
|
49
51
|
Every AI coding session starts from zero. The model re-reads your code, re-guesses the
|
package/dist/cli/index.js
CHANGED
|
@@ -150,11 +150,17 @@ program
|
|
|
150
150
|
else {
|
|
151
151
|
console.log(" โ not a git repo โ skipped hooks (run `git init` to enable the learning loop)");
|
|
152
152
|
}
|
|
153
|
-
const mcp = writeMcpJson(root, inv.mcp);
|
|
154
153
|
// .mcp.json is the CANONICAL registration: Claude Code resolves it by file path,
|
|
155
154
|
// so it's immune to the Windows ~/.claude.json drive-letter case-split that a
|
|
156
|
-
// global `claude mcp add` is prone to (see `hunch doctor`).
|
|
157
|
-
|
|
155
|
+
// global `claude mcp add` is prone to (see `hunch doctor`). An unparseable
|
|
156
|
+
// existing file is refused (con_8460b6770f) โ warn and continue, never clobber.
|
|
157
|
+
try {
|
|
158
|
+
const mcp = writeMcpJson(root, inv.mcp);
|
|
159
|
+
console.log(` โ wrote ${rel(root, mcp)} (registers the Hunch MCP server โ canonical, path-keyed; prefer over a global \`claude mcp add\`)`);
|
|
160
|
+
}
|
|
161
|
+
catch (e) {
|
|
162
|
+
console.log(` โ skipped .mcp.json: ${e.message}`);
|
|
163
|
+
}
|
|
158
164
|
const cmds = writeSlashCommands(root);
|
|
159
165
|
console.log(` โ wrote ${cmds.length} slash commands (/hunch-why, /hunch-fix, /hunch-fragile)`);
|
|
160
166
|
const cmd = updateClaudeMd(root, store);
|
|
@@ -191,7 +191,11 @@ export function indexRepo(store, root, opts = {}) {
|
|
|
191
191
|
// ---- helpers --------------------------------------------------------------
|
|
192
192
|
function listCodeFiles(root) {
|
|
193
193
|
if (isGitRepo(root)) {
|
|
194
|
-
|
|
194
|
+
// Apply SKIP_DIRS to the git-tracked list too: a repo that (accidentally)
|
|
195
|
+
// tracks node_modules/ or dist/ must not flood the graph with vendored symbols.
|
|
196
|
+
const tracked = trackedFiles(root, CODE_EXTS)
|
|
197
|
+
.filter((f) => !f.split(/[\\/]/).some((seg) => SKIP_DIRS.has(seg)))
|
|
198
|
+
.map((f) => join(root, f));
|
|
195
199
|
if (tracked.length > 0)
|
|
196
200
|
return tracked; // else fall through (nothing committed yet)
|
|
197
201
|
}
|
|
@@ -5,16 +5,25 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs";
|
|
7
7
|
import { join, dirname } from "node:path";
|
|
8
|
-
/** Merge a `hunch` server entry into .mcp.json, preserving other servers.
|
|
8
|
+
/** Merge a `hunch` server entry into .mcp.json, preserving other servers.
|
|
9
|
+
* A non-empty file we cannot parse THROWS instead of being silently replaced
|
|
10
|
+
* (con_8460b6770f โ it may hold the user's other MCP servers); the caller
|
|
11
|
+
* degrades that to a warning. */
|
|
9
12
|
export function writeMcpJson(root, inv) {
|
|
10
13
|
const file = join(root, ".mcp.json");
|
|
11
14
|
let json = {};
|
|
12
15
|
if (existsSync(file)) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
const raw = readFileSync(file, "utf8");
|
|
17
|
+
if (raw.trim()) {
|
|
18
|
+
try {
|
|
19
|
+
const v = JSON.parse(raw);
|
|
20
|
+
if (!v || typeof v !== "object" || Array.isArray(v))
|
|
21
|
+
throw new Error("not a JSON object");
|
|
22
|
+
json = v;
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
throw new Error(`refusing to overwrite ${file}: could not parse it (${e.message}). Fix or remove it, then re-run.`);
|
|
26
|
+
}
|
|
18
27
|
}
|
|
19
28
|
}
|
|
20
29
|
json.mcpServers = json.mcpServers ?? {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davesheffer/hunch",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"author": "Dave Sheffer <dave.sheffer1@gmail.com>",
|
|
6
6
|
"description": "Architectural Conformance for AI-generated code: a git-native graph that deterministically blocks AI changes which break your architecture โ the semantic invariants (layering, must-reach, dependency direction) pattern-SAST can't express โ grounded in the decisions and bugs behind each rule, across any MCP assistant (Claude Code, Cursor, Copilot, Windsurf, Codex).",
|