@agentmemory/agentmemory 0.7.0 → 0.7.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.
Files changed (218) hide show
  1. package/AGENTS.md +2 -2
  2. package/README.md +76 -82
  3. package/dist/cli.mjs +99 -32
  4. package/dist/cli.mjs.map +1 -1
  5. package/dist/index.mjs +4 -2
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/{src-QxitMPfJ.mjs → src-sYZDDbiA.mjs} +5 -3
  8. package/dist/src-sYZDDbiA.mjs.map +1 -0
  9. package/dist/standalone.mjs +1 -1
  10. package/dist/standalone.mjs.map +1 -1
  11. package/package.json +11 -1
  12. package/plugin/.claude-plugin/plugin.json +1 -1
  13. package/plugin/scripts/notification.d.mts +1 -0
  14. package/plugin/scripts/notification.mjs.map +1 -0
  15. package/plugin/scripts/post-tool-failure.d.mts +1 -0
  16. package/plugin/scripts/post-tool-failure.mjs.map +1 -0
  17. package/plugin/scripts/post-tool-use.d.mts +1 -0
  18. package/plugin/scripts/post-tool-use.mjs.map +1 -0
  19. package/plugin/scripts/pre-compact.d.mts +1 -0
  20. package/plugin/scripts/pre-compact.mjs.map +1 -0
  21. package/plugin/scripts/pre-tool-use.d.mts +1 -0
  22. package/plugin/scripts/pre-tool-use.mjs.map +1 -0
  23. package/plugin/scripts/prompt-submit.d.mts +1 -0
  24. package/plugin/scripts/prompt-submit.mjs.map +1 -0
  25. package/plugin/scripts/session-end.d.mts +1 -0
  26. package/plugin/scripts/session-end.mjs.map +1 -0
  27. package/plugin/scripts/session-start.d.mts +1 -0
  28. package/plugin/scripts/session-start.mjs.map +1 -0
  29. package/plugin/scripts/stop.d.mts +1 -0
  30. package/plugin/scripts/stop.mjs.map +1 -0
  31. package/plugin/scripts/subagent-start.d.mts +1 -0
  32. package/plugin/scripts/subagent-start.mjs.map +1 -0
  33. package/plugin/scripts/subagent-stop.d.mts +1 -0
  34. package/plugin/scripts/subagent-stop.mjs.map +1 -0
  35. package/plugin/scripts/task-completed.d.mts +1 -0
  36. package/plugin/scripts/task-completed.mjs.map +1 -0
  37. package/.claude-plugin/marketplace.json +0 -14
  38. package/.github/workflows/ci.yml +0 -22
  39. package/.github/workflows/publish.yml +0 -28
  40. package/assets/banner.png +0 -0
  41. package/assets/demo.gif +0 -0
  42. package/assets/demo.mp4 +0 -0
  43. package/benchmark/QUALITY.md +0 -73
  44. package/benchmark/REAL-EMBEDDINGS.md +0 -67
  45. package/benchmark/SCALE.md +0 -110
  46. package/benchmark/dataset.ts +0 -293
  47. package/benchmark/quality-eval.ts +0 -643
  48. package/benchmark/real-embeddings-eval.ts +0 -405
  49. package/benchmark/scale-eval.ts +0 -398
  50. package/dist/src-QxitMPfJ.mjs.map +0 -1
  51. package/src/auth.ts +0 -12
  52. package/src/cli.ts +0 -159
  53. package/src/config.ts +0 -221
  54. package/src/eval/metrics-store.ts +0 -65
  55. package/src/eval/quality.ts +0 -51
  56. package/src/eval/schemas.ts +0 -124
  57. package/src/eval/self-correct.ts +0 -28
  58. package/src/eval/validator.ts +0 -31
  59. package/src/functions/actions.ts +0 -288
  60. package/src/functions/audit.ts +0 -61
  61. package/src/functions/auto-forget.ts +0 -169
  62. package/src/functions/branch-aware.ts +0 -169
  63. package/src/functions/cascade.ts +0 -80
  64. package/src/functions/checkpoints.ts +0 -209
  65. package/src/functions/claude-bridge.ts +0 -161
  66. package/src/functions/compress.ts +0 -194
  67. package/src/functions/consolidate.ts +0 -212
  68. package/src/functions/consolidation-pipeline.ts +0 -258
  69. package/src/functions/context.ts +0 -169
  70. package/src/functions/crystallize.ts +0 -293
  71. package/src/functions/dedup.ts +0 -57
  72. package/src/functions/diagnostics.ts +0 -785
  73. package/src/functions/enrich.ts +0 -132
  74. package/src/functions/evict.ts +0 -163
  75. package/src/functions/export-import.ts +0 -508
  76. package/src/functions/facets.ts +0 -248
  77. package/src/functions/file-index.ts +0 -106
  78. package/src/functions/flow-compress.ts +0 -214
  79. package/src/functions/frontier.ts +0 -196
  80. package/src/functions/governance.ts +0 -131
  81. package/src/functions/graph-retrieval.ts +0 -277
  82. package/src/functions/graph.ts +0 -275
  83. package/src/functions/leases.ts +0 -216
  84. package/src/functions/lessons.ts +0 -253
  85. package/src/functions/mesh.ts +0 -434
  86. package/src/functions/migrate.ts +0 -165
  87. package/src/functions/observe.ts +0 -144
  88. package/src/functions/obsidian-export.ts +0 -310
  89. package/src/functions/patterns.ts +0 -138
  90. package/src/functions/privacy.ts +0 -39
  91. package/src/functions/profile.ts +0 -155
  92. package/src/functions/query-expansion.ts +0 -186
  93. package/src/functions/relations.ts +0 -237
  94. package/src/functions/remember.ts +0 -162
  95. package/src/functions/retention.ts +0 -235
  96. package/src/functions/routines.ts +0 -289
  97. package/src/functions/search.ts +0 -80
  98. package/src/functions/sentinels.ts +0 -417
  99. package/src/functions/signals.ts +0 -186
  100. package/src/functions/sketches.ts +0 -274
  101. package/src/functions/sliding-window.ts +0 -257
  102. package/src/functions/smart-search.ts +0 -115
  103. package/src/functions/snapshot.ts +0 -219
  104. package/src/functions/summarize.ts +0 -155
  105. package/src/functions/team.ts +0 -147
  106. package/src/functions/temporal-graph.ts +0 -476
  107. package/src/functions/timeline.ts +0 -138
  108. package/src/functions/verify.ts +0 -117
  109. package/src/health/monitor.ts +0 -110
  110. package/src/health/thresholds.ts +0 -73
  111. package/src/hooks/notification.ts +0 -52
  112. package/src/hooks/post-tool-failure.ts +0 -58
  113. package/src/hooks/post-tool-use.ts +0 -62
  114. package/src/hooks/pre-compact.ts +0 -60
  115. package/src/hooks/pre-tool-use.ts +0 -72
  116. package/src/hooks/prompt-submit.ts +0 -46
  117. package/src/hooks/session-end.ts +0 -71
  118. package/src/hooks/session-start.ts +0 -48
  119. package/src/hooks/stop.ts +0 -39
  120. package/src/hooks/subagent-start.ts +0 -49
  121. package/src/hooks/subagent-stop.ts +0 -54
  122. package/src/hooks/task-completed.ts +0 -54
  123. package/src/index.ts +0 -342
  124. package/src/mcp/in-memory-kv.ts +0 -61
  125. package/src/mcp/server.ts +0 -1455
  126. package/src/mcp/standalone.ts +0 -177
  127. package/src/mcp/tools-registry.ts +0 -769
  128. package/src/mcp/transport.ts +0 -91
  129. package/src/prompts/compression.ts +0 -67
  130. package/src/prompts/consolidation.ts +0 -48
  131. package/src/prompts/graph-extraction.ts +0 -35
  132. package/src/prompts/summary.ts +0 -38
  133. package/src/prompts/xml.ts +0 -26
  134. package/src/providers/agent-sdk.ts +0 -34
  135. package/src/providers/anthropic.ts +0 -35
  136. package/src/providers/circuit-breaker.ts +0 -82
  137. package/src/providers/embedding/cohere.ts +0 -46
  138. package/src/providers/embedding/gemini.ts +0 -54
  139. package/src/providers/embedding/index.ts +0 -39
  140. package/src/providers/embedding/local.ts +0 -52
  141. package/src/providers/embedding/openai.ts +0 -45
  142. package/src/providers/embedding/openrouter.ts +0 -51
  143. package/src/providers/embedding/voyage.ts +0 -46
  144. package/src/providers/fallback-chain.ts +0 -31
  145. package/src/providers/index.ts +0 -84
  146. package/src/providers/openrouter.ts +0 -71
  147. package/src/providers/resilient.ts +0 -37
  148. package/src/state/hybrid-search.ts +0 -295
  149. package/src/state/index-persistence.ts +0 -63
  150. package/src/state/keyed-mutex.ts +0 -18
  151. package/src/state/kv.ts +0 -33
  152. package/src/state/schema.ts +0 -71
  153. package/src/state/search-index.ts +0 -245
  154. package/src/state/stemmer.ts +0 -104
  155. package/src/state/synonyms.ts +0 -63
  156. package/src/state/vector-index.ts +0 -130
  157. package/src/telemetry/setup.ts +0 -116
  158. package/src/triggers/api.ts +0 -1904
  159. package/src/triggers/events.ts +0 -71
  160. package/src/types.ts +0 -769
  161. package/src/version.ts +0 -1
  162. package/src/viewer/index.html +0 -2497
  163. package/src/viewer/server.ts +0 -207
  164. package/src/xenova.d.ts +0 -3
  165. package/test/actions.test.ts +0 -490
  166. package/test/audit.test.ts +0 -108
  167. package/test/auto-forget.test.ts +0 -188
  168. package/test/cascade.test.ts +0 -277
  169. package/test/checkpoints.test.ts +0 -493
  170. package/test/circuit-breaker.test.ts +0 -107
  171. package/test/claude-bridge.test.ts +0 -178
  172. package/test/confidence.test.ts +0 -247
  173. package/test/consistency.test.ts +0 -61
  174. package/test/consolidation-pipeline.test.ts +0 -251
  175. package/test/crystallize.test.ts +0 -521
  176. package/test/diagnostics.test.ts +0 -638
  177. package/test/embedding-provider.test.ts +0 -49
  178. package/test/enrich.test.ts +0 -209
  179. package/test/eval.test.ts +0 -300
  180. package/test/export-import.test.ts +0 -251
  181. package/test/facets.test.ts +0 -448
  182. package/test/fallback-chain.test.ts +0 -93
  183. package/test/frontier.test.ts +0 -485
  184. package/test/governance.test.ts +0 -147
  185. package/test/graph-retrieval.test.ts +0 -186
  186. package/test/graph.test.ts +0 -160
  187. package/test/helpers/mocks.ts +0 -40
  188. package/test/hybrid-search.test.ts +0 -145
  189. package/test/index-persistence.test.ts +0 -124
  190. package/test/integration.test.ts +0 -265
  191. package/test/leases.test.ts +0 -399
  192. package/test/mcp-prompts.test.ts +0 -218
  193. package/test/mcp-resources.test.ts +0 -286
  194. package/test/mcp-standalone.test.ts +0 -113
  195. package/test/mesh.test.ts +0 -700
  196. package/test/privacy.test.ts +0 -87
  197. package/test/profile.test.ts +0 -161
  198. package/test/query-expansion.test.ts +0 -154
  199. package/test/relations.test.ts +0 -198
  200. package/test/retention.test.ts +0 -245
  201. package/test/routines.test.ts +0 -497
  202. package/test/schema-fingerprint.test.ts +0 -81
  203. package/test/schema.test.ts +0 -42
  204. package/test/search-index.test.ts +0 -128
  205. package/test/sentinels.test.ts +0 -626
  206. package/test/signals.test.ts +0 -410
  207. package/test/sketches.test.ts +0 -549
  208. package/test/sliding-window.test.ts +0 -199
  209. package/test/smart-search.test.ts +0 -169
  210. package/test/snapshot.test.ts +0 -165
  211. package/test/team.test.ts +0 -156
  212. package/test/temporal-graph.test.ts +0 -378
  213. package/test/timeline.test.ts +0 -148
  214. package/test/vector-index.test.ts +0 -79
  215. package/test/verify.test.ts +0 -209
  216. package/test/xml.test.ts +0 -65
  217. package/tsconfig.json +0 -22
  218. package/tsdown.config.ts +0 -62
