@davesheffer/hunch 0.14.0 → 0.14.1
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 +4 -2
- package/dist/synthesis/provider.js +15 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -109,8 +109,10 @@ The MCP tools Claude calls under the hood: `hunch_why`, `hunch_query`,
|
|
|
109
109
|
`hunch_check_constraints`, `hunch_get_dependents` (blast radius), `hunch_blast_radius`
|
|
110
110
|
(dependent files + near-violations a change could break indirectly), `hunch_bug_lineage`,
|
|
111
111
|
`hunch_context` (surgical minimal slice for a task), `hunch_timeline` (a target's decision
|
|
112
|
-
history over time), `
|
|
113
|
-
|
|
112
|
+
history over time), `hunch_merge_verdict` (a cited BLOCK/WARN/PASS over a diff — see below),
|
|
113
|
+
and the write-backs `hunch_record_decision`, `hunch_record_correction` (turn a correction into
|
|
114
|
+
an enforced invariant — see below). `hunch_why` and `hunch_context` take an optional `as_of`
|
|
115
|
+
(commit/tag/branch) to **time-travel** the graph to a past state.
|
|
114
116
|
|
|
115
117
|
### Works with any MCP assistant
|
|
116
118
|
|
|
@@ -177,6 +177,18 @@ class CliSynthProvider {
|
|
|
177
177
|
return draft;
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
|
+
// A model id comes from a HUNCH_*_MODEL env var and ends up as an argv token that,
|
|
181
|
+
// on Windows, pexecIn joins into the cmd.exe line (shell:true, to resolve the npm
|
|
182
|
+
// `.cmd` shim). The untrusted prompt always travels via stdin — never argv — so the
|
|
183
|
+
// ONLY non-literal token reaching that shell line is this model id. Reject anything
|
|
184
|
+
// with whitespace or a cmd.exe metacharacter so a poisoned env var can't smuggle
|
|
185
|
+
// `& evil.exe` into the line; fall back to the provider default rather than crash on
|
|
186
|
+
// a mere typo. (pexecIn itself stays general — callers may legitimately pass a
|
|
187
|
+
// pre-quoted path token — so the guard lives here, at the untrusted-input source.)
|
|
188
|
+
const MODEL_RE = /^[A-Za-z0-9._:/-]+$/;
|
|
189
|
+
export function safeModel(v, fallback) {
|
|
190
|
+
return v && MODEL_RE.test(v) ? v : fallback;
|
|
191
|
+
}
|
|
180
192
|
// --------------------------------------------------------------------------
|
|
181
193
|
// Provider A: headless `claude -p` CLI — billed to the user's Claude subscription
|
|
182
194
|
// --------------------------------------------------------------------------
|
|
@@ -184,7 +196,7 @@ class ClaudeCliProvider extends CliSynthProvider {
|
|
|
184
196
|
name = "claude-cli";
|
|
185
197
|
// Default to the `haiku` alias (cheap/fast, and survives model retirements)
|
|
186
198
|
// rather than a pinned dated id; override with HUNCH_SYNTH_MODEL if needed.
|
|
187
|
-
model = process.env.HUNCH_SYNTH_MODEL
|
|
199
|
+
model = safeModel(process.env.HUNCH_SYNTH_MODEL, "haiku");
|
|
188
200
|
async available() {
|
|
189
201
|
try {
|
|
190
202
|
await pexecIn("claude", ["--version"], { timeout: 8000 });
|
|
@@ -242,7 +254,7 @@ class ClaudeCliProvider extends CliSynthProvider {
|
|
|
242
254
|
// --------------------------------------------------------------------------
|
|
243
255
|
class CodexCliProvider extends CliSynthProvider {
|
|
244
256
|
name = "codex-cli";
|
|
245
|
-
model = process.env.HUNCH_CODEX_MODEL; // omit → codex uses its configured default
|
|
257
|
+
model = safeModel(process.env.HUNCH_CODEX_MODEL, undefined); // omit → codex uses its configured default
|
|
246
258
|
async available() {
|
|
247
259
|
try {
|
|
248
260
|
await pexecIn("codex", ["--version"], { timeout: 8000 });
|
|
@@ -266,7 +278,7 @@ class CodexCliProvider extends CliSynthProvider {
|
|
|
266
278
|
// --------------------------------------------------------------------------
|
|
267
279
|
class CursorCliProvider extends CliSynthProvider {
|
|
268
280
|
name = "cursor-agent";
|
|
269
|
-
model = process.env.HUNCH_CURSOR_MODEL;
|
|
281
|
+
model = safeModel(process.env.HUNCH_CURSOR_MODEL, undefined);
|
|
270
282
|
async available() {
|
|
271
283
|
try {
|
|
272
284
|
await pexecIn("cursor-agent", ["--version"], { timeout: 8000 });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davesheffer/hunch",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Dave Sheffer <dave.sheffer1@gmail.com>",
|
|
6
6
|
"description": "Hunch — an Engineering Memory OS: a persistent, git-native reasoning graph over a codebase, exposed to Claude Code via MCP.",
|
|
@@ -20,7 +20,8 @@
|
|
|
20
20
|
"dist/**/*.js"
|
|
21
21
|
],
|
|
22
22
|
"publishConfig": {
|
|
23
|
-
"access": "public"
|
|
23
|
+
"access": "public",
|
|
24
|
+
"provenance": true
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"claude-code",
|