@davesheffer/hunch 1.23.3 → 1.24.0
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 +18 -0
- package/dist/cli/index.js +2 -0
- package/dist/cli/update.js +72 -0
- package/dist/integrations/claudemd.js +1 -0
- package/package.json +2 -2
- package/server.json +2 -2
package/README.md
CHANGED
|
@@ -49,6 +49,24 @@ assistants without replacing their existing configuration. The next session rece
|
|
|
49
49
|
story with its sources, not a giant transcript or a generic prompt wall. Lifecycle coverage
|
|
50
50
|
depends on the harness; MCP connectivity alone does not establish automatic grounding or enforcement.
|
|
51
51
|
|
|
52
|
+
To update Hunch and all configured harness pins for the current repository:
|
|
53
|
+
|
|
54
|
+
```sh
|
|
55
|
+
hunch update
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Agents receive an instruction to run this when you ask **“update Hunch”** in the generated
|
|
59
|
+
Hunch guidance. The command resolves npm's latest release, updates an existing dependency
|
|
60
|
+
to an exact version in its current dependency section, then runs the new version's pin
|
|
61
|
+
repair and integration check. Without a repository dependency it updates the global CLI.
|
|
62
|
+
Use `--global` to also update the global CLI when a local dependency exists, or `--dry-run`
|
|
63
|
+
to preview the commands. Restart active harnesses afterward. This applies to the current
|
|
64
|
+
repository, not every project on your machine. Automatic dependency installation currently
|
|
65
|
+
supports standalone npm projects; other package managers should update their dependency
|
|
66
|
+
explicitly and then use `hunch integrations repair-pins`. Existing hook settings are preserved.
|
|
67
|
+
An installation or check failure stops the command with a nonzero exit; completed npm
|
|
68
|
+
changes are not rolled back. Fix the reported issue and rerun the command.
|
|
69
|
+
|
|
52
70
|
Check the repository's integrations after upgrading Hunch or switching assistants:
|
|
53
71
|
|
|
54
72
|
```sh
|
package/dist/cli/index.js
CHANGED
|
@@ -25,6 +25,7 @@ import { writeFileAtomic } from "../core/io.js";
|
|
|
25
25
|
import { looksLikeCorrection, CORRECTION_NUDGE } from "../core/correction.js";
|
|
26
26
|
import { HUNCH_VERSION } from "../core/version.js";
|
|
27
27
|
import { registerIntegrationCommands } from "./integrations.js";
|
|
28
|
+
import { registerUpdateCommand } from "./update.js";
|
|
28
29
|
import { inspectIntegrations, formatIntegrationHealth, integrationHealthFails, integrationSessionWarning } from "../integrations/health.js";
|
|
29
30
|
import { HunchStore } from "../store/hunchStore.js";
|
|
30
31
|
import { JsonStore } from "../store/jsonStore.js";
|
|
@@ -112,6 +113,7 @@ import { resolveInvocation, dim, synthesisStatusLines, maybeWarnOllamaContext }
|
|
|
112
113
|
const program = new Command();
|
|
113
114
|
program.name("hunch").description("Hunch — engineering memory and a deterministic Change Gate for AI-assisted codebases.").version(HUNCH_VERSION);
|
|
114
115
|
registerIntegrationCommands(program);
|
|
116
|
+
registerUpdateCommand(program);
|
|
115
117
|
let openStore = null;
|
|
116
118
|
function openTeamStore(root, opts = {}) {
|
|
117
119
|
// A committed team.json is an explicit declaration that this checkout belongs
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { findRoot } from "../core/paths.js";
|
|
5
|
+
const PACKAGE = "@davesheffer/hunch";
|
|
6
|
+
/** Arguments come only from fixed commands and a validated registry version.
|
|
7
|
+
* Windows needs the shell to resolve npm.cmd; cwd is never interpolated. */
|
|
8
|
+
export function runNpm(root, args, capture = false) {
|
|
9
|
+
if (args.some(arg => !/^[a-zA-Z0-9@/_.=+:-]+$/.test(arg)))
|
|
10
|
+
throw new Error("unsafe npm argument");
|
|
11
|
+
const windows = process.platform === "win32";
|
|
12
|
+
const result = spawnSync(windows ? `npm ${args.join(" ")}` : "npm", windows ? [] : args, {
|
|
13
|
+
cwd: root, shell: windows, windowsHide: true,
|
|
14
|
+
encoding: "utf8", stdio: capture ? ["ignore", "pipe", "pipe"] : "inherit",
|
|
15
|
+
});
|
|
16
|
+
if (result.error)
|
|
17
|
+
throw result.error;
|
|
18
|
+
if (result.status !== 0)
|
|
19
|
+
throw new Error(`npm ${args.join(" ")} failed (${result.status ?? result.signal})${result.stderr ? `: ${result.stderr.trim()}` : ""}`);
|
|
20
|
+
return result.stdout ?? "";
|
|
21
|
+
}
|
|
22
|
+
/** Fresh child execution is essential: the currently running CLI still has the
|
|
23
|
+
* old modules loaded after npm replaces its installation. */
|
|
24
|
+
export function updateHunch(root, opts = {}, run = (args, capture) => runNpm(root, args, capture), log = console.log) {
|
|
25
|
+
const file = join(root, "package.json");
|
|
26
|
+
const manifest = existsSync(file) ? JSON.parse(readFileSync(file, "utf8")) : {};
|
|
27
|
+
if (!manifest || typeof manifest !== "object" || Array.isArray(manifest))
|
|
28
|
+
throw new Error("package.json must contain an object");
|
|
29
|
+
if (manifest.name === PACKAGE)
|
|
30
|
+
throw new Error("Run hunch update in a consumer repository, not Hunch's own source checkout.");
|
|
31
|
+
const sections = ["dependencies", "devDependencies", "optionalDependencies"];
|
|
32
|
+
const declared = sections.filter(section => {
|
|
33
|
+
const deps = manifest[section];
|
|
34
|
+
if (deps !== undefined && (!deps || typeof deps !== "object" || Array.isArray(deps)))
|
|
35
|
+
throw new Error(`invalid ${section} in package.json`);
|
|
36
|
+
return deps && Object.hasOwn(deps, PACKAGE);
|
|
37
|
+
});
|
|
38
|
+
if (declared.length > 1)
|
|
39
|
+
throw new Error("Hunch is declared in multiple dependency sections; resolve the duplicate before updating.");
|
|
40
|
+
if (declared.length && (manifest.workspaces || (manifest.packageManager && !/^npm@/.test(manifest.packageManager)) || ["pnpm-lock.yaml", "yarn.lock", "bun.lock", "bun.lockb"].some(name => existsSync(join(root, name))))) {
|
|
41
|
+
throw new Error("Automatic dependency updates currently support standalone npm projects. Update Hunch to an exact version with your package manager, then run hunch integrations repair-pins.");
|
|
42
|
+
}
|
|
43
|
+
const version = JSON.parse(run(["view", `${PACKAGE}@latest`, "version", "--json"], true));
|
|
44
|
+
if (typeof version !== "string" || !/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(version))
|
|
45
|
+
throw new Error("npm returned an invalid Hunch version");
|
|
46
|
+
const spec = `${PACKAGE}@${version}`;
|
|
47
|
+
const commands = [];
|
|
48
|
+
if (declared.length) {
|
|
49
|
+
const flag = { dependencies: "--save-prod", devDependencies: "--save-dev", optionalDependencies: "--save-optional" }[declared[0]];
|
|
50
|
+
commands.push(["install", flag, "--save-exact", spec]);
|
|
51
|
+
}
|
|
52
|
+
if (!declared.length || opts.global)
|
|
53
|
+
commands.push(["install", "--global", spec]);
|
|
54
|
+
// The alias prevents npm exec from substituting a stale local hunch binary.
|
|
55
|
+
commands.push(["exec", "--yes", `--package=hunch-exact@npm:${spec}`, "--", "hunch", "integrations", "repair-pins"]);
|
|
56
|
+
log(`${opts.dryRun ? "Preview" : "Updating"}: Hunch ${version} for ${root}`);
|
|
57
|
+
for (const args of commands) {
|
|
58
|
+
log(`npm ${args.join(" ")}`);
|
|
59
|
+
if (!opts.dryRun)
|
|
60
|
+
run(args);
|
|
61
|
+
}
|
|
62
|
+
if (!opts.dryRun)
|
|
63
|
+
log("Hunch updated; repository integration check passed. Restart or reconnect active harnesses to load the new MCP version.");
|
|
64
|
+
}
|
|
65
|
+
export function registerUpdateCommand(program) {
|
|
66
|
+
program.command("update")
|
|
67
|
+
.description("Update Hunch to latest and repair all configured harness pins in this repository")
|
|
68
|
+
.option("--global", "also update the global CLI when a repository dependency exists")
|
|
69
|
+
.option("--dry-run", "resolve latest and print commands without changing files")
|
|
70
|
+
.action((opts) => updateHunch(findRoot(), opts));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -46,6 +46,7 @@ export function renderHunchSection(store, root) {
|
|
|
46
46
|
lines.push("**Consult Hunch via the `hunch_*` MCP tools — pick by MOMENT, not from memory:**");
|
|
47
47
|
lines.push("");
|
|
48
48
|
lines.push("**Orient (session/task start):**");
|
|
49
|
+
lines.push("- When the user asks to **update Hunch**, run `hunch update` from this repository root. It updates to the latest release and repairs all configured harness pins. Use `hunch update --global` to also update a global CLI alongside a repository dependency; reconnect active MCP sessions afterward.");
|
|
49
50
|
lines.push("- `hunch_context(target)` — the minimal relevant slice for what you're about to do; a task phrase falls back to the closest graph matches. **Call FIRST.**");
|
|
50
51
|
lines.push("- `hunch_structure(target?)` — the indexed shape of the repo/dir/file/symbol — orient from the graph, not grep rounds.");
|
|
51
52
|
lines.push("- `hunch_runbook(task)` — the proven steps for a recurring task, before re-deriving them.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davesheffer/hunch",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.24.0",
|
|
4
4
|
"mcpName": "io.github.davesheffer/hunch",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Dave Sheffer <dave.sheffer1@gmail.com>",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"node": ">=22.13.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|
|
72
|
-
"version": "node tooling/sync-version-pins.mjs && git add plugin/.mcp.json server.json",
|
|
72
|
+
"version": "node tooling/sync-version-pins.mjs && git add plugin/.mcp.json server.json .windsurf/hooks.json",
|
|
73
73
|
"sync-version-pins": "node tooling/sync-version-pins.mjs",
|
|
74
74
|
"clean": "node --input-type=commonjs -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
75
75
|
"build": "npm run clean && tsc -p tsconfig.json",
|
package/server.json
CHANGED
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
9
|
"websiteUrl": "https://www.hunchmemory.com",
|
|
10
|
-
"version": "1.
|
|
10
|
+
"version": "1.24.0",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "npm",
|
|
14
14
|
"registryBaseUrl": "https://registry.npmjs.org",
|
|
15
15
|
"identifier": "@davesheffer/hunch",
|
|
16
|
-
"version": "1.
|
|
16
|
+
"version": "1.24.0",
|
|
17
17
|
"runtimeHint": "npx",
|
|
18
18
|
"packageArguments": [
|
|
19
19
|
{
|