@davesheffer/hunch 0.17.2 → 0.17.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/dist/cli/index.js +21 -4
- package/dist/integrations/hooks.js +5 -3
- package/package.json +1 -1
package/dist/cli/index.js
CHANGED
|
@@ -67,6 +67,7 @@ program
|
|
|
67
67
|
.option("--no-agent-hooks", "skip installing the Claude Code agent hooks (.claude/settings.json)")
|
|
68
68
|
.option("--firmness <level>", "agent-hook firmness: off | advisory | firm | strict")
|
|
69
69
|
.option("--private-sync", "post-commit synthesis writes captured decisions into the private overlay (HUNCH_PRIVATE_DIR), never the public repo")
|
|
70
|
+
.option("--auto-commit", "opt-in: the post-commit hook also git add+commit+pushes the captured decision (the repo it landed in)")
|
|
70
71
|
.action((opts) => {
|
|
71
72
|
// Validate --firmness up front, before any side effects (indexing, git hooks,
|
|
72
73
|
// .mcp.json) or opening the store — a bad value must not leave a half-init.
|
|
@@ -95,8 +96,8 @@ program
|
|
|
95
96
|
console.log(` ⚠ ${res.skipped} file(s) could not be parsed (skipped)`);
|
|
96
97
|
}
|
|
97
98
|
if (isGitRepo(root)) {
|
|
98
|
-
const h = installPostCommitHook(root, inv.shell, { private: opts.privateSync });
|
|
99
|
-
console.log(` ✓ post-commit hook ${h.action} (learning loop)${opts.privateSync ? " — syncs to the private overlay" : ""}`);
|
|
99
|
+
const h = installPostCommitHook(root, inv.shell, { private: opts.privateSync, commit: opts.autoCommit });
|
|
100
|
+
console.log(` ✓ post-commit hook ${h.action} (learning loop)${opts.privateSync ? " — syncs to the private overlay" : ""}${opts.autoCommit ? " — auto-commit+push on" : ""}`);
|
|
100
101
|
const m = installMergeDriver(root, inv.shell);
|
|
101
102
|
console.log(` ✓ team merge driver ${m.action}`);
|
|
102
103
|
// Auto-install the pre-commit guard by default (advisory: flags invariants
|
|
@@ -227,6 +228,7 @@ program
|
|
|
227
228
|
.option("--quiet", "minimal output")
|
|
228
229
|
.option("--force", "re-synthesize even if a decision already exists for the commit")
|
|
229
230
|
.option("--private", "write the synthesized decision into the private overlay (HUNCH_PRIVATE_DIR), not the public repo — for a repo whose memory is kept private")
|
|
231
|
+
.option("--commit", "after a capture, also git add+commit+push the repo the decision landed in (opt-in; best-effort) — the private store under --private, else this repo")
|
|
230
232
|
.action(async (sha, opts) => {
|
|
231
233
|
const { store, root } = storeFor();
|
|
232
234
|
if (!isGitRepo(root))
|
|
@@ -243,6 +245,20 @@ program
|
|
|
243
245
|
// on every commit. `hunch index`/`init` refresh it intentionally instead.
|
|
244
246
|
if (!opts.fromHook)
|
|
245
247
|
updateClaudeMd(root, store);
|
|
248
|
+
// Opt-in: persist the captured decision in the repo it landed in (private store
|
|
249
|
+
// under --private, else this repo). Best-effort — a non-repo dir / offline push
|
|
250
|
+
// just no-ops. Stage ONLY the hunch dir (never sweep unrelated working-tree
|
|
251
|
+
// changes), and set HUNCH_SYNC=1 so the commit we create can't re-trigger this
|
|
252
|
+
// hook (no recursion, including on a manual `hunch sync --commit`).
|
|
253
|
+
const commitTarget = opts.commit ? (opts.private ? store.privateDir : hunchPaths(root).hunch) : undefined;
|
|
254
|
+
if (commitTarget) {
|
|
255
|
+
const g = (args) => { spawnSync("git", ["-C", commitTarget, ...args], { stdio: "ignore", env: { ...process.env, HUNCH_SYNC: "1" } }); };
|
|
256
|
+
g(["add", "--", "."]);
|
|
257
|
+
g(["commit", "-m", `hunch: capture ${r.decision?.id ?? "decision"}`]);
|
|
258
|
+
g(["push"]);
|
|
259
|
+
if (!opts.quiet)
|
|
260
|
+
console.log(` ↳ committed + pushed ${r.decision?.id} (${commitTarget})`);
|
|
261
|
+
}
|
|
246
262
|
if (!opts.quiet)
|
|
247
263
|
console.log(`✓ captured decision ${r.decision?.id} via ${r.provider}: "${r.decision?.title}"`);
|
|
248
264
|
}
|
|
@@ -257,6 +273,7 @@ program
|
|
|
257
273
|
.description("Enable a PRIVATE memory overlay — sensitive decisions/bugs/constraints kept in a separate location, unioned into local queries, never committed here. Writes a gitignored .hunch/local.json so it's auto-detected (no env var needed).")
|
|
258
274
|
.option("--repo <url>", "clone a private git repo to use as the store (into ./.hunch-private)")
|
|
259
275
|
.option("--no-hook", "don't switch the post-commit hook to private sync")
|
|
276
|
+
.option("--auto-commit", "opt-in: the post-commit hook also git add+commit+pushes the private repo after each capture")
|
|
260
277
|
.action((dir, opts) => {
|
|
261
278
|
const root = findRoot();
|
|
262
279
|
const paths = hunchPaths(root);
|
|
@@ -290,8 +307,8 @@ program
|
|
|
290
307
|
let hookNote = "";
|
|
291
308
|
if (opts.hook && isGitRepo(root)) {
|
|
292
309
|
const inv = resolveInvocation();
|
|
293
|
-
const h = installPostCommitHook(root, inv.shell, { private: true });
|
|
294
|
-
hookNote = ` ✓ post-commit hook ${h.action} — captured decisions route here\n`;
|
|
310
|
+
const h = installPostCommitHook(root, inv.shell, { private: true, commit: opts.autoCommit });
|
|
311
|
+
hookNote = ` ✓ post-commit hook ${h.action} — captured decisions route here${opts.autoCommit ? " (auto-commit+push on)" : ""}\n`;
|
|
295
312
|
}
|
|
296
313
|
console.log(`✓ private overlay enabled → ${hunchDir}\n` +
|
|
297
314
|
` ✓ recorded in .hunch/local.json (gitignored) — auto-detected, no env var or shell-profile edit\n` +
|
|
@@ -11,14 +11,16 @@ const MARK = "# >>> hunch post-commit >>>";
|
|
|
11
11
|
const ENDMARK = "# <<< hunch post-commit <<<";
|
|
12
12
|
function block(invocation, opts = {}) {
|
|
13
13
|
// --private routes the auto-synthesized decision into the HUNCH_PRIVATE_DIR overlay
|
|
14
|
-
// instead of the public repo.
|
|
15
|
-
//
|
|
14
|
+
// instead of the public repo. --commit (opt-in) also commits & pushes the repo the
|
|
15
|
+
// decision landed in (the private store under --private, else this repo). The hook
|
|
16
|
+
// script is local (.git/hooks/), never committed.
|
|
16
17
|
const priv = opts.private ? " --private" : "";
|
|
18
|
+
const commit = opts.commit ? " --commit" : "";
|
|
17
19
|
return [
|
|
18
20
|
MARK,
|
|
19
21
|
'if [ -z "$HUNCH_SYNC" ]; then',
|
|
20
22
|
" export HUNCH_SYNC=1",
|
|
21
|
-
` ( ${invocation} sync --from-hook --quiet${priv} >/dev/null 2>&1 || true ) &`,
|
|
23
|
+
` ( ${invocation} sync --from-hook --quiet${priv}${commit} >/dev/null 2>&1 || true ) &`,
|
|
22
24
|
"fi",
|
|
23
25
|
ENDMARK,
|
|
24
26
|
].join("\n");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@davesheffer/hunch",
|
|
3
|
-
"version": "0.17.
|
|
3
|
+
"version": "0.17.3",
|
|
4
4
|
"license": "Apache-2.0",
|
|
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.",
|