@davesheffer/hunch 1.32.3 → 1.32.4

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.
@@ -0,0 +1,30 @@
1
+ export declare const MCP_TOOL_GROUPS: {
2
+ /** nuryel.state/1 — the state-partition contract (Sofia-style agents). */
3
+ readonly nuryel: readonly ["nuryel_capabilities", "nuryel_read", "nuryel_write", "nuryel_capture", "nuryel_capture_batch", "nuryel_subscribe", "nuryel_records"];
4
+ /** Constitution G2/G3 experiment-track tools; the CLI remains the primary surface. */
5
+ readonly "constitution-experiments": readonly ["hunch_constitution_g2_readiness", "hunch_constitution_g3_readiness", "hunch_constitution_g2_shadow_queue", "hunch_constitution_g2_operational_drill", "hunch_constitution_g2_candidates", "hunch_constitution_g2_behavior_candidates", "hunch_constitution_g2_behavior_replay", "hunch_constitution_g2_behavior_materialization", "hunch_constitution_g2_behavior_policy_materialize"];
6
+ };
7
+ export type McpToolGroup = keyof typeof MCP_TOOL_GROUPS;
8
+ export declare const MCP_TOOL_GROUP_NAMES: McpToolGroup[];
9
+ export interface McpToolset {
10
+ enabled: (group: McpToolGroup) => boolean;
11
+ groups: McpToolGroup[];
12
+ hidden: string[];
13
+ /** Where the selection came from, for the startup log and doctor. */
14
+ source: "env" | "config" | "default";
15
+ }
16
+ /** Grammar shared by the env var and the config value: `all`, `core`, or a
17
+ * comma-separated list of extra groups on top of core (`core,nuryel`). Unknown
18
+ * words are ignored rather than failing the server. */
19
+ export declare function parseToolsetSpec(spec: string): McpToolGroup[] | null;
20
+ /** A root that already stores nuryel state records is a state partition and
21
+ * needs the nuryel tools; every other root gets the everyday set by default. */
22
+ export declare function rootStoresState(root: string): boolean;
23
+ /** `pinned` is `hunch mcp --root <dir>`: a server dedicated to one root, which is
24
+ * how state partitions are served — including a brand-new partition that has no
25
+ * state records yet and could never receive its first nuryel_write otherwise. */
26
+ export declare function resolveMcpToolset(root: string, opts?: {
27
+ env?: NodeJS.ProcessEnv;
28
+ configSpec?: string | null;
29
+ pinned?: boolean;
30
+ }): McpToolset;
@@ -0,0 +1,72 @@
1
+ /** Which MCP tool groups a server exposes. Every host shares one server, so the
2
+ * selection surface is the same for all of them: 57 tools with ~24 KB of
3
+ * descriptions dilute tool choice for everyday grounding. The everyday set is
4
+ * the default; the two specialist groups are enabled by evidence (a root that
5
+ * stores nuryel state records), by `.hunch/config.json` `mcp_tools`, or by the
6
+ * `HUNCH_MCP_TOOLS` environment variable. Hidden tools are not registered at
7
+ * all, so a client never sees them in tools/list. */
8
+ import { existsSync, readdirSync } from "node:fs";
9
+ import { join } from "node:path";
10
+ import { STATE_KINDS } from "../core/stateDelivery.js";
11
+ export const MCP_TOOL_GROUPS = {
12
+ /** nuryel.state/1 — the state-partition contract (Sofia-style agents). */
13
+ nuryel: ["nuryel_capabilities", "nuryel_read", "nuryel_write", "nuryel_capture", "nuryel_capture_batch", "nuryel_subscribe", "nuryel_records"],
14
+ /** Constitution G2/G3 experiment-track tools; the CLI remains the primary surface. */
15
+ "constitution-experiments": [
16
+ "hunch_constitution_g2_readiness", "hunch_constitution_g3_readiness", "hunch_constitution_g2_shadow_queue",
17
+ "hunch_constitution_g2_operational_drill", "hunch_constitution_g2_candidates", "hunch_constitution_g2_behavior_candidates",
18
+ "hunch_constitution_g2_behavior_replay", "hunch_constitution_g2_behavior_materialization", "hunch_constitution_g2_behavior_policy_materialize",
19
+ ],
20
+ };
21
+ export const MCP_TOOL_GROUP_NAMES = Object.keys(MCP_TOOL_GROUPS);
22
+ /** Grammar shared by the env var and the config value: `all`, `core`, or a
23
+ * comma-separated list of extra groups on top of core (`core,nuryel`). Unknown
24
+ * words are ignored rather than failing the server. */
25
+ export function parseToolsetSpec(spec) {
26
+ const words = spec.split(",").map(w => w.trim().toLowerCase()).filter(Boolean);
27
+ if (!words.length)
28
+ return null;
29
+ if (words.includes("all"))
30
+ return [...MCP_TOOL_GROUP_NAMES];
31
+ return MCP_TOOL_GROUP_NAMES.filter(g => words.includes(g));
32
+ }
33
+ /** A root that already stores nuryel state records is a state partition and
34
+ * needs the nuryel tools; every other root gets the everyday set by default. */
35
+ export function rootStoresState(root) {
36
+ return STATE_KINDS.some(kind => {
37
+ const dir = join(root, ".hunch", kind);
38
+ try {
39
+ return existsSync(dir) && readdirSync(dir).some(f => f.endsWith(".json"));
40
+ }
41
+ catch {
42
+ return false;
43
+ }
44
+ });
45
+ }
46
+ /** `pinned` is `hunch mcp --root <dir>`: a server dedicated to one root, which is
47
+ * how state partitions are served — including a brand-new partition that has no
48
+ * state records yet and could never receive its first nuryel_write otherwise. */
49
+ export function resolveMcpToolset(root, opts = {}) {
50
+ const env = opts.env ?? process.env;
51
+ let groups = null;
52
+ let source = "default";
53
+ const fromEnv = env.HUNCH_MCP_TOOLS?.trim();
54
+ if (fromEnv) {
55
+ groups = parseToolsetSpec(fromEnv);
56
+ if (groups)
57
+ source = "env";
58
+ }
59
+ if (!groups && opts.configSpec?.trim()) {
60
+ groups = parseToolsetSpec(opts.configSpec);
61
+ if (groups)
62
+ source = "config";
63
+ }
64
+ if (!groups) {
65
+ groups = opts.pinned || rootStoresState(root) ? ["nuryel"] : [];
66
+ source = "default";
67
+ }
68
+ const set = new Set(groups);
69
+ const hidden = MCP_TOOL_GROUP_NAMES.filter(g => !set.has(g)).flatMap(g => [...MCP_TOOL_GROUPS[g]]);
70
+ return { enabled: g => set.has(g), groups: [...set], hidden, source };
71
+ }
72
+ //# sourceMappingURL=toolset.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@davesheffer/hunch",
3
- "version": "1.32.3",
3
+ "version": "1.32.4",
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.3",
10
+ "version": "1.32.4",
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.3",
16
+ "version": "1.32.4",
17
17
  "runtimeHint": "npx",
18
18
  "packageArguments": [
19
19
  {