package/AGENTS.md CHANGED
@@ -98,7 +98,7 @@ Hook scripts in `src/hooks/` are standalone Node.js scripts (no iii-sdk import).
98
98
 
99
99
  ## Testing
100
100
 
101
- - All tests must pass before PR: `npm test` (573+ tests)
101
+ - All tests must pass before PR: `npm test` (613+ tests)
102
102
  - Mock pattern: `vi.mock("iii-sdk")` with mock `sdk.trigger`, `kv.get/set/list`
103
103
  - Test files go in `test/` with `.test.ts` extension
104
104
  - Follow existing patterns in `test/crystallize.test.ts` for function tests
@@ -110,4 +110,4 @@ Hook scripts in `src/hooks/` are standalone Node.js scripts (no iii-sdk import).
110
110
  - 6 MCP resources, 3 MCP prompts
111
111
  - 12 hooks, 4 skills
112
112
  - 50+ iii functions
113
- - 573 tests
113
+ - 614 tests
package/README.md CHANGED
@@ -26,14 +26,12 @@
26
26
 
27
27
  ---
28
28
 
29
- Every AI coding agent has the same blind spot. Session ends, memory vanishes. You re-explain architecture. You re-discover bugs. You re-teach preferences. Built-in memory files like CLAUDE.md and .cursorrules are 200-line sticky notes that overflow and go stale. agentmemory replaces that with a searchable, versioned, cross-agent database — 41 MCP tools, triple-stream retrieval (BM25 + vector + knowledge graph), 4-tier memory consolidation, provenance-tracked citations, and cascading staleness so retired facts never pollute your context again. One instance serves Claude Code, Cursor, Codex, Windsurf, and any MCP client simultaneously. 573 tests. Zero external DB dependencies.
29
+ Every AI coding agent has the same blind spot. Session ends, memory vanishes. You re-explain architecture. You re-discover bugs. You re-teach preferences. Built-in memory files like CLAUDE.md and .cursorrules are 200-line sticky notes that overflow and go stale. agentmemory replaces that with a searchable, versioned, cross-agent database — 41 MCP tools, triple-stream retrieval (BM25 + vector + knowledge graph), 4-tier memory consolidation, provenance-tracked citations, and cascading staleness so retired facts never pollute your context again. One instance serves Claude Code, Cursor, Codex, Windsurf, and any MCP client simultaneously. 614 tests. Zero external DB dependencies.
30
30
 
