@davesheffer/hunch 1.32.1 → 1.32.2

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 CHANGED
@@ -80,8 +80,9 @@ import { appendEvent, readEvents } from "../core/events.js";
80
80
  import { computeStats, formatStats } from "../core/stats.js";
81
81
  import { injectionMode, resetSessionInjections } from "../core/hookcache.js";
82
82
  import { recordServed, servedSummary } from "../core/served.js";
83
- import { recordTaskDelivery, reportActivity } from "../core/taskReport.js";
83
+ import { recordTaskDelivery, reportActivity, reportPresentationEnabled, unseenLessons } from "../core/taskReport.js";
84
84
  import { snapshotDeliveredRecords } from "../core/taskReportEvidence.js";
85
+ import { renderRecalledLine } from "../core/taskReportRender.js";
85
86
  import { hookReportTaskId, startHookReport, stopHookReport, observeHookDenial } from "../core/taskReportHook.js";
86
87
  import { recordHookObservation } from "../core/hookObservations.js";
87
88
  import { contextHookOutput, denyHookOutput, hookProvider, normalizeHookEvent, stopHookOutput } from "../core/agenthook.js";
@@ -90,7 +91,7 @@ import { draftDuplicateOf, isAcceptedDuplicateAnchor } from "../core/dupdetect.j
90
91
  import { planAutoReview, planMutations } from "../core/autoreview.js";
91
92
  import { loadGoldenSet, evaluateRetrieval, evaluateTraversalLift } from "../eval/harness.js";
92
93
  import { loadGuardCases, evalGuards, generateGuardCases } from "../eval/guards.js";
93
- import { computeDrift } from "../core/drift.js";
94
+ import { DRIFT_KINDS, computeDrift } from "../core/drift.js";
94
95
  import { renderCompilerScorecard, scoreCompilerCaseBank } from "../constitution/scorecard.js";
95
96
  import { generateWiki, wikiStatus, wikiPrompt, publicHome, privateHome, readWikiManifestAt, nowData } from "../wiki/wiki.js";
96
97
  import { adoptProsePrompt } from "../wiki/adopt.js";
@@ -108,6 +109,7 @@ import { MAX_LANDSCAPE_REFRESH_REVISIONS, planLandscapeAdoption, } from "../core
108
109
  import { discoverRepositoryLandscape } from "../extractors/landscapeDiscovery.js";
109
110
  import { checkConformance } from "../core/conformance.js";
110
111
  import { ConstitutionService, policyEvaluationEnvelope } from "../constitution/service.js";
112
+ import { renderPolicyEvaluations } from "../constitution/renderEvaluations.js";
111
113
  import { sourceGraphSnapshot } from "../constitution/evaluator.js";
112
114
  import { renderProofCard } from "../constitution/card.js";
113
115
  import { movePolicyArtifactsToPrivate } from "../constitution/repository.js";
@@ -2295,20 +2297,6 @@ policyCmd
2295
2297
  store.close();
2296
2298
  }
2297
2299
  });
2298
- function renderPolicyEvaluations(results) {
2299
- if (!results.length)
2300
- return ["No Constitution policies matched."];
2301
- const icon = { satisfied: "✅", violated: "⛔", not_applicable: "·", unknown: "?", error: "‼" };
2302
- const out = [`Constitution policy evaluation: ${results.length} canonical receipt(s)`];
2303
- for (const r of results) {
2304
- out.push(` ${icon[r.evaluation.result] ?? "·"} ${r.policy.id} [${r.policy.state}] ${r.evaluation.result}${r.blocks ? " — BLOCK" : ""}`);
2305
- out.push(` ${r.evaluation.explanation}`);
2306
- if (r.gate_error)
2307
- out.push(` gate error: ${r.gate_error}`);
2308
- out.push(` receipt: ${r.evaluation.deterministic_hash}`);
2309
- }
2310
- return out;
2311
- }
2312
2300
  // ---- constitution (deterministic evidence -> candidate bootstrap) --------
2313
2301
  const constitutionCmd = program
2314
2302
  .command("constitution")
