@dahch/muninn 0.0.0-stage → 0.2.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.
Files changed (92) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +395 -2
  3. package/dist/cli.d.ts +23 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +186 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/check.d.ts +3 -0
  8. package/dist/commands/check.d.ts.map +1 -0
  9. package/dist/commands/check.js +56 -0
  10. package/dist/commands/check.js.map +1 -0
  11. package/dist/commands/memory.d.ts +6 -0
  12. package/dist/commands/memory.d.ts.map +1 -0
  13. package/dist/commands/memory.js +374 -0
  14. package/dist/commands/memory.js.map +1 -0
  15. package/dist/commands/setup.d.ts +3 -0
  16. package/dist/commands/setup.d.ts.map +1 -0
  17. package/dist/commands/setup.js +397 -0
  18. package/dist/commands/setup.js.map +1 -0
  19. package/dist/contracts/compiler.d.ts +71 -0
  20. package/dist/contracts/compiler.d.ts.map +1 -0
  21. package/dist/contracts/compiler.js +362 -0
  22. package/dist/contracts/compiler.js.map +1 -0
  23. package/dist/contracts/index.d.ts +2 -0
  24. package/dist/contracts/index.d.ts.map +1 -0
  25. package/dist/contracts/index.js +2 -0
  26. package/dist/contracts/index.js.map +1 -0
  27. package/dist/db/client.d.ts +100 -0
  28. package/dist/db/client.d.ts.map +1 -0
  29. package/dist/db/client.js +318 -0
  30. package/dist/db/client.js.map +1 -0
  31. package/dist/db/schema.sql +99 -0
  32. package/dist/index.d.ts +23 -0
  33. package/dist/index.d.ts.map +1 -0
  34. package/dist/index.js +23 -0
  35. package/dist/index.js.map +1 -0
  36. package/dist/indexer/ast-indexer.d.ts +55 -0
  37. package/dist/indexer/ast-indexer.d.ts.map +1 -0
  38. package/dist/indexer/ast-indexer.js +445 -0
  39. package/dist/indexer/ast-indexer.js.map +1 -0
  40. package/dist/indexer/index.d.ts +2 -0
  41. package/dist/indexer/index.d.ts.map +1 -0
  42. package/dist/indexer/index.js +2 -0
  43. package/dist/indexer/index.js.map +1 -0
  44. package/dist/mcp/index.d.ts +2 -0
  45. package/dist/mcp/index.d.ts.map +1 -0
  46. package/dist/mcp/index.js +2 -0
  47. package/dist/mcp/index.js.map +1 -0
  48. package/dist/mcp/server.d.ts +254 -0
  49. package/dist/mcp/server.d.ts.map +1 -0
  50. package/dist/mcp/server.js +636 -0
  51. package/dist/mcp/server.js.map +1 -0
  52. package/dist/service/index.d.ts +2 -0
  53. package/dist/service/index.d.ts.map +1 -0
  54. package/dist/service/index.js +2 -0
  55. package/dist/service/index.js.map +1 -0
  56. package/dist/service/memory-service.d.ts +320 -0
  57. package/dist/service/memory-service.d.ts.map +1 -0
  58. package/dist/service/memory-service.js +1511 -0
  59. package/dist/service/memory-service.js.map +1 -0
  60. package/dist/setup/index.d.ts +6 -0
  61. package/dist/setup/index.d.ts.map +1 -0
  62. package/dist/setup/index.js +6 -0
  63. package/dist/setup/index.js.map +1 -0
  64. package/dist/setup/json-target.d.ts +30 -0
  65. package/dist/setup/json-target.d.ts.map +1 -0
  66. package/dist/setup/json-target.js +263 -0
  67. package/dist/setup/json-target.js.map +1 -0
  68. package/dist/setup/portable.d.ts +56 -0
  69. package/dist/setup/portable.d.ts.map +1 -0
  70. package/dist/setup/portable.js +365 -0
  71. package/dist/setup/portable.js.map +1 -0
  72. package/dist/setup/registry.d.ts +54 -0
  73. package/dist/setup/registry.d.ts.map +1 -0
  74. package/dist/setup/registry.js +225 -0
  75. package/dist/setup/registry.js.map +1 -0
  76. package/dist/setup/rules-target.d.ts +31 -0
  77. package/dist/setup/rules-target.d.ts.map +1 -0
  78. package/dist/setup/rules-target.js +270 -0
  79. package/dist/setup/rules-target.js.map +1 -0
  80. package/dist/setup/toml-target.d.ts +62 -0
  81. package/dist/setup/toml-target.d.ts.map +1 -0
  82. package/dist/setup/toml-target.js +869 -0
  83. package/dist/setup/toml-target.js.map +1 -0
  84. package/dist/util/path-safety.d.ts +94 -0
  85. package/dist/util/path-safety.d.ts.map +1 -0
  86. package/dist/util/path-safety.js +162 -0
  87. package/dist/util/path-safety.js.map +1 -0
  88. package/dist/util/text.d.ts +9 -0
  89. package/dist/util/text.d.ts.map +1 -0
  90. package/dist/util/text.js +19 -0
  91. package/dist/util/text.js.map +1 -0
  92. package/package.json +87 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel Hernández
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,396 @@
1
- # Temporary Holding Version
1
+ # Muninn
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Persistent **semantic and symbol memory** for AI coding agents.
4
+
5
+ Muninn stores the things a coding session learns — architectural decisions, conventions,
6
+ discoveries, bugfixes — next to the symbols they refer to, in a single SQLite file that lives
7
+ with the project. It speaks **MCP** so any agent can save and query it, and it exposes the same
8
+ engine as a plain Node/Bun library and a CLI.
9
+
10
+ It used to live inside [Huginn](https://github.com/dahch/huginn); it is now an independent
11
+ package with no dependency on the orchestrator.
12
+
13
+ ## Overview
14
+
15
+ - **Observations with categories** — `decision`, `convention`, `discovery`, `bugfix`,
16
+ `architecture` — searchable with SQLite **FTS5 + BM25** ranking.
17
+ - **Decision supersession** — saving a decision with `supersedesTopicKey` atomically marks the
18
+ project's active decisions with that topic key as `superseded`, linking each to its replacement.
19
+ Search and context hide superseded observations by default; pass `includeSuperseded` to see them.
20
+ - **Read-only session brief** — the library, MCP `muninn_bootstrap` tool, and
21
+ `muninn memory brief` render the same deterministic Markdown view of project identity, active
22
+ decisions, recent activity, path-selected indexed symbols, related graph neighbors, and counts.
23
+ Bootstrap reads an existing database without DDL or project insertion and fails open when memory
24
+ is missing or unusable.
25
+ - **A symbol graph** — the TypeScript Compiler API extracts files, functions, classes,
26
+ interfaces and modules from your sources, plus the `imports`/`extends`/`implements`/
27
+ `references` edges between them, and links observations to symbols. The schema also reserves a
28
+ `calls` relation, but the current indexer does not emit call edges.
29
+ - **Graph-aware recovery** — `MemoryService.neighbors` traverses stored dependency edges in both
30
+ directions, grouped by relation and direction, with deduplication, cycle protection, depth at most
31
+ 2 (default 1), and at most 50 neighbors (default 20). Briefs expand these neighbors by default,
32
+ and `muninn_inspect_symbol` adds a bounded depth-1 traversal.
33
+ - **MCP tools** for agents: `muninn_context`, `muninn_save`, `muninn_search`,
34
+ `muninn_link_symbol`, `muninn_inspect_symbol`, `muninn_verify_contract`, `muninn_stats`,
35
+ `muninn_bootstrap`.
36
+ - **Contract verification** — the same TypeScript execution-contract check as a CLI command
37
+ (`muninn check`) and as the `muninn_verify_contract` MCP tool.
38
+ - **JSONL sync** — export/import the whole memory as portable line-delimited JSON.
39
+ - **Agent setup** — `muninn setup` lists the supported agent catalog and installs a `muninn` MCP
40
+ entry into standard `mcpServers`, OpenCode `mcp`, and Codex TOML configurations, plus the
41
+ project-agnostic portable file at `{home}/.muninn/mcp.json`. It supports `--agent`, `--project`,
42
+ `--list`, `--status`, `--dry-run`, `--force`, `--home`, and `--no-rules`, preserves unrelated
43
+ configuration, and never modifies the legacy Huginn file. Codex TOML is merged safely, and selected
44
+ agents receive an idempotent marked rules block with legacy-block detection.
45
+ - **Local-first and self-contained** — no embeddings, no network, no server: one SQLite file
46
+ and one process.
47
+
48
+ ## Prerequisites
49
+
50
+ - Node.js 20 or newer (the published package also runs under Bun)
51
+ - A C/C++ toolchain for `better-sqlite3`'s native module when a prebuilt binary is unavailable
52
+ - Git only if you want repository discovery and sanitized remote metadata; Muninn works outside a repository
53
+
54
+ ## Getting Started
55
+
56
+ ```sh
57
+ npm install -g @dahch/muninn # CLI + MCP server
58
+ # or as a library
59
+ npm install @dahch/muninn
60
+ ```
61
+
62
+ From a checkout, install the locked dependencies and initialize memory for this repository:
63
+
64
+ ```sh
65
+ npm ci
66
+ npm run build
67
+ node dist/cli.js memory init --project .
68
+ ```
69
+
70
+ ## CLI
71
+
72
+ ```sh
73
+ muninn memory init [--db <path>] [--project <path>]
74
+ muninn memory search <query> [--category <cat>] [--limit <n>] [--project <path>]
75
+ muninn memory sync [--import] [--file <path>] [--project <path>]
76
+ muninn memory index [files...] [--project <path>] [--db <path>]
77
+ muninn memory brief [--project <path>] [--paths a,b] [--budget <n>] [--db <path>]
78
+
79
+ muninn check [files...] [--project <path>]
80
+
81
+ muninn mcp run [--db <path>] [--project <path>]
82
+
83
+ muninn setup [--list] [--agent <id|all|id,id>] [--project <path>] [--home <path>]
84
+ [--portable|--no-portable] [--no-rules] [--force] [--dry-run] [--status]
85
+ ```
86
+
87
+ The database resolves to `<git-root>/.huginn/muninn.db` inside a repository and to
88
+ `~/.huginn/muninn.db` outside one. `--db` overrides it; `:memory:` is accepted for tests.
89
+ Both the database file and the project record are resolved from the **same** root, so
90
+ `--project X` can never write into another project's database.
91
+
92
+ `muninn memory brief` is read-only. `--paths` accepts up to 20 comma-separated files or directories
93
+ (relative to the project root, or absolute inside it) and selects only indexed symbols. `--budget`
94
+ limits the complete Markdown output to a positive integer no greater than 20,000 characters; the
95
+ default is 8,000. Briefs expand dependency neighbors by default; `getSessionBrief({ expandGraph:
96
+ false })` and MCP `expandGraph` / `expand_graph` disable that section. If the selected symbols have no
97
+ stored dependencies, the section is omitted and a note explains why. A missing, inaccessible, or
98
+ corrupt database yields an empty brief with an explanatory note instead of being created or repaired.
99
+
100
+ ## MCP
101
+
102
+ Register Muninn with any MCP-capable agent. For example, a Claude Code / Codex / Cursor config
103
+ (`mcpServers`):
104
+
105
+ ```json
106
+ {
107
+ "mcpServers": {
108
+ "muninn": {
109
+ "command": "muninn",
110
+ "args": ["mcp", "run", "--project", "/absolute/path/to/repo"]
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ OpenCode uses the same shape under the `mcp` key with `"type": "local"` and a `command` array.
117
+
118
+ ```sh
119
+ muninn mcp run --project .
120
+ ```
121
+
122
+ `muninn setup --list` shows every supported destination and where its configuration lives. With
123
+ `--agent`, setup merges the `muninn` entry into the selected destinations (JSON or Codex TOML), installs
124
+ marked usage rules unless `--no-rules` is given, and includes the portable file unless `--no-portable`
125
+ is given; `--project` supplies the absolute project path used by project-contained configuration files
126
+ and rules. Codex TOML merging is supported with safe atomic writes and read-only diagnostics.
127
+
128
+ The `muninn_save` tool accepts `supersedesTopicKey` / `supersedes_topic_key`, and
129
+ `muninn_search` / `muninn_context` accept `includeSuperseded` / `include_superseded`. Existing
130
+ calls keep working: replacement is opt-in and retrieval excludes superseded observations by
131
+ default.
132
+
133
+ `muninn_bootstrap` optionally accepts `paths` (at most 20), `budgetChars` / `budget_chars`
134
+ (default 8,000, maximum 20,000), and `expandGraph` / `expand_graph` (default `true`, disabling the
135
+ related-symbol expansion). It returns the shared service-rendered Markdown directly, not a JSON
136
+ wrapper, and does not create or initialize a database when called on a default server.
137
+
138
+ ## Agent Setup
139
+
140
+ `muninn setup` manages the portable destination `{home}/.muninn/mcp.json` and the JSON- and
141
+ TOML-format agent destinations in the catalog.
142
+
143
+ ```sh
144
+ muninn setup --list # print the catalog without writing
145
+ muninn setup # write/merge the portable entry
146
+ muninn setup --agent cursor,pi --project . # configure selected agents + portable
147
+ muninn setup --agent all --project . # every catalog destination + portable
148
+ muninn setup --agent opencode --no-portable # only the selected destination
149
+ muninn setup --agent cursor --no-rules # configure without installing rules
150
+ muninn setup --status --agent claude --project . # selected agents + portable, read-only
151
+ muninn setup --dry-run --agent all --project . # report intended actions without writing
152
+ ```
153
+
154
+ The catalog is `cursor`, `claude`, `opencode`, `devin`, `qwen`, `codex`, `agy`, `kimi`, `pi`,
155
+ `commandcode`, `omp`, `mcode`, and `mimo`. Path templates expand `{project}`, `{home}`, and
156
+ `{opencodeConfigDir}`; `MUNINN_AGENT_<ID>_MCP_PATH` (colon-separated) overrides a target's paths, and
157
+ `HUGINN_AGENT_<ID>_MCP_PATH` is accepted as an equivalent fallback. `MUNINN_OPENCODE_CONFIG_DIR`
158
+ overrides the OpenCode config directory (`HUGINN_OPENCODE_CONFIG_DIR` is the fallback). Project-contained
159
+ config files get `--project <absolute path>`; shared user-level and portable files never pin a project.
160
+
161
+ Standard entries are `{ "command": "muninn", "args": ["mcp", "run"] }` under `mcpServers.muninn`.
162
+ OpenCode uses `{ "type": "local", "command": ["muninn", "mcp", "run"], "enabled": true }` under
163
+ `mcp.muninn`. Setup merges only the Muninn entry, preserves unrelated keys and servers, and leaves the
164
+ legacy `{home}/.huginn/mcp.json` untouched (it only reports it when present).
165
+
166
+ Diagnostic states are `absent`, `registered`, `legacy`, `conflict`, and `malformed`. A conflicting
167
+ entry, or a JSON target whose existing entry still invokes the legacy `huginn` command (`legacy`), is
168
+ skipped without `--force`. For the portable file, `legacy` means the portable config is missing while
169
+ `{home}/.huginn/mcp.json` exists: setup writes the portable entry and only reports the legacy file.
170
+ Malformed JSON, a non-regular file, a final-component symlink, or a protected path fails with exit
171
+ code 1. Writes are atomic, new files use mode `0o600`, new parent directories use `0o700`, and existing
172
+ permissions are preserved. Re-running setup over a correct entry is byte-for-byte idempotent and
173
+ reports `changed: false`. `--list`, `--status`, and `--dry-run` never create or modify files,
174
+ directories, or temporary files.
175
+
176
+ Codex uses a dependency-free TOML writer that merges `[mcp_servers.muninn]`, preserves unrelated
177
+ tables and keys, and applies the same conflict, permission, atomic-write, and symlink rules as JSON
178
+ destinations. A forced replacement can discard comments and formatting inside the replaced Muninn
179
+ region; unrelated content outside it is preserved where feasible. Malformed TOML, including duplicate
180
+ table definitions, is reported with its path and cause, leaves the original untouched, and status
181
+ continues to inspect the remaining destinations before exiting 1.
182
+
183
+ Selected agents also receive a Markdown rules block delimited by `<!-- muninn:rules:start -->` and
184
+ `<!-- muninn:rules:end -->`. It recommends `muninn_bootstrap` at session start, `muninn_search` and
185
+ `muninn_inspect_symbol` before designing a change, and `muninn_verify_contract` before completing code.
186
+ Setup appends the block to an existing rules file, creates the file only when a write is needed, and
187
+ replaces only its own marked block on later runs. Agents that share a rules file (for example the
188
+ various `AGENTS.md` destinations) receive one deduplicated block. Without `--agent`, rules are neither
189
+ read nor written; `--no-rules` suppresses them for an explicit selection.
190
+
191
+ A prior `<!-- huginn:muninn-rules:start -->` block is reported as `stale` and left byte-identical
192
+ without `--force`; with `--force` it is replaced while surrounding prose is preserved. Unmatched,
193
+ duplicate, unterminated, crossed, or nested managed/legacy markers are fatal and leave the file
194
+ untouched. Rules paths use the same containment and symlink checks as MCP configuration, and writes
195
+ preserve existing permissions or use `0o600` for new files. Status reports `absent`, `present`, `stale`,
196
+ or `malformed` per rules file and identifies the selected agents that share it; normal setup and dry-run
197
+ report `written`, `present`, `stale`, or `failed`. A selected agent binary missing from `PATH` produces
198
+ a nonfatal `not installed` warning and does not change the exit code. Targets with no meaningful local
199
+ executable (`cursor`, `devin`) are not probed and never warn.
200
+
201
+ ## Architecture
202
+
203
+ Muninn is one `MemoryService` core with three adapters: the CLI, the MCP stdio server, and the
204
+ library. Storage is a single embedded SQLite database with FTS5. The AST indexer writes through the
205
+ service/database boundary; contract verification is a separate read-only TypeScript pass.
206
+
207
+ ```mermaid
208
+ flowchart LR
209
+ Agent["MCP-capable agent"] -->|stdio JSON-RPC| MCP["MCP server\nmuninn mcp run"]
210
+ CLI["CLI\nmuninn ..."] --> Service["MemoryService"]
211
+ Library["Node/Bun library"] --> Service
212
+ MCP --> Service
213
+ Service --> DB[("SQLite + FTS5\n.huginn/muninn.db")]
214
+ Service <--> JSONL["JSONL export/import\n.huginn/memories.jsonl"]
215
+ Indexer["AST indexer\nTypeScript Compiler API"] --> Service
216
+ CLI --> Verifier["Contract verifier\nTypeScript Compiler API"]
217
+ MCP --> Verifier
218
+ CLI --> Setup["Agent setup\nJSON/TOML catalog + portable"]
219
+ ```
220
+
221
+ See [`DESIGN.md`](./DESIGN.md) for the schema, service transactions, MCP validation pipeline, CLI
222
+ parsing, contract verifier and indexer internals.
223
+
224
+ ## Library
225
+
226
+ ```ts
227
+ import { MemoryService, indexFilesIntoMuninn } from "@dahch/muninn";
228
+
229
+ const memory = new MemoryService({ projectRoot: process.cwd() });
230
+
231
+ memory.saveObservation({
232
+ category: "decision",
233
+ title: "Auth is a port",
234
+ content: "Tokens are validated behind an AuthPort so the transport can change.",
235
+ topicKey: "auth-boundary",
236
+ symbols: ["src/auth/port.ts"],
237
+ });
238
+
239
+ // Replaces earlier active decisions with the same topic key in this project.
240
+ memory.saveObservation({
241
+ category: "decision",
242
+ title: "Auth is a middleware boundary",
243
+ content: "Tokens are validated in middleware before any handler runs.",
244
+ topicKey: "auth-boundary",
245
+ supersedesTopicKey: "auth-boundary",
246
+ });
247
+
248
+ // Superseded decisions are hidden unless explicitly requested.
249
+ const history = memory.search({
250
+ query: "token validation",
251
+ includeSuperseded: true,
252
+ });
253
+
254
+ indexFilesIntoMuninn(memory, ["src/auth/port.ts"], { projectRoot: process.cwd() });
255
+
256
+ for (const hit of memory.search({ query: "token validation", limit: 5 })) {
257
+ console.log(hit.category, hit.title, hit.rank);
258
+ }
259
+
260
+ // The same bounded Markdown used by the MCP tool and CLI.
261
+ const brief = memory.getSessionBrief({ paths: ["src/auth"], budgetChars: 8000 });
262
+ console.log(brief.markdown);
263
+
264
+ // Bounded, deterministic dependency neighbors (depth max 2, limit max 50).
265
+ const graph = memory.neighbors("src/auth/port.ts::TokenValidator", { depth: 2 });
266
+ console.log(graph?.groups);
267
+
268
+ memory.close();
269
+ ```
270
+
271
+ For bootstrap without initializing anything, use the standalone read-only entry point:
272
+
273
+ ```ts
274
+ import { readSessionBrief } from "@dahch/muninn";
275
+
276
+ const brief = readSessionBrief({
277
+ projectRoot: process.cwd(),
278
+ paths: ["src/service"],
279
+ budgetChars: 8000,
280
+ });
281
+ console.log(brief.markdown);
282
+ ```
283
+
284
+ Subpath entry points are available for narrower imports:
285
+
286
+ | Import | Contents |
287
+ |---|---|
288
+ | `@dahch/muninn` | everything below |
289
+ | `@dahch/muninn/db` | SQLite client, schema, path resolution, project records |
290
+ | `@dahch/muninn/service` | `MemoryService` (save, search, context, linking, sync, stats, session brief, graph neighbors) |
291
+ | `@dahch/muninn/indexer` | AST symbol/dependency extraction and indexing |
292
+ | `@dahch/muninn/mcp` | MCP server, tool registry, bounded stdio transport |
293
+ | `@dahch/muninn/contracts` | TypeScript contract verification |
294
+ | `@dahch/muninn/util` | terminal-text sanitizer |
295
+
296
+ ## Environment Variables
297
+
298
+ Muninn has no required environment variables. Configuration is passed as CLI flags or
299
+ `MemoryService` options.
300
+
301
+ | Variable | Type | Default | Purpose |
302
+ |---|---|---|---|
303
+ | `MUNINN_DEBUG` | string (presence is enough) | unset | Emit the `[muninn] mcp run: stdin closed by the client; shutting down.` diagnostic on stderr when the parent closes stdin. |
304
+ | `HUGINN_DEBUG` | string (presence is enough) | unset | Legacy alias for `MUNINN_DEBUG`, retained for Huginn compatibility. |
305
+ | `MUNINN_AGENT_<ID>_MCP_PATH` | string (colon-separated paths) | the catalog paths for that agent | Replace a setup target's MCP configuration paths. `<ID>` is the uppercase agent ID, for example `MUNINN_AGENT_CURSOR_MCP_PATH`; an all-empty override is rejected. |
306
+ | `HUGINN_AGENT_<ID>_MCP_PATH` | string (colon-separated paths) | unset | Legacy fallback for `MUNINN_AGENT_<ID>_MCP_PATH`, retained for Huginn compatibility. |
307
+ | `MUNINN_OPENCODE_CONFIG_DIR` | string (directory path) | `{home}/.config/opencode` | Directory used to expand the OpenCode target's `{opencodeConfigDir}` marker. |
308
+ | `HUGINN_OPENCODE_CONFIG_DIR` | string (directory path) | unset | Legacy fallback for `MUNINN_OPENCODE_CONFIG_DIR`, retained for Huginn compatibility. |
309
+ | `PATH` | string (platform path list) | inherited | Used by `muninn setup --agent` to detect each selected agent's executable for the nonfatal `not installed` warning. |
310
+ | `PATHEXT` | string (semicolon-separated extensions, Windows only) | `.EXE;.CMD;.BAT;.COM` | Windows executable extensions used by the same lookup; ignored on other platforms. |
311
+
312
+ ## Security notes
313
+
314
+ - Session bootstrap opens an existing database read-only. It never creates a directory or file, runs
315
+ DDL/migrations, or inserts a project row; path selections are confined to the project root.
316
+ - Every path Muninn writes to — the SQLite file and the JSONL export — is screened: a symlink on
317
+ the final component is refused, and a project-relative path must resolve inside the project, so
318
+ a repository cannot redirect the write outside itself (the `src/util/path-safety.ts` rule, with
319
+ the tests in `test/db.test.ts` and `test/service.test.ts`).
320
+ - The MCP stdio transport is bounded and survives a dead parent instead of crashing or hanging.
321
+ - MCP tool inputs are validated with zod; unknown tools and bad arguments fail closed.
322
+ - Setup screens its config and legacy paths with the path-safety helper, refuses a final-component
323
+ symlink, merges only the `muninn` entry, and writes through an exclusive temporary file + atomic
324
+ rename. Neither `--status` nor `--dry-run` creates files or directories.
325
+
326
+ ## Available Scripts
327
+
328
+ ```sh
329
+ npm run dev # run src/cli.ts directly with Bun
330
+ npm run build # tsc -> dist/ (+ schema.sql, +x cli.js)
331
+ npm test # vitest run (storage, service, session brief, graph, indexer, MCP, CLI, contracts, setup)
332
+ npm run test:watch # vitest in watch mode
333
+ npm run typecheck # tsc --noEmit
334
+ npm run prepublishOnly # build + test + typecheck (npm lifecycle hook)
335
+ ```
336
+
337
+ Run the built CLI without installing it globally:
338
+
339
+ ```sh
340
+ node dist/cli.js memory init --project .
341
+ node dist/cli.js memory search "auth boundary" --project .
342
+ ```
343
+
344
+ ### Releasing
345
+
346
+ Publishing is tag-driven, but only once the package exists. The **first** publish is manual, from a
347
+ logged-in machine, because npm's trusted publishing attaches to a package page that has to exist first:
348
+
349
+ ```sh
350
+ npm login
351
+ npm run build && npm publish # 0.1.0, once
352
+ ```
353
+
354
+ After that, configure the trusted publisher on npm (repository `dahch/muninn`, workflow
355
+ `publish.yml`) and tagged releases need no token at all: `git tag v0.1.1 && git push origin v0.1.1`
356
+ runs the workflow, which checks the tag against `package.json`, builds, tests and publishes over
357
+ OIDC. A run whose version is already on npm skips the publish step and refreshes the GitHub release
358
+ instead, so re-tagging to fix a message stays safe. The release job copies the matching version
359
+ section from [`CHANGELOG.md`](./CHANGELOG.md).
360
+
361
+ ## Project Structure
362
+
363
+ ```text
364
+ src/
365
+ cli.ts argument parsing, command routing, process entry point
366
+ commands/ memory (init/search/sync/index/brief), mcp run, check, setup
367
+ db/ SQLite client, schema.sql, path and project resolution
368
+ service/ MemoryService: save, search, context, links, sync, stats, brief, neighbors
369
+ indexer/ TypeScript/JavaScript AST symbol and dependency extraction
370
+ mcp/ MCP server, tool registry, Zod schemas, bounded stdio transport
371
+ contracts/ in-process TypeScript contract verification
372
+ setup/ agent catalog/path resolution, JSON/TOML target merge, marked rules
373
+ install/diagnose, and portable MCP install/diagnose
374
+ util/ terminal-text sanitizer and path-safety helpers
375
+ test/ Vitest integration suites for db, service, session brief, graph, indexer, MCP, CLI, contracts, setup
376
+ ```
377
+
378
+ ## Documentation
379
+
380
+ - [`SPEC.md`](./SPEC.md) — product behaviour, domain model, use cases and constraints.
381
+ - [`DESIGN.md`](./DESIGN.md) — technical design, schema, data flow and internals.
382
+ - [`ADR.md`](./ADR.md) — architecture decision records and their implementation status.
383
+ - [`CHANGELOG.md`](./CHANGELOG.md) — release notes.
384
+ - [`plan.md`](./plan.md) — staged plan for the agent-setup work.
385
+ - [`AGENTS.md`](./AGENTS.md) — repository conventions for coding agents; no `.opencode/agents/` are defined.
386
+
387
+ ## Contributing
388
+
389
+ Keep changes aligned with the current contract: update both `src/db/schema.sql` and the `SCHEMA_SQL`
390
+ fallback in `src/db/client.ts`, add or update a Vitest suite under `test/`, and run
391
+ `npm run build && npm test && npm run typecheck` before opening a pull request. Add a new ADR for a
392
+ new architectural decision instead of rewriting an existing one.
393
+
394
+ ## License
395
+
396
+ MIT © Daniel Hernández
package/dist/cli.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ export declare const VERSION = "0.2.0";
3
+ export interface ParsedArgs {
4
+ [key: string]: string | boolean | undefined | string[];
5
+ _command?: string;
6
+ _positional?: string;
7
+ _positionals?: string[];
8
+ }
9
+ /**
10
+ * Parses argv into flags plus positionals.
11
+ *
12
+ * The first bare word is `_command`; every later bare word is appended to
13
+ * `_positionals` (and mirrored in `_positional` as the last one), which is what
14
+ * lets `memory search "vector search"` keep a multi-word query intact.
15
+ */
16
+ export declare function parseArgs(argv: string[]): ParsedArgs;
17
+ export declare function usage(): string;
18
+ /**
19
+ * Runs the CLI. Exported (rather than inlined) so tests can drive it with an
20
+ * explicit argv and assert on the routed handler.
21
+ */
22
+ export declare function main(argv: string[]): Promise<void>;
23
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAqBA,eAAO,MAAM,OAAO,UAAU,CAAC;AAE/B,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,EAAE,CAAC;IACvD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAwBD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA8BpD;AAED,wBAAgB,KAAK,IAAI,MAAM,CAwB9B;AAED;;;GAGG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAoExD"}
package/dist/cli.js ADDED
@@ -0,0 +1,186 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `muninn` — command-line surface for the Muninn memory engine.
4
+ *
5
+ * Three commands, one per consumer:
6
+ *
7
+ * - `muninn memory …` — init / search / sync / index the project database.
8
+ * - `muninn mcp run` — the stdio MCP server an agent runtime registers.
9
+ * - `muninn check …` — TypeScript execution-contract verification, the same
10
+ * pass the MCP `muninn_verify_contract` tool performs.
11
+ *
12
+ * The parser and the usage text are deliberately small and dependency-free:
13
+ * this file is the only part of Muninn that has to be stable for other tools to
14
+ * embed it.
15
+ */
16
+ import { realpathSync } from "node:fs";
17
+ import { fileURLToPath } from "node:url";
18
+ import { handleMcpCommand, handleMemoryCommand } from "./commands/memory.js";
19
+ import { handleCheckCommand } from "./commands/check.js";
20
+ import { handleSetupCommand } from "./commands/setup.js";
21
+ export const VERSION = "0.2.0";
22
+ /**
23
+ * Flags that never consume the next argv entry as their value. `--import` is the
24
+ * one that matters in practice: `muninn memory sync --import backup.jsonl` must
25
+ * leave `backup.jsonl` as a positional, not swallow it into the flag.
26
+ */
27
+ const BOOLEAN_FLAGS = new Set([
28
+ "-h",
29
+ "--help",
30
+ "-v",
31
+ "--version",
32
+ "--import",
33
+ "--json",
34
+ "--quiet",
35
+ "--force",
36
+ "--dry-run",
37
+ "--status",
38
+ "--portable",
39
+ "--no-portable",
40
+ "--no-rules",
41
+ "--list",
42
+ ]);
43
+ /**
44
+ * Parses argv into flags plus positionals.
45
+ *
46
+ * The first bare word is `_command`; every later bare word is appended to
47
+ * `_positionals` (and mirrored in `_positional` as the last one), which is what
48
+ * lets `memory search "vector search"` keep a multi-word query intact.
49
+ */
50
+ export function parseArgs(argv) {
51
+ const out = { _positionals: [] };
52
+ for (let i = 0; i < argv.length; i++) {
53
+ const arg = argv[i];
54
+ if (arg.startsWith("-") && arg !== "-") {
55
+ const eq = arg.indexOf("=");
56
+ let key = arg;
57
+ let value = true;
58
+ if (eq !== -1) {
59
+ key = arg.slice(0, eq);
60
+ value = arg.slice(eq + 1);
61
+ }
62
+ else if (!BOOLEAN_FLAGS.has(key)) {
63
+ const next = argv[i + 1];
64
+ if (next !== undefined &&
65
+ (!next.startsWith("-") || /^-\d+(\.\d+)?$/.test(next))) {
66
+ value = next;
67
+ i++;
68
+ }
69
+ }
70
+ out[key] = value;
71
+ }
72
+ else if (out._command === undefined) {
73
+ out._command = arg;
74
+ }
75
+ else {
76
+ out._positional = arg;
77
+ out._positionals.push(arg);
78
+ }
79
+ }
80
+ return out;
81
+ }
82
+ export function usage() {
83
+ return `muninn — persistent semantic and symbol memory for coding agents.
84
+
85
+ Usage:
86
+ muninn memory init [--db <path>] [--project <path>]
87
+ muninn memory search <query> [--category <cat>] [--limit <n>] [--project <path>]
88
+ muninn memory sync [--import] [--file <path>] [--project <path>]
89
+ muninn memory index [files...] [--project <path>] [--db <path>]
90
+ muninn memory brief [--project <path>] [--paths a,b] [--budget <n>] [--db <path>]
91
+ muninn check [files...] [--project <path>]
92
+ muninn mcp run [--db <path>] [--project <path>]
93
+ muninn setup [--list] [--agent <id|all|id,id>] [--project <path>] [--home <path>]
94
+ [--portable|--no-portable] [--no-rules] [--force] [--dry-run] [--status]
95
+
96
+ Commands:
97
+ memory query and manage the persistent codebase memory (init, search, sync, index, brief)
98
+ mcp start the Muninn MCP server for agent memory integration (run)
99
+ check verify TypeScript execution contracts and pre-emit diagnostics
100
+ setup list, install, and diagnose Muninn agent and portable MCP configurations
101
+
102
+ Storage:
103
+ The database resolves to <git-root>/.huginn/muninn.db inside a repository and
104
+ to ~/.huginn/muninn.db outside one. --db overrides it (":memory:" is accepted).
105
+ `;
106
+ }
107
+ /**
108
+ * Runs the CLI. Exported (rather than inlined) so tests can drive it with an
109
+ * explicit argv and assert on the routed handler.
110
+ */
111
+ export async function main(argv) {
112
+ const args = parseArgs(argv);
113
+ const command = args._command;
114
+ if (args["--version"] === true || args["-v"] === true || command === "version") {
115
+ console.log(`muninn ${VERSION}`);
116
+ return;
117
+ }
118
+ if (command === undefined ||
119
+ command === "help" ||
120
+ command === "--help" ||
121
+ args["--help"] === true ||
122
+ args["-h"] === true) {
123
+ console.log(usage());
124
+ return;
125
+ }
126
+ if (command === "memory") {
127
+ const positionals = args._positionals ?? [];
128
+ const subcommand = typeof positionals[0] === "string"
129
+ ? positionals[0]
130
+ : typeof args._positional === "string"
131
+ ? args._positional
132
+ : undefined;
133
+ await handleMemoryCommand(subcommand, args, positionals.slice(1));
134
+ return;
135
+ }
136
+ if (command === "mcp") {
137
+ const positionals = args._positionals ?? [];
138
+ const subcommand = typeof positionals[0] === "string"
139
+ ? positionals[0]
140
+ : typeof args._positional === "string"
141
+ ? args._positional
142
+ : undefined;
143
+ await handleMcpCommand(subcommand, args);
144
+ return;
145
+ }
146
+ if (command === "check") {
147
+ const positionals = args._positionals ?? [];
148
+ const files = positionals.length > 0
149
+ ? positionals
150
+ : typeof args._positional === "string" && args._positional !== "check"
151
+ ? [args._positional]
152
+ : [];
153
+ await handleCheckCommand(files, args);
154
+ return;
155
+ }
156
+ if (command === "setup") {
157
+ await handleSetupCommand(args);
158
+ return;
159
+ }
160
+ console.error(`Unknown command: ${command}`);
161
+ console.log(usage());
162
+ process.exitCode = 1;
163
+ }
164
+ /**
165
+ * True only when this module is the process entry point — under `node dist/cli.js`,
166
+ * `bun dist/cli.js` or the installed `muninn` bin — and false when a test or a
167
+ * consumer merely imports it.
168
+ */
169
+ function isDirectRun() {
170
+ const entry = process.argv[1];
171
+ if (!entry)
172
+ return false;
173
+ try {
174
+ return realpathSync(entry) === realpathSync(fileURLToPath(import.meta.url));
175
+ }
176
+ catch {
177
+ return false;
178
+ }
179
+ }
180
+ if (isDirectRun()) {
181
+ main(process.argv.slice(2)).catch((err) => {
182
+ console.error(`muninn: ${err instanceof Error ? err.message : String(err)}`);
183
+ process.exitCode = 1;
184
+ });
185
+ }
186
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function printCheckUsage(): void;
2
+ export declare function handleCheckCommand(files: string[], args: Record<string, string | boolean | undefined>): Promise<void>;
3
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAIA,wBAAgB,eAAe,IAAI,IAAI,CAStC;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EAAE,EACf,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC,GACjD,OAAO,CAAC,IAAI,CAAC,CAyDf"}