31
31
  The result is measurable. On 240 real observations across 30 sessions, agentmemory hits 64% Recall@10 and perfect MRR while using 92% fewer tokens than dumping everything into context. When an agent searches "database performance optimization," it finds the N+1 fix you made three weeks ago — something keyword grep literally cannot do. Memories version automatically, supersede each other, propagate staleness to related graph nodes, and sync across agent instances via P2P mesh. Your agents stop repeating mistakes. Your context stays clean. Your sessions start fast.
32
32
 
33
33
  ```bash
34
- git clone https://github.com/rohitg00/agentmemory.git && cd agentmemory
35
- docker compose up -d && npm install && npm run build && npm start
36
- curl http://localhost:3111/agentmemory/health
34
+ npx @agentmemory/agentmemory # installs iii-engine if missing, starts everything
37
35
  ```
38
36
 
39
37
  ---
@@ -162,8 +160,8 @@ GET /agentmemory/profile # Get project intelligence
162
160
  |---|---|
163
161
  | Claude Code user | Plugin install (hooks + MCP + skills) |
164
162
  | Building a custom agent with Claude SDK | AgentSDKProvider (zero config) |
165
- | Using Cursor, Windsurf, or any MCP client | MCP server (38 tools + 6 resources + 3 prompts) |
166
- | Building your own agent framework | REST API (93 endpoints) |
163
+ | Using Cursor, Windsurf, or any MCP client | MCP server (41 tools + 6 resources + 3 prompts) |
164
+ | Building your own agent framework | REST API (100 endpoints) |
167
165
  | Sharing memory across multiple agents | All agents point to the same iii-engine instance |
168
166
 
169
167
  ## Quick Start
@@ -177,17 +175,22 @@ GET /agentmemory/profile # Get project intelligence
177
175
 
178
176
  All 12 hooks, 4 skills, and MCP server are registered automatically.
179
177
 
180
- ### 2. Start the Worker
178
+ ### 2. Start agentmemory
181
179
 
182
180
  ```bash
183
- git clone https://github.com/rohitg00/agentmemory.git
184
- cd agentmemory
181
+ npx @agentmemory/agentmemory
182
+ ```
183
+
184
+ This auto-installs iii-engine if missing, starts it, and runs the worker. One command.
185
+
186
+ Or from source:
185
187
 
186
- docker compose up -d # Start iii-engine
188
+ ```bash
189
+ git clone https://github.com/rohitg00/agentmemory.git && cd agentmemory
187
190
  npm install && npm run build && npm start
188
191
  ```
189
192
 
190
- ### 3. Verify
193
+ ### 4. Verify
191
194
 