@@ -4201,8 +4189,9 @@ program
4201
4189
  if (opts.task) {
4202
4190
  try {
4203
4191
  const records = asOf ? [] : snapshotDeliveredRecords(store, envelope);
4192
+ const recalled = renderRecalledLine(unseenLessons(root, opts.task, records));
4204
4193
  const occurrence = recordTaskDelivery(root, opts.task, envelope, records);
4205
- console.log(`\nTask evidence: ${opts.task} · occurrence ${occurrence}`);
4194
+ console.log(`\n${recalled ? `${recalled}\n` : ""}Task evidence: ${opts.task} · occurrence ${occurrence}`);
4206
4195
  }
4207
4196
  catch {
4208
4197
  console.error(`Task evidence could not be recorded for ${opts.task}; context remains available but report attribution is unverified.`);
@@ -4894,16 +4883,22 @@ program
4894
4883
  }
4895
4884
  receipts("served");
4896
4885
  let reportNotice = "";
4886
+ let recalled = null;
4897
4887
  if (reportTaskId) {
4898
4888
  try {
4899
- const occurrence = recordTaskDelivery(root, reportTaskId, envelope, snapshotDeliveredRecords(store, envelope));
4889
+ const snapshots = snapshotDeliveredRecords(store, envelope);
4890
+ // The first time a lesson reaches this prompt's task, tell the USER in one
4891
+ // line (systemMessage); repeats of the same revision stay silent.
4892
+ recalled = reportPresentationEnabled(root) ? renderRecalledLine(unseenLessons(root, reportTaskId, snapshots)) : null;
4893
+ const occurrence = recordTaskDelivery(root, reportTaskId, envelope, snapshots);
4900
4894
  reportNotice = `\n\nHunch task ${reportTaskId} · delivery ${occurrence}. Inspect exact application references with hunch_report(task_id).`;
4901
4895
  }
4902
4896
  catch {
4903
4897
  reportNotice = "\n\nTask report observation unavailable; this delivery's task contribution remains unverified.";
4898
+ recalled = null;
4904
4899
  }
4905
4900
  }
4906
- emitContext(provider, "PreToolUse", text + reportNotice);
4901
+ emitContext(provider, "PreToolUse", text + reportNotice, recalled ?? undefined);
4907
4902
  }