192
195
  ```bash
193
196
  curl http://localhost:3111/agentmemory/health
@@ -200,7 +203,7 @@ open http://localhost:3113
200
203
  {
201
204
  "status": "healthy",
202
205
  "service": "agentmemory",
203
- "version": "0.6.1",
206
+ "version": "0.7.1",
204
207
  "health": {
205
208
  "memory": { "heapUsed": 42000000, "heapTotal": 67000000 },
206
209
  "cpu": { "percent": 2.1 },
@@ -604,9 +607,18 @@ ANTHROPIC_API_KEY=sk-ant-...
604
607
  # GRAPH_EXTRACTION_BATCH_SIZE=10
605
608
 
606
609
  # Consolidation Pipeline (v0.5.0)
607
- # CONSOLIDATION_ENABLED=false
610
+ # CONSOLIDATION_ENABLED=true
608
611
  # CONSOLIDATION_DECAY_DAYS=30
609
612
 
613
+ # Lesson Decay (v0.7.0)
614
+ # LESSON_DECAY_ENABLED=true
615
+
616
+ # Obsidian Export (v0.7.0)
617
+ # OBSIDIAN_AUTO_EXPORT=false
618
+
619
+ # MCP Tool Visibility (v0.7.0) — "core" (7 tools) or "all" (41 tools)
620
+ # AGENTMEMORY_TOOLS=core
621
+
610
622
  # Team Memory (v0.5.0)
611
623
  # TEAM_ID=
612
624
  # USER_ID=
@@ -667,6 +679,11 @@ ANTHROPIC_API_KEY=sk-ant-...
667
679
  | `GET` | `/agentmemory/snapshots` | List git snapshots |
668
680
  | `POST` | `/agentmemory/snapshot/create` | Create git-versioned snapshot |
669
681
  | `POST` | `/agentmemory/snapshot/restore` | Restore from snapshot commit |
682
+ | `POST` | `/agentmemory/lessons` | Save a lesson (returns 201 if created, 200 if strengthened) |
683
+ | `GET` | `/agentmemory/lessons` | List lessons (`?project=X&minConfidence=0.5`) |
684
+ | `POST` | `/agentmemory/lessons/search` | Search lessons by query |
685
+ | `POST` | `/agentmemory/lessons/strengthen` | Reinforce a lesson's confidence |
686
+ | `POST` | `/agentmemory/obsidian/export` | Export vault as Obsidian Markdown |
670
687
  | `GET` | `/agentmemory/mcp/tools` | List MCP tools |
671
688
  | `POST` | `/agentmemory/mcp/call` | Execute MCP tool |
672
689
  | `GET` | `/agentmemory/mcp/resources` | List MCP resources |
@@ -707,71 +724,47 @@ agentmemory is built on iii-engine's three primitives:
707
724
  | Prometheus / Grafana | iii OTEL + built-in health monitor |
708
725
  | Redis (circuit breaker) | In-process circuit breaker + fallback chain |
709
726
 
710
- **105+ source files. ~16,000 LOC. 573 tests. Zero external DB dependencies.**
711
-
712
- ### Functions (52)
713
-
714
- | Function | Purpose |
715
- |----------|---------|
716
- | `mem::observe` | Store raw observation with dedup check |
717
- | `mem::compress` | LLM compression with validation + quality scoring + embedding |
718
- | `mem::search` | BM25-ranked full-text search |
719
- | `mem::smart-search` | Hybrid search with progressive disclosure |
720
- | `mem::context` | Build session context within token budget |
721
- | `mem::summarize` | Generate validated session summaries |
722
- | `mem::remember` | Save to long-term memory (auto-supersedes similar) |
723
- | `mem::forget` | Delete observations, sessions, or memories |
724
- | `mem::file-index` | File-specific observation lookup |
725
- | `mem::consolidate` | Merge duplicate observations |
726
- | `mem::patterns` | Detect recurring patterns |
727
- | `mem::generate-rules` | Generate CLAUDE.md rules from patterns |
728
- | `mem::migrate` | Import from SQLite |
729
- | `mem::evict` | Age + importance + cap-based memory eviction |
730
- | `mem::relate` | Create relationship between memories |
731
- | `mem::evolve` | Create new version of a memory |
732
- | `mem::get-related` | Traverse memory relationship graph |
733
- | `mem::timeline` | Chronological observations around anchor |
734
- | `mem::profile` | Aggregate project profile |
735
- | `mem::auto-forget` | TTL expiry + contradiction detection |
736
- | `mem::enrich` | Unified enrichment (file context + observations + bug memories) |
737
- | `mem::export` / `mem::import` | Full JSON round-trip (v0.3.0 + v0.4.0 + v0.5.0 formats) |
738
- | `mem::claude-bridge-read` | Read Claude Code native MEMORY.md |
739
- | `mem::claude-bridge-sync` | Sync top memories back to MEMORY.md |
740
- | `mem::graph-extract` | LLM-powered entity extraction from observations |
741
- | `mem::graph-query` | BFS traversal of knowledge graph |
742
- | `mem::graph-stats` | Node/edge counts by type |
743
- | `mem::consolidate-pipeline` | 4-tier memory consolidation with strength decay |
744
- | `mem::team-share` | Share memory/observation with team namespace |
745
- | `mem::team-feed` | Fetch recent shared items from team |
746
- | `mem::team-profile` | Aggregate team concepts, files, patterns |
747
- | `mem::governance-delete` | Delete specific memories with audit trail |
748
- | `mem::governance-bulk` | Bulk delete by type/date/quality filter |
749
- | `mem::snapshot-create` | Git commit memory state |
750
- | `mem::snapshot-list` | List all snapshots |
751
- | `mem::snapshot-restore` | Restore memory from snapshot commit |
752
- | `mem::action-create` / `action-update` | Dependency-aware work items with typed edges |
753
- | `mem::frontier` / `mem::next` | Priority-ranked unblocked action queue |
754
- | `mem::lease-acquire` / `release` / `renew` | TTL-based atomic agent claims |
755
- | `mem::routine-create` / `run` / `status` | Frozen workflow templates instantiated into action chains |
756
- | `mem::signal-send` / `read` / `threads` | Threaded inter-agent messaging with read receipts |
757
- | `mem::checkpoint-create` / `resolve` | External condition gates (CI, approval, deploy) |
758
- | `mem::flow-compress` | LLM-powered summarization of completed action chains |
759
- | `mem::mesh-register` / `sync` / `receive` | P2P sync between agentmemory instances |
760
- | `mem::detect-worktree` / `branch-sessions` | Git worktree detection for shared memory |
761
- | `mem::sentinel-create` / `trigger` / `check` | Event-driven condition watchers (webhook, timer, threshold, pattern, approval) |
762
- | `mem::sketch-create` / `add` / `promote` / `discard` | Ephemeral action graphs for exploratory work with auto-expiry |
763
- | `mem::crystallize` / `auto-crystallize` | LLM-powered compaction of completed action chains into crystal digests |
764
- | `mem::diagnose` / `heal` | Self-diagnosis across 8 categories with auto-fix for stuck/orphaned/stale state |
765
- | `mem::facet-tag` / `query` / `stats` | Multi-dimensional tagging with AND/OR queries on actions, memories, observations |
766
- | `mem::expand-query` | LLM-generated query reformulations for improved recall |
767
- | `mem::sliding-window` | Context-window enrichment at ingestion (resolve pronouns, abbreviations) |
768
- | `mem::temporal-graph` | Append-only versioned edges with point-in-time queries |
769
- | `mem::retention-score` / `evict` | Ebbinghaus-inspired decay with tiered storage (hot/warm/cold/evictable) |
770
- | `mem::graph-retrieval` | Entity search + chunk expansion + temporal queries via knowledge graph |
771
- | `mem::verify` | JIT verification — trace memory provenance back to source observations |
772
- | `mem::cascade-update` | Propagate staleness to graph nodes, edges, and sibling memories |
773
-
774
- ### Data Model (33 KV scopes)
727
+ **113 source files. ~20,000 LOC. 614 tests. Zero external DB dependencies.**
728
+
729
+ ### Functions (89 mem:: functions)
730
+
731
+ | Category | Functions | Purpose |
732
+ |----------|-----------|---------|
733
+ | **Core Memory** | `observe`, `compress`, `search`, `smart-search` | Capture, compress, and search observations |
734
+ | | `context`, `summarize`, `remember`, `forget` | Build context, generate summaries, save/delete memories |
735
+ | | `file-context`, `enrich`, `patterns`, `generate-rules` | File history, enrichment, pattern detection, rule generation |
736
+ | | `migrate`, `export`, `import` | SQLite migration, JSON round-trip (v0.3.0–v0.7.2) |
737
+ | **Search** | `expand-query`, `sliding-window`, `graph-retrieval` | Query reformulations, context enrichment, entity-based retrieval |
738
+ | | `retention-score`, `retention-evict` | Ebbinghaus decay with tiered storage (hot/warm/cold) |
739
+ | **Memory Evolution** | `evolve`, `auto-forget`, `evict` | Version memories, TTL expiry, importance-based eviction |
740
+ | | `consolidate`, `consolidate-pipeline` | Merge duplicates, 4-tier consolidation (working→episodic→semantic→procedural) |
741
+ | | `verify`, `cascade-update` | Citation chain provenance, staleness propagation |
742
+ | **Knowledge Graph** | `graph-extract`, `graph-query`, `graph-stats` | LLM entity extraction, BFS traversal, statistics |
743
+ | | `temporal-graph-extract`, `temporal-query` | Temporal knowledge extraction + point-in-time queries |
744
+ | **Relationships** | `relate`, `get-related`, `timeline`, `profile` | Memory relations, chronological view, project profiles |
745
+ | **Claude Bridge** | `claude-bridge-read`, `claude-bridge-sync` | Bi-directional sync with MEMORY.md |
746
+ | **Actions** | `action-create`, `action-update`, `action-get`, `action-list` | Dependency-aware work items with typed edges |
747
+ | | `action-edge-create` | Create typed edges between actions (requires, unlocks, gated_by) |
748
+ | | `frontier`, `next` | Priority-ranked unblocked action queue |
749
+ | **Leases** | `lease-acquire`, `lease-release`, `lease-renew`, `lease-cleanup` | TTL-based atomic agent claims with auto-cleanup |
750
+ | **Routines** | `routine-create`, `routine-freeze`, `routine-list`, `routine-run`, `routine-status` | Frozen workflow templates instantiated into action chains |
751
+ | **Signals** | `signal-send`, `signal-read`, `signal-threads`, `signal-cleanup` | Threaded inter-agent messaging with read receipts |
752
+ | **Checkpoints** | `checkpoint-create`, `checkpoint-resolve`, `checkpoint-list`, `checkpoint-expire` | External condition gates (CI, approval, deploy) |
753
+ | **Mesh** | `mesh-register`, `mesh-sync`, `mesh-receive`, `mesh-list`, `mesh-remove` | P2P sync between agentmemory instances |
754
+ | **Sentinels** | `sentinel-create`, `sentinel-trigger`, `sentinel-check`, `sentinel-cancel`, `sentinel-list`, `sentinel-expire` | Event-driven condition watchers |
755
+ | **Sketches** | `sketch-create`, `sketch-add`, `sketch-promote`, `sketch-discard`, `sketch-list`, `sketch-gc` | Ephemeral action graphs with auto-expiry |
756
+ | **Crystals** | `crystallize`, `auto-crystallize`, `crystal-list`, `crystal-get` | LLM-powered compaction of action chains into digests |
757
+ | **Lessons** | `lesson-save`, `lesson-recall`, `lesson-list`, `lesson-strengthen`, `lesson-decay-sweep` | Confidence-scored lessons with dedup, reinforcement, and decay |
758
+ | **Facets** | `facet-tag`, `facet-untag`, `facet-query`, `facet-get`, `facet-stats`, `facet-dimensions` | Multi-dimensional tagging with AND/OR queries |
759
+ | **Diagnostics** | `diagnose`, `heal` | Self-diagnosis across 8 categories with auto-fix |
760
+ | **Flow** | `flow-compress` | LLM summarization of completed action chains |
761
+ | **Branch** | `detect-worktree`, `list-worktrees`, `branch-sessions` | Git worktree detection for shared memory |
762
+ | **Team** | `team-share`, `team-feed`, `team-profile` | Namespaced shared + private team memory |
763
+ | **Governance** | `governance-delete`, `governance-bulk`, `audit-query` | Delete with audit trail, bulk operations |
764
+ | **Snapshots** | `snapshot-create`, `snapshot-list`, `snapshot-restore` | Git-versioned memory state |
765
+ | **Export** | `obsidian-export` | Obsidian-compatible Markdown with YAML frontmatter + wikilinks |
766
+
767
+ ### Data Model (34 KV scopes)
775
768
 
776
769
  | Scope | Stores |
777
770
  |-------|--------|
@@ -808,20 +801,21 @@ agentmemory is built on iii-engine's three primitives:
808
801
  | `mem:sketches` | Ephemeral action graphs |
809
802
  | `mem:crystals` | Compacted action chain digests |
810
803
  | `mem:facets` | Multi-dimensional tags |
804
+ | `mem:lessons` | Confidence-scored lessons with decay |
811
805
 
812
806
  ## Development
813
807
 
814
808
  ```bash