4908
4903
  catch {
4909
4904
  // swallow — never block an edit on a hook failure
@@ -6031,8 +6026,13 @@ program
6031
6026
  // ---- drift (doc≠graph detector; advisory + CI-gateable) -------------------
6032
6027
  program
6033
6028
  .command("drift")
6034
- .description("Detect memory drift: dead refs, dangling supersedes, stale 'proposed' docs, commit-unresolvable (a decision cites a commit that no longer resolves in this repository), doc≠graph anchor-stale (a file still anchored to a superseded decision), markdown sections whose <!-- hunch:topic … dec_id --> pin points at a superseded or missing decision (AGENTS.md/CLAUDE.md as a drift surface), and ledger≠records replay divergence when this partition has a change ledger. Exits non-zero on any anchor-stale drift, topic collision or replay divergence — the doc≠graph and ledger≠records gate.")
6035
- .action(() => {
6029
+ .description("Detect memory drift: dead refs, dangling supersedes, stale 'proposed' docs, commit-unresolvable (a decision cites a commit that no longer resolves in this repository), doc≠graph anchor-stale (a file still anchored to a superseded decision), markdown sections whose <!-- hunch:topic … dec_id --> pin points at a superseded or missing decision (AGENTS.md/CLAUDE.md as a drift surface), and ledger≠records replay divergence when this partition has a change ledger. Exits non-zero on any anchor-stale drift, topic collision or replay divergence — the doc≠graph and ledger≠records gate. --fail-on adds further kinds to the gate (the release gate passes finding-stale).")
6030
+ .option("--fail-on <kinds>", `comma-separated drift kinds that also fail the gate (${DRIFT_KINDS.join(", ")})`)
6031
+ .action((opts) => {
6032
+ const failOn = new Set((opts.failOn ?? "").split(",").map((k) => k.trim()).filter(Boolean));
6033
+ for (const kind of failOn)
6034
+ if (!DRIFT_KINDS.includes(kind))
6035
+ return fail(`--fail-on: unknown drift kind "${kind}" (known: ${DRIFT_KINDS.join(", ")})`);
6036
6036
  const { store, root } = storeFor();
6037
6037
  try {
6038
6038
  const { findings } = computeDrift(store, root);
@@ -6056,8 +6056,9 @@ program
6056
6056
  if (replayCount && !replayFailing.length)
6057
6057
  console.log(`· [replay-fingerprint] ${scopePath(own)}: ledger fold ${replay.replay_hash} ≠ stored ${replay.stored_hash}`);
6058
6058
  const anchor = findings.filter((f) => f.kind === "anchor-stale" || f.kind === "doc-anchor-stale").length;
6059
- console.log(`\n${findings.length + replayCount} finding(s)${anchor ? `, ${anchor} doc≠graph (anchor-stale)` : ""}${collisions.size ? `, ${collisions.size} topic-collision(s)` : ""}${replayCount ? `, ${replayCount} ledger≠records (replay: hunch serve replay --root .)` : ""}.`);
6060
- if (anchor || collisions.size || replayCount)
6059
+ const failing = findings.filter((f) => failOn.has(f.kind)).length;
6060
+ console.log(`\n${findings.length + replayCount} finding(s)${anchor ? `, ${anchor} doc≠graph (anchor-stale)` : ""}${collisions.size ? `, ${collisions.size} topic-collision(s)` : ""}${replayCount ? `, ${replayCount} ledger≠records (replay: hunch serve replay --root .)` : ""}${failing ? `, ${failing} failing by --fail-on (${[...failOn].join(", ")})` : ""}.`);
6061
+ if (anchor || collisions.size || replayCount || failing)
6061
6062
  process.exitCode = 1;
6062
6063
  }
6063
6064
  finally {
@@ -6813,7 +6814,10 @@ function realpathNorm(p) {
6813
6814
  function toRepoRel(root, abs) {
6814
6815
  return relative(realpathNorm(root), realpathNorm(abs)).split("\\").join("/");
6815
6816
  }
6816
- function emitContext(provider, event, text) {
6817
+ function emitContext(provider, event, text,
6818
+ /** One user-facing line where the host shows hook messages (Claude Code's
6819
+ * `systemMessage`); never a block, never a second model turn. */
6820
+ systemMessage) {
6817
6821
  if (event === "SessionStart") {
6818
6822
  const warning = integrationSessionWarning(findRoot(), provider);
6819
6823
  if (warning)
@@ -6821,7 +6825,7 @@ function emitContext(provider, event, text) {
6821
6825
  }
6822
6826
  const output = contextHookOutput(provider, event, text);
6823
6827
  if (output)
6824
- process.stdout.write(JSON.stringify(output));
6828
+ process.stdout.write(JSON.stringify(provider === "claude" && systemMessage ? { ...output, systemMessage } : output));
6825
6829
  }
6826
6830
  function emitDeny(provider, reason) {
6827
6831
  const result = denyHookOutput(provider, reason);
@@ -1,7 +1,7 @@
1
1
  import { execFileSync, spawnSync } from "node:child_process";
2
2
  import { dirname, join } from "node:path";
3
3
  import { pathToFileURL } from "node:url";
4
- import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
4
+ import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
5
5
  import { tmpdir } from "node:os";
6
6
  import { headSha } from "../extractors/git.js";
7
7
  import { canonicalHash } from "./canonical.js";
@@ -125,7 +125,14 @@ export function evaluateExecutableBehaviorPolicy(root, policy, opts = {}) {
125
125
  }
126
126
  const dependency = dependencySnapshotForCommit(root, commit, assertion.dependency_snapshot_ids);
127
127
  if (!dependency) {
128
- return evaluation(policy, commit, { ...baseExecution, commit, error_code: "dependency-snapshot-unavailable" }, "error", "no unique exact dependency snapshot is available for executable behavior evaluation");
128
+ // Two different situations hid behind one message (fnd_b421b3f7ab): a machine
129
+ // that never built the snapshot cache, and a policy whose pinned snapshots no
130
+ // longer match the commit's dependency inputs. Name each with its recovery;
131
+ // both stay `error`, never a coerced pass.
132
+ if (!existsSync(join(root, ".hunch-cache", "behavior-deps"))) {
133
+ return evaluation(policy, commit, { ...baseExecution, commit, error_code: "dependency-snapshot-cache-absent" }, "error", "no dependency snapshot cache exists on this machine (.hunch-cache/behavior-deps); executable behavior is unevaluated here, not failed — provision the policy's snapshots (hunch constitution bootstrap --behavior-deps <candidate>) or evaluate where they were built");
134
+ }
135
+ return evaluation(policy, commit, { ...baseExecution, commit, error_code: "dependency-snapshot-unavailable" }, "error", `no unique exact dependency snapshot matches this commit's package.json/package-lock.json among the policy's pinned ids (${assertion.dependency_snapshot_ids.join(", ")}); dependency inputs changed since compilation — re-plan and re-prove the policy (rb_g2_stale_policy_01)`);
129
136
  }
130
137
  const session = mkdtempSync(join(tmpdir(), "hunch-behavior-policy-"));
131
138
  const hooks = join(session, "hooks-disabled");
@@ -0,0 +1,8 @@
1
+ /** Terminal rendering of canonical policy receipts, shared by `hunch policy
2
+ * evaluate` and the pre-commit `hunch check`. Rendering never alters a receipt.
3
+ * Receipts that did not evaluate (error / unknown / not_applicable) and share
4
+ * one explanation are grouped, so ten policies failing for the same
5
+ * environmental reason read as one actionable block instead of ten
6
+ * (fnd_b421b3f7ab); satisfied and violated policies always stay one per line. */
7
+ import type { PolicyEvaluationSet } from "./service.js";
8
+ export declare function renderPolicyEvaluations(results: PolicyEvaluationSet[]): string[];
@@ -0,0 +1,48 @@
1
+ const ICON = { satisfied: "✅", violated: "⛔", not_applicable: "·", unknown: "?", error: "‼" };
2
+ const GROUP_AT = 3;
3
+ function groupKey(r) {
4
+ const result = r.evaluation.result;
5
+ const groupable = (result === "error" || result === "unknown" || result === "not_applicable") && !r.blocks && !r.gate_error;
6
+ if (!groupable)
7
+ return `one ${r.policy.id}`;
8
+ return `${r.policy.state} ${result} ${r.evaluation.explanation}`;
9
+ }
10
+ export function renderPolicyEvaluations(results) {
11
+ if (!results.length)
12
+ return ["No Constitution policies matched."];
13
+ const out = [`Constitution policy evaluation: ${results.length} canonical receipt(s)`];
14
+ const groups = new Map();
15
+ for (const r of results) {
16
+ const key = groupKey(r);
17
+ const members = groups.get(key) ?? [];
18
+ members.push(r);
19
+ groups.set(key, members);
20
+ }
21
+ const rendered = new Set();
22
+ for (const r of results) {
23
+ if (rendered.has(r))
24
+ continue;
25
+ const members = groups.get(groupKey(r)) ?? [r];
26
+ const icon = ICON[r.evaluation.result] ?? "·";
27
+ if (members.length >= GROUP_AT) {
28
+ for (const member of members)
29
+ rendered.add(member);
30
+ const ids = members.map((m) => m.policy.id);
31
+ const receipts = members.map((m) => `${m.policy.id}=${m.evaluation.deterministic_hash.slice(0, 17)}`);
32
+ out.push(` ${icon} ${members.length} policies [${r.policy.state}] ${r.evaluation.result} — same cause`);
33
+ out.push(` ${r.evaluation.explanation}`);
34
+ out.push(` policies: ${ids.join(", ")}`);
35
+ out.push(` receipts: ${receipts.join(" ")}`);
36
+ out.push(" full receipts: hunch policy evaluate --json");
37
+ continue;
38
+ }
39
+ rendered.add(r);
40
+ out.push(` ${icon} ${r.policy.id} [${r.policy.state}] ${r.evaluation.result}${r.blocks ? " — BLOCK" : ""}`);
41
+ out.push(` ${r.evaluation.explanation}`);
42
+ if (r.gate_error)
43
+ out.push(` gate error: ${r.gate_error}`);
44
+ out.push(` receipt: ${r.evaluation.deterministic_hash}`);
45
+ }
46
+ return out;
47
+ }
48
+ //# sourceMappingURL=renderEvaluations.js.map
@@ -1,5 +1,6 @@
1
1
  import type { HunchStore } from "../store/hunchStore.js";
2
- export type DriftKind = "dead-ref" | "supersede" | "doc-stale" | "anchor-stale" | "doc-anchor-stale" | "doc-anchor-dangling" | "wiki-stale" | "finding-stale" | "premise-stale" | "commit-unresolvable" | "madr-stale" | "madr-edited" | "madr-orphan";
2
+ export declare const DRIFT_KINDS: readonly ["dead-ref", "supersede", "doc-stale", "anchor-stale", "doc-anchor-stale", "doc-anchor-dangling", "wiki-stale", "finding-stale", "premise-stale", "commit-unresolvable", "madr-stale", "madr-edited", "madr-orphan"];
3
+ export type DriftKind = typeof DRIFT_KINDS[number];
3
4
  export interface DriftFinding {
4
5
  kind: DriftKind;
5
6
  id: string;
@@ -27,6 +27,7 @@ import { markdownDocs, STALE_MARKER, SRC_REF } from "./docscan.js";
27
27
  import { computeWikiDrift } from "../wiki/wiki.js";
28
28
  import { computeMadrDrift } from "../integrations/madrManifest.js";
29
29
  import { commitsExist, isGitRepo } from "../extractors/git.js";
30
+ export const DRIFT_KINDS = ["dead-ref", "supersede", "doc-stale", "anchor-stale", "doc-anchor-stale", "doc-anchor-dangling", "wiki-stale", "finding-stale", "premise-stale", "commit-unresolvable", "madr-stale", "madr-edited", "madr-orphan"];
30
31
  export function computeDrift(store, root, deps = {}) {
31
32
  const findings = [];
32
33
  const decisions = store.recs("decisions");
@@ -198,6 +198,12 @@ export declare function readLessonHistory(root: string, reference: LessonReferen
198
198
  before?: number;
199
199
  }): LessonHistory;
200
200
  export declare function startReportTask(root: string, title: string, taskId?: string): ReportTask;
201
+ /** The record revisions among `records` that this task has not received before.
202
+ * Powers the one-line "Hunch recalled …" indication on a lesson's FIRST delivery
203
+ * in a task; repeats of the same revision stay silent (deduplicated per task and
204
+ * revision, never per session or file). Read-only; never throws for callers
205
+ * that must stay silent on failure — they catch. */
206
+ export declare function unseenLessons(root: string, taskId: string, records: readonly ReportRecord[]): ReportRecord[];
201
207
  /** Strict operation for explicit callers. Passive integrations catch failure
202
208
  * and disclose it without blocking context delivery. Empty envelopes count. */
203
209
  export declare function recordTaskDelivery(root: string, taskId: string, envelope: DeliveryEnvelope, records: ReportRecord[], occurrenceId?: string): string;
@@ -281,6 +281,21 @@ function appendEvent(root, taskId, kind, body, eventId) {
281
281
  return id;
282
282
  }));
283
283
  }
284
+ /** The record revisions among `records` that this task has not received before.
285
+ * Powers the one-line "Hunch recalled …" indication on a lesson's FIRST delivery
286
+ * in a task; repeats of the same revision stay silent (deduplicated per task and
287
+ * revision, never per session or file). Read-only; never throws for callers
288
+ * that must stay silent on failure — they catch. */
289
+ export function unseenLessons(root, taskId, records) {
290
+ if (!records.length)
291
+ return [];
292
+ return taskDb(root, db => {
293
+ readTask(db, root, taskId);
294
+ const seen = db.prepare(`SELECT 1 FROM report_record_links l JOIN report_events e ON e.event_id = l.event_id
295
+ WHERE e.task_id = ? AND e.kind = 'delivery' AND l.kind = ? AND l.record_id = ? AND l.content_hash = ? LIMIT 1`);
296
+ return records.filter(r => !seen.get(taskId, r.kind, r.record_id, r.content_hash));
297
+ });
298
+ }
284
299
  /** Strict operation for explicit callers. Passive integrations catch failure
285
300
  * and disclose it without blocking context delivery. Empty envelopes count. */
286
301
  export function recordTaskDelivery(root, taskId, envelope, records, occurrenceId = `hocc_${randomBytes(12).toString("hex")}`) {
@@ -1,5 +1,10 @@
1
1
  import { type LessonHistory, type TaskReport } from "./taskReport.js";
2
2
  export declare function writeTaskReportHtml(root: string, taskId: string, publicOnly?: boolean): string;
3
+ /** One short line for the first time a lesson reaches a task; null when every
4
+ * delivered revision was already seen in this task. Never a banner per delivery. */
5
+ export declare function renderRecalledLine(fresh: readonly {
6
+ title: string;
7
+ }[]): string | null;
3
8
  export declare function renderTaskReport(report: TaskReport): string;
4
9
  /** Standalone, local-only projection. No active content, external assets or
5
10
  * untrusted outbound URLs; evidence references are internal anchors. */
@@ -36,6 +36,14 @@ function ruleStanding(report) {
36
36
  function recordTitle(report, rule) {
37
37
  return uniqueRecords(report).find(r => r.kind === rule.kind && r.record_id === rule.record_id && r.content_hash === rule.content_hash)?.title ?? rule.record_id;
38
38
  }
39
+ /** One short line for the first time a lesson reaches a task; null when every
40
+ * delivered revision was already seen in this task. Never a banner per delivery. */
41
+ export function renderRecalledLine(fresh) {
42
+ if (!fresh.length)
43
+ return null;
44
+ const rest = fresh.length - 1;
45
+ return `Hunch recalled: ${clip(fresh[0].title, 90)}${rest ? ` (+${rest} more lesson${rest === 1 ? "" : "s"})` : ""}`;
46
+ }
39
47
  export function renderTaskReport(report) {
40
48
  const records = uniqueRecords(report);
41
49
  const lines = [`Hunch · ${clip(report.task.title)}`, `Task ${report.task.task_id} · ${report.task.state}`];
@@ -40,7 +40,8 @@ import { PROJECT_DNA_DELTA_SCHEMA_VERSION, diffProjectDna } from "../core/projec
40
40
  import { projectDnaDeliverySupplement } from "../core/projectDnaDelivery.js";
41
41
  import { armExecutionObligations, loadPipelineState, savePipelineState } from "../core/pipeline.js";
42
42
  import { recordServed } from "../core/served.js";
43
- import { TaskIdSchema, recordTaskDelivery } from "../core/taskReport.js";
43
+ import { TaskIdSchema, recordTaskDelivery, unseenLessons } from "../core/taskReport.js";
44
+ import { renderRecalledLine } from "../core/taskReportRender.js";
44
45
  import { observeReportCapture } from "../core/taskReportCapture.js";
45
46
  import { snapshotDeliveredRecords } from "../core/taskReportEvidence.js";
46
47
  import { registerTaskReportTools } from "./taskReportTools.js";
@@ -1049,8 +1050,10 @@ export function buildServerWithRootControl(initialRoot, options = {}) {
1049
1050
  try {
1050
1051
  // Historical contexts must not borrow today's record text/revision.
1051
1052
  const records = as_of ? [] : snapshotDeliveredRecords(store, envelope);
1053
+ // First delivery of a revision in this task earns one line; repeats stay quiet.
1054
+ const recalled = renderRecalledLine(unseenLessons(root, task_id, records));
1052
1055
  const occurrence = recordTaskDelivery(root, task_id, envelope, records);
1053
- result.content.push({ type: "text", text: `Task evidence: ${task_id} · occurrence ${occurrence}.\n${records.slice(0, 20).map(r => `${r.record_id} @ ${r.content_hash}`).join("\n")}${records.length > 20 ? "\nMore record identities: hunch_report(task_id)." : ""}` });
1056
+ result.content.push({ type: "text", text: `${recalled ? `${recalled}\n` : ""}Task evidence: ${task_id} · occurrence ${occurrence}.\n${records.slice(0, 20).map(r => `${r.record_id} @ ${r.content_hash}`).join("\n")}${records.length > 20 ? "\nMore record identities: hunch_report(task_id)." : ""}` });
1054
1057
  }
1055
1058
  catch {
1056
1059
  result.content.push({ type: "text", text: `Task evidence could not be recorded for ${task_id}. Context remains available; this delivery's report attribution is unverified. Check the task ID, working directory, and local ledger.` });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davesheffer/hunch",
3
- "version": "1.32.1",
3
+ "version": "1.32.2",
4
4
  "mcpName": "io.github.davesheffer/hunch",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Dave Sheffer <dave.sheffer1@gmail.com>",
package/server.json CHANGED
@@ -7,13 +7,13 @@
7
7
  "source": "github"
8
8
  },
9
9
  "websiteUrl": "https://www.hunchmemory.com",
10
- "version": "1.32.1",
10
+ "version": "1.32.2",
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.1",
16
+ "version": "1.32.2",
17
17
  "runtimeHint": "npx",
18
18
  "packageArguments": [
19
19
  {