815
809
  npm run dev # Hot reload
816
- npm run build # Production build (365KB)
817
- npm test # Unit tests (573 tests, ~1.5s)
810
+ npm run build # Production build (~425KB)
811
+ npm test # Unit tests (614 tests, ~1.5s)
818
812
  npm run test:integration # API tests (requires running services)
819
813
  ```
820
814
 
821
815
  ### Prerequisites
822
816
 
823
- - Node.js >= 18
824
- - Docker
817
+ - Node.js >= 20
818
+ - [iii-engine](https://iii.dev/docs) (`curl -fsSL https://install.iii.dev/iii/main/install.sh | sh`)
825
819
 
826
820
  ## License
827
821
 
package/dist/cli.mjs CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { execFileSync, spawn } from "node:child_process";
2
+ import { execFileSync, execSync, spawn } from "node:child_process";
3
3
  import { existsSync } from "node:fs";
4
4
  import { dirname, join } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
+ import * as p from "@clack/prompts";
6
7
 
7
8
  //#region src/cli.ts
8
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -20,14 +21,14 @@ Options:
20
21
  --port <N> Override REST port (default: 3111)
21
22
 
22
23
  Environment:
23
- AGENTMEMORY_TOOLS=all Expose all 41 MCP tools
24
- AGENTMEMORY_SECRET=xxx Auth secret for REST/MCP
24
+ AGENTMEMORY_TOOLS=all Expose all 41 MCP tools
25
+ AGENTMEMORY_SECRET=xxx Auth secret for REST/MCP
25
26
  CONSOLIDATION_ENABLED=true Enable auto-consolidation (off by default)
26
27
  OBSIDIAN_AUTO_EXPORT=true Auto-export on consolidation
27
28
 
28
29
  Quick start:
29
- npx agentmemory # auto-starts iii-engine, runs worker
30
- npx agentmemory-mcp # standalone MCP server (no engine needed)
30
+ npx @agentmemory/agentmemory # installs iii if missing, starts everything
31
+ npx agentmemory-mcp # standalone MCP server (no engine needed)
31
32
  `);
32
33
  process.exit(0);
33
34
  }
@@ -63,23 +64,74 @@ function whichBinary(name) {
63
64
  return null;
64
65
  }
65
66
  }
67
+ async function installIii() {
68
+ if (process.platform === "win32") {
69
+ p.log.warn("Automatic iii-engine install is not supported on Windows.");
70
+ p.log.info("Install manually: https://iii.dev/docs");
71
+ return false;
72
+ }
73
+ if (!whichBinary("curl")) {
74
+ p.log.warn("curl not found — cannot auto-install iii-engine.");
75
+ return false;
76
+ }
77
+ const shouldInstall = await p.confirm({
78
+ message: "iii-engine is not installed. Install it now?",
79
+ initialValue: true
80
+ });
81
+ if (p.isCancel(shouldInstall) || !shouldInstall) return false;
82
+ const s = p.spinner();
83
+ s.start("Installing iii-engine...");
84
+ try {
85
+ execSync("curl -fsSL https://install.iii.dev/iii/main/install.sh | sh", {
86
+ stdio: [
87
+ "pipe",
88
+ "pipe",
89
+ "pipe"
90
+ ],
91
+ timeout: 12e4
92
+ });
93
+ if (whichBinary("iii")) {
94
+ s.stop("iii-engine installed successfully");
95
+ return true;
96
+ }
97
+ s.stop("Installation completed but iii not found in PATH");
98
+ p.log.warn("You may need to restart your shell or add iii to your PATH.");
99
+ const iiiPaths = [join(process.env["HOME"] || "", ".local", "bin", "iii"), "/usr/local/bin/iii"];
100
+ for (const iiiPath of iiiPaths) if (existsSync(iiiPath)) {
101
+ p.log.info(`Found iii at: ${iiiPath}`);
102
+ process.env["PATH"] = `${dirname(iiiPath)}:${process.env["PATH"]}`;
103
+ return true;
104
+ }
105
+ return false;
106
+ } catch (err) {
107
+ s.stop("Failed to install iii-engine");
108
+ p.log.error(err instanceof Error ? err.message : String(err));
109
+ return false;
110
+ }
111
+ }
66
112
  async function startEngine() {
67
113
  const configPath = findIiiConfig();
68
- const iiiBin = whichBinary("iii");
114
+ let iiiBin = whichBinary("iii");
115
+ if (!iiiBin) {
116
+ if (await installIii()) iiiBin = whichBinary("iii");
117
+ }
69
118
  if (iiiBin && configPath) {
70
- console.log(`[agentmemory] Starting iii-engine: ${iiiBin} --config ${configPath}`);
119
+ const s = p.spinner();
120
+ s.start(`Starting iii-engine: ${iiiBin}`);
71
121
  spawn(iiiBin, ["--config", configPath], {
72
122
  detached: true,
73
123
  stdio: "ignore"
74
124
  }).unref();
125
+ s.stop("iii-engine process started");
75
126
  return true;
76
127
  }
128
+ const dockerBin = whichBinary("docker");
77
129
  const dockerCompose = join(__dirname, "..", "docker-compose.yml");
78
130
  const dcExists = existsSync(dockerCompose) || existsSync(join(process.cwd(), "docker-compose.yml"));
79
- const dockerBin = whichBinary("docker");
80
131
  if (dockerBin && dcExists) {
81
132
  const composeFile = existsSync(dockerCompose) ? dockerCompose : join(process.cwd(), "docker-compose.yml");
82
- console.log(`[agentmemory] Starting iii-engine via Docker...`);
133
+ const s = p.spinner();
134
+ s.start("Starting iii-engine via Docker...");
83
135
  spawn(dockerBin, [
84
136
  "compose",
85
137
  "-f",
@@ -90,6 +142,7 @@ async function startEngine() {
90
142
  detached: true,
91
143
  stdio: "ignore"
92
144
  }).unref();
145
+ s.stop("Docker compose started");
93
146
  return true;
94
147
  }
95
148
  return false;
@@ -103,32 +156,46 @@ async function waitForEngine(timeoutMs) {
103
156
  return false;
104
157
  }
105
158
  async function main() {
106
- if (!skipEngine && !await isEngineRunning()) {
107
- if (!await startEngine()) {
108
- console.error(`
109
- [agentmemory] iii-engine is not running and could not be auto-started.
110
-
111
- Install one of:
112
- 1. iii CLI: npm install -g iii-engine
113
- 2. Docker: docker compose up -d (with docker-compose.yml)
114
-
115
- Or run with --no-engine to connect to a remote engine.
116
- `);
117
- process.exit(1);
118
- }
119
- console.log(`[agentmemory] Waiting for iii-engine to start...`);
120
- if (!await waitForEngine(15e3)) {
121
- const port = getRestPort();
122
- console.error(`[agentmemory] iii-engine did not become ready within 15s.`);
123
- console.error(`[agentmemory] Check that ports ${port}, ${port + 1}, 49134 are available.`);
124
- process.exit(1);
125
- }
126
- console.log(`[agentmemory] iii-engine is ready.`);
159
+ p.intro("agentmemory");
160
+ if (skipEngine) {
161
+ p.log.info("Skipping engine check (--no-engine)");
162
+ await import("./src-sYZDDbiA.mjs");
163
+ return;
164
+ }
165
+ if (await isEngineRunning()) {
166
+ p.log.success("iii-engine is running");
167
+ await import("./src-sYZDDbiA.mjs");
168
+ return;
169
+ }
170
+ if (!await startEngine()) {
171
+ p.log.error("Could not start iii-engine.");
172
+ p.note([
173
+ "Install iii-engine (pick one):",
174
+ " curl -fsSL https://install.iii.dev/iii/main/install.sh | sh",
175
+ " cargo install iii-engine",
176
+ "",
177
+ "Or use Docker:",
178
+ " docker pull iiidev/iii:latest",
179
+ "",
180
+ "Docs: https://iii.dev/docs",
181
+ "",
182
+ "Or skip with: agentmemory --no-engine"
183
+ ].join("\n"), "Setup required");
184
+ process.exit(1);
185
+ }
186
+ const s = p.spinner();
187
+ s.start("Waiting for iii-engine to be ready...");
188
+ if (!await waitForEngine(15e3)) {
189
+ const port = getRestPort();
190
+ s.stop("iii-engine did not become ready within 15s");
191
+ p.log.error(`Check that ports ${port}, ${port + 1}, 49134 are available.`);
192
+ process.exit(1);
127
193
  }
128
- await import("./src-QxitMPfJ.mjs");
194
+ s.stop("iii-engine is ready");
195
+ await import("./src-sYZDDbiA.mjs");
129
196
  }
130
197
  main().catch((err) => {
131
- console.error(`[agentmemory] Fatal:`, err);
198
+ p.log.error(err instanceof Error ? err.message : String(err));
132
199
  process.exit(1);
133
200
  });
134
201
 
package/dist/cli.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { spawn, execFileSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\n\nconst args = process.argv.slice(2);\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nagentmemory — persistent memory for AI coding agents\n\nUsage: agentmemory [options]\n\nOptions:\n --help, -h Show this help\n --tools all|core Tool visibility (default: core = 7 tools)\n --no-engine Skip auto-starting iii-engine\n --port <N> Override REST port (default: 3111)\n\nEnvironment:\n AGENTMEMORY_TOOLS=all Expose all 41 MCP tools\n AGENTMEMORY_SECRET=xxx Auth secret for REST/MCP\n CONSOLIDATION_ENABLED=true Enable auto-consolidation (off by default)\n OBSIDIAN_AUTO_EXPORT=true Auto-export on consolidation\n\nQuick start:\n npx agentmemory # auto-starts iii-engine, runs worker\n npx agentmemory-mcp # standalone MCP server (no engine needed)\n`);\n process.exit(0);\n}\n\nconst toolsIdx = args.indexOf(\"--tools\");\nif (toolsIdx !== -1 && args[toolsIdx + 1]) {\n process.env[\"AGENTMEMORY_TOOLS\"] = args[toolsIdx + 1];\n}\n\nconst portIdx = args.indexOf(\"--port\");\nif (portIdx !== -1 && args[portIdx + 1]) {\n process.env[\"III_REST_PORT\"] = args[portIdx + 1];\n}\n\nconst skipEngine = args.includes(\"--no-engine\");\n\nfunction getRestPort(): number {\n return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n const res = await fetch(`http://localhost:${getRestPort()}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nfunction findIiiConfig(): string {\n const candidates = [\n join(__dirname, \"iii-config.yaml\"),\n join(__dirname, \"..\", \"iii-config.yaml\"),\n join(process.cwd(), \"iii-config.yaml\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return \"\";\n}\n\nfunction whichBinary(name: string): string | null {\n const cmd = process.platform === \"win32\" ? \"where\" : \"which\";\n try {\n return execFileSync(cmd, [name], { encoding: \"utf-8\" }).trim().split(\"\\n\")[0];\n } catch {\n return null;\n }\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n\n const iiiBin = whichBinary(\"iii\");\n if (iiiBin && configPath) {\n console.log(`[agentmemory] Starting iii-engine: ${iiiBin} --config ${configPath}`);\n const child = spawn(iiiBin, [\"--config\", configPath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n return true;\n }\n\n const dockerCompose = join(__dirname, \"..\", \"docker-compose.yml\");\n const dcExists = existsSync(dockerCompose) || existsSync(join(process.cwd(), \"docker-compose.yml\"));\n const dockerBin = whichBinary(\"docker\");\n\n if (dockerBin && dcExists) {\n const composeFile = existsSync(dockerCompose) ? dockerCompose : join(process.cwd(), \"docker-compose.yml\");\n console.log(`[agentmemory] Starting iii-engine via Docker...`);\n const child = spawn(dockerBin, [\"compose\", \"-f\", composeFile, \"up\", \"-d\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n return true;\n }\n\n return false;\n}\n\nasync function waitForEngine(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isEngineRunning()) return true;\n await new Promise((r) => setTimeout(r, 500));\n }\n return false;\n}\n\nasync function main() {\n if (!skipEngine && !(await isEngineRunning())) {\n const started = await startEngine();\n if (!started) {\n console.error(`\n[agentmemory] iii-engine is not running and could not be auto-started.\n\nInstall one of:\n 1. iii CLI: npm install -g iii-engine\n 2. Docker: docker compose up -d (with docker-compose.yml)\n\nOr run with --no-engine to connect to a remote engine.\n`);\n process.exit(1);\n }\n\n console.log(`[agentmemory] Waiting for iii-engine to start...`);\n const ready = await waitForEngine(15000);\n if (!ready) {\n const port = getRestPort();\n console.error(`[agentmemory] iii-engine did not become ready within 15s.`);\n console.error(`[agentmemory] Check that ports ${port}, ${port + 1}, 49134 are available.`);\n process.exit(1);\n }\n console.log(`[agentmemory] iii-engine is ready.`);\n }\n\n await import(\"./index.js\");\n}\n\nmain().catch((err) => {\n console.error(`[agentmemory] Fatal:`, err);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cli.mjs","names":[],"sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { spawn, execFileSync, execSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { join, dirname } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport * as p from \"@clack/prompts\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst args = process.argv.slice(2);\n\nif (args.includes(\"--help\") || args.includes(\"-h\")) {\n console.log(`\nagentmemory — persistent memory for AI coding agents\n\nUsage: agentmemory [options]\n\nOptions:\n --help, -h Show this help\n --tools all|core Tool visibility (default: core = 7 tools)\n --no-engine Skip auto-starting iii-engine\n --port <N> Override REST port (default: 3111)\n\nEnvironment:\n AGENTMEMORY_TOOLS=all Expose all 41 MCP tools\n AGENTMEMORY_SECRET=xxx Auth secret for REST/MCP\n CONSOLIDATION_ENABLED=true Enable auto-consolidation (off by default)\n OBSIDIAN_AUTO_EXPORT=true Auto-export on consolidation\n\nQuick start:\n npx @agentmemory/agentmemory # installs iii if missing, starts everything\n npx agentmemory-mcp # standalone MCP server (no engine needed)\n`);\n process.exit(0);\n}\n\nconst toolsIdx = args.indexOf(\"--tools\");\nif (toolsIdx !== -1 && args[toolsIdx + 1]) {\n process.env[\"AGENTMEMORY_TOOLS\"] = args[toolsIdx + 1];\n}\n\nconst portIdx = args.indexOf(\"--port\");\nif (portIdx !== -1 && args[portIdx + 1]) {\n process.env[\"III_REST_PORT\"] = args[portIdx + 1];\n}\n\nconst skipEngine = args.includes(\"--no-engine\");\n\nfunction getRestPort(): number {\n return parseInt(process.env[\"III_REST_PORT\"] || \"3111\", 10) || 3111;\n}\n\nasync function isEngineRunning(): Promise<boolean> {\n try {\n const res = await fetch(`http://localhost:${getRestPort()}/agentmemory/livez`, {\n signal: AbortSignal.timeout(2000),\n });\n return res.ok;\n } catch {\n return false;\n }\n}\n\nfunction findIiiConfig(): string {\n const candidates = [\n join(__dirname, \"iii-config.yaml\"),\n join(__dirname, \"..\", \"iii-config.yaml\"),\n join(process.cwd(), \"iii-config.yaml\"),\n ];\n for (const c of candidates) {\n if (existsSync(c)) return c;\n }\n return \"\";\n}\n\nfunction whichBinary(name: string): string | null {\n const cmd = process.platform === \"win32\" ? \"where\" : \"which\";\n try {\n return execFileSync(cmd, [name], { encoding: \"utf-8\" }).trim().split(\"\\n\")[0];\n } catch {\n return null;\n }\n}\n\nasync function installIii(): Promise<boolean> {\n if (process.platform === \"win32\") {\n p.log.warn(\"Automatic iii-engine install is not supported on Windows.\");\n p.log.info(\"Install manually: https://iii.dev/docs\");\n return false;\n }\n\n const curlBin = whichBinary(\"curl\");\n if (!curlBin) {\n p.log.warn(\"curl not found — cannot auto-install iii-engine.\");\n return false;\n }\n\n const shouldInstall = await p.confirm({\n message: \"iii-engine is not installed. Install it now?\",\n initialValue: true,\n });\n\n if (p.isCancel(shouldInstall) || !shouldInstall) {\n return false;\n }\n\n const s = p.spinner();\n s.start(\"Installing iii-engine...\");\n\n try {\n execSync(\"curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\", {\n stdio: [\"pipe\", \"pipe\", \"pipe\"],\n timeout: 120000,\n });\n\n const installed = whichBinary(\"iii\");\n if (installed) {\n s.stop(\"iii-engine installed successfully\");\n return true;\n }\n\n s.stop(\"Installation completed but iii not found in PATH\");\n p.log.warn(\"You may need to restart your shell or add iii to your PATH.\");\n\n const iiiPaths = [\n join(process.env[\"HOME\"] || \"\", \".local\", \"bin\", \"iii\"),\n \"/usr/local/bin/iii\",\n ];\n for (const iiiPath of iiiPaths) {\n if (existsSync(iiiPath)) {\n p.log.info(`Found iii at: ${iiiPath}`);\n process.env[\"PATH\"] = `${dirname(iiiPath)}:${process.env[\"PATH\"]}`;\n return true;\n }\n }\n\n return false;\n } catch (err) {\n s.stop(\"Failed to install iii-engine\");\n p.log.error(err instanceof Error ? err.message : String(err));\n return false;\n }\n}\n\nasync function startEngine(): Promise<boolean> {\n const configPath = findIiiConfig();\n let iiiBin = whichBinary(\"iii\");\n\n if (!iiiBin) {\n const installed = await installIii();\n if (installed) {\n iiiBin = whichBinary(\"iii\");\n }\n }\n\n if (iiiBin && configPath) {\n const s = p.spinner();\n s.start(`Starting iii-engine: ${iiiBin}`);\n const child = spawn(iiiBin, [\"--config\", configPath], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n s.stop(\"iii-engine process started\");\n return true;\n }\n\n const dockerBin = whichBinary(\"docker\");\n const dockerCompose = join(__dirname, \"..\", \"docker-compose.yml\");\n const dcExists = existsSync(dockerCompose) || existsSync(join(process.cwd(), \"docker-compose.yml\"));\n\n if (dockerBin && dcExists) {\n const composeFile = existsSync(dockerCompose) ? dockerCompose : join(process.cwd(), \"docker-compose.yml\");\n const s = p.spinner();\n s.start(\"Starting iii-engine via Docker...\");\n const child = spawn(dockerBin, [\"compose\", \"-f\", composeFile, \"up\", \"-d\"], {\n detached: true,\n stdio: \"ignore\",\n });\n child.unref();\n s.stop(\"Docker compose started\");\n return true;\n }\n\n return false;\n}\n\nasync function waitForEngine(timeoutMs: number): Promise<boolean> {\n const start = Date.now();\n while (Date.now() - start < timeoutMs) {\n if (await isEngineRunning()) return true;\n await new Promise((r) => setTimeout(r, 500));\n }\n return false;\n}\n\nasync function main() {\n p.intro(\"agentmemory\");\n\n if (skipEngine) {\n p.log.info(\"Skipping engine check (--no-engine)\");\n await import(\"./index.js\");\n return;\n }\n\n if (await isEngineRunning()) {\n p.log.success(\"iii-engine is running\");\n await import(\"./index.js\");\n return;\n }\n\n const started = await startEngine();\n if (!started) {\n p.log.error(\"Could not start iii-engine.\");\n p.note(\n [\n \"Install iii-engine (pick one):\",\n \" curl -fsSL https://install.iii.dev/iii/main/install.sh | sh\",\n \" cargo install iii-engine\",\n \"\",\n \"Or use Docker:\",\n \" docker pull iiidev/iii:latest\",\n \"\",\n \"Docs: https://iii.dev/docs\",\n \"\",\n \"Or skip with: agentmemory --no-engine\",\n ].join(\"\\n\"),\n \"Setup required\",\n );\n process.exit(1);\n }\n\n const s = p.spinner();\n s.start(\"Waiting for iii-engine to be ready...\");\n\n const ready = await waitForEngine(15000);\n if (!ready) {\n const port = getRestPort();\n s.stop(\"iii-engine did not become ready within 15s\");\n p.log.error(`Check that ports ${port}, ${port + 1}, 49134 are available.`);\n process.exit(1);\n }\n\n s.stop(\"iii-engine is ready\");\n await import(\"./index.js\");\n}\n\nmain().catch((err) => {\n p.log.error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n});\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -3739,7 +3739,7 @@ function registerAutoForgetFunction(sdk, kv) {
3739
3739
 
3740
3740
  //#endregion
3741
3741
  //#region src/version.ts
3742
- const VERSION = "0.7.0";
3742
+ const VERSION = "0.7.3";
3743
3743
 
3744
3744
  //#endregion
3745
3745
  //#region src/functions/export-import.ts
@@ -3835,7 +3835,9 @@ function registerExportImportFunction(sdk, kv) {
3835
3835
  "0.5.0",
3836
3836
  "0.6.0",
3837
3837
  "0.6.1",
3838
- "0.7.0"
3838
+ "0.7.0",
3839
+ "0.7.2",
3840
+ "0.7.3"
3839
3841
  ]).has(importData.version)) return {
3840
3842
  success: false,
3841
3843
  error: `Unsupported export version: ${importData.version}`