memorix 1.1.13 → 1.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.
- package/CHANGELOG.md +19 -0
- package/README.md +3 -2
- package/README.zh-CN.md +3 -2
- package/dist/cli/index.js +36313 -31189
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/static/app.js +50 -30
- package/dist/index.js +5348 -674
- package/dist/index.js.map +1 -1
- package/dist/maintenance-runner.d.ts +1 -1
- package/dist/maintenance-runner.js +3661 -293
- package/dist/maintenance-runner.js.map +1 -1
- package/dist/memcode-runtime/CHANGELOG.md +19 -0
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.js +5346 -672
- package/dist/sdk.js.map +1 -1
- package/docs/1.2.0-CLAIM-LEDGER.md +72 -0
- package/docs/1.2.0-CODE-STATE.md +61 -0
- package/docs/1.2.0-DEVELOPMENT-CHARTER.md +255 -0
- package/docs/1.2.0-DYNAMIC-LIFECYCLE.md +71 -0
- package/docs/1.2.0-EVALUATION-HARNESS.md +51 -0
- package/docs/1.2.0-IMPLEMENTATION-PLAN.md +554 -0
- package/docs/1.2.0-KNOWLEDGE-WORKFLOW-RESEARCH.md +205 -0
- package/docs/1.2.0-KNOWLEDGE-WORKSPACE.md +68 -0
- package/docs/1.2.0-PRODUCT-STORY.md +234 -0
- package/docs/1.2.0-PROVIDER-QUALITY.md +189 -0
- package/docs/1.2.0-WORKFLOW-INHERITANCE.md +101 -0
- package/docs/1.2.0-WORKSET-RETRIEVAL.md +80 -0
- package/docs/AGENT_OPERATOR_PLAYBOOK.md +6 -3
- package/docs/API_REFERENCE.md +25 -6
- package/docs/CONFIGURATION.md +21 -3
- package/docs/README.md +17 -2
- package/docs/dev-log/progress.txt +120 -40
- package/llms-full.txt +16 -2
- package/llms.txt +9 -4
- package/package.json +3 -2
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/src/cli/capability-map.ts +1 -0
- package/src/cli/commands/codegraph.ts +112 -9
- package/src/cli/commands/context.ts +2 -0
- package/src/cli/commands/doctor.ts +73 -4
- package/src/cli/commands/knowledge.ts +282 -0
- package/src/cli/commands/serve-http.ts +12 -1
- package/src/cli/index.ts +3 -1
- package/src/cli/tui/App.tsx +1 -1
- package/src/cli/tui/Panels.tsx +8 -8
- package/src/cli/tui/theme.ts +1 -1
- package/src/cli/tui/views/GraphView.tsx +8 -7
- package/src/cli/tui/views/KnowledgeView.tsx +9 -9
- package/src/codegraph/auto-context.ts +171 -9
- package/src/codegraph/code-state.ts +95 -0
- package/src/codegraph/context-pack.ts +82 -1
- package/src/codegraph/external-provider.ts +581 -0
- package/src/codegraph/lite-provider.ts +64 -19
- package/src/codegraph/project-context.ts +9 -1
- package/src/codegraph/store.ts +154 -6
- package/src/codegraph/types.ts +117 -0
- package/src/config/resolved-config.ts +28 -0
- package/src/config/toml-loader.ts +3 -0
- package/src/config/yaml-loader.ts +6 -0
- package/src/dashboard/server.ts +15 -1
- package/src/evaluation/workset-evaluation.ts +120 -0
- package/src/hooks/handler.ts +48 -6
- package/src/knowledge/claim-store.ts +267 -0
- package/src/knowledge/claims.ts +537 -0
- package/src/knowledge/markdown.ts +129 -0
- package/src/knowledge/types.ts +157 -0
- package/src/knowledge/wiki.ts +524 -0
- package/src/knowledge/workflow-store.ts +168 -0
- package/src/knowledge/workflow-types.ts +95 -0
- package/src/knowledge/workflows.ts +743 -0
- package/src/knowledge/workset.ts +515 -0
- package/src/knowledge/workspace-store.ts +220 -0
- package/src/knowledge/workspace-types.ts +106 -0
- package/src/knowledge/workspace.ts +220 -0
- package/src/memory/observations.ts +19 -0
- package/src/runtime/control-plane-maintenance.ts +5 -0
- package/src/runtime/isolated-maintenance.ts +5 -0
- package/src/runtime/lifecycle-status.ts +102 -0
- package/src/runtime/lifecycle.ts +107 -0
- package/src/runtime/maintenance-jobs.ts +5 -0
- package/src/runtime/project-maintenance.ts +190 -0
- package/src/server/tool-profile.ts +3 -2
- package/src/server.ts +354 -14
- package/src/store/file-lock.ts +24 -4
- package/src/store/sqlite-db.ts +307 -0
- package/src/wiki/generator.ts +4 -2
- package/src/wiki/knowledge-graph.ts +7 -4
- package/src/wiki/types.ts +16 -4
|
@@ -4,43 +4,123 @@
|
|
|
4
4
|
> older notes when they conflict.
|
|
5
5
|
|
|
6
6
|
## Current State
|
|
7
|
-
- Phase: 1.
|
|
8
|
-
- Branch: `codex/1.
|
|
9
|
-
- Last updated: 2026-07-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
##
|
|
45
|
-
-
|
|
46
|
-
|
|
7
|
+
- Phase: 1.2 release validation and publication
|
|
8
|
+
- Branch: `codex/1.2.0-multidimensional-memory`
|
|
9
|
+
- Last updated: 2026-07-18
|
|
10
|
+
- Released baseline: `memorix@1.1.13`, tag `v1.1.13`, PR #129 merged as
|
|
11
|
+
`7e8077f`.
|
|
12
|
+
- Goal: turn Memorix from a useful narrative-memory layer into a task-ready
|
|
13
|
+
working-context layer where code state, change evidence, verification,
|
|
14
|
+
source-backed project knowledge, workflows, and durable decisions are ranked
|
|
15
|
+
together.
|
|
16
|
+
|
|
17
|
+
## 1.1.13 Closeout
|
|
18
|
+
- Codex setup now stamps plugin versions and doctor distinguishes bundle,
|
|
19
|
+
marketplace, installed/enabled state, declared hooks, and hook trust.
|
|
20
|
+
- Root package publishing is isolated from internal `@memorix/*` workspaces.
|
|
21
|
+
- Full tests, build, pack inspection, isolated MCP smoke, isolated Codex smoke,
|
|
22
|
+
and Ubuntu/Windows CI all passed before release.
|
|
23
|
+
|
|
24
|
+
## 1.2 Accepted Direction
|
|
25
|
+
- The [1.2 Product Story](../1.2.0-PRODUCT-STORY.md) is the canonical
|
|
26
|
+
user-facing narrative; the Development Charter is its implementation
|
|
27
|
+
contract.
|
|
28
|
+
- The [Knowledge and Workflow Research](../1.2.0-KNOWLEDGE-WORKFLOW-RESEARCH.md)
|
|
29
|
+
establishes Knowledge Workspace and Workflow Inheritance as 1.2 core product
|
|
30
|
+
layers, with an explicit boundary against claiming the existing memory map is
|
|
31
|
+
already a semantic graph or maintained LLM Wiki.
|
|
32
|
+
- The [1.2 Implementation Plan](../1.2.0-IMPLEMENTATION-PLAN.md) is the
|
|
33
|
+
execution contract for the single complete 1.2 goal. All phases are internal
|
|
34
|
+
gates in one continuous delivery path, not separate user approval points.
|
|
35
|
+
- Use the [1.2 Development Charter](../1.2.0-DEVELOPMENT-CHARTER.md) as the
|
|
36
|
+
working product contract.
|
|
37
|
+
- Keep the current SQLite CodeGraph tables and incremental refresh as the base;
|
|
38
|
+
do not discard working 1.1 Code Memory.
|
|
39
|
+
- Add versioned Code State and evidence-quality semantics before new parsers,
|
|
40
|
+
external providers, or user-visible tool surfaces.
|
|
41
|
+
- Treat natural-language `memorix_project_context` as the product surface;
|
|
42
|
+
internal graph/provider complexity must stay behind it.
|
|
43
|
+
|
|
44
|
+
## Phase 0 Evaluation Foundation
|
|
45
|
+
- Existing UI/API projections now identify themselves honestly as a read-only
|
|
46
|
+
Memory Overview and deterministic Memory Map. They are not presented as a
|
|
47
|
+
maintained wiki or semantic graph.
|
|
48
|
+
- The Workset evaluation harness has fixture repositories for TypeScript,
|
|
49
|
+
Python, Go, docs-only, dirty worktree, deleted-symbol, and incomplete-scan
|
|
50
|
+
cases. Its seed manifest covers observations, Git facts, test evidence,
|
|
51
|
+
mini-skills, and explicit graph relations.
|
|
52
|
+
- The harness compares memory-only, current-context, and candidate Worksets
|
|
53
|
+
against source/evidence/caution requirements and variant token ceilings.
|
|
54
|
+
- The current Auto Context path is smoke-tested against real local TypeScript
|
|
55
|
+
and dirty-worktree fixtures with embeddings disabled. The candidate budget is
|
|
56
|
+
180 tokens; the current baseline budget is 320 tokens.
|
|
57
|
+
- The former memory map remains separate from the formal Claim Ledger. Phase 2
|
|
58
|
+
owns claim provenance, conflict, and supersession semantics; Phase 0 only
|
|
59
|
+
prevents the old views from being mislabeled as those capabilities.
|
|
60
|
+
|
|
61
|
+
## Phase 1 Code State
|
|
62
|
+
- Lite refresh now appends a Code State Snapshot with bounded Git revision and
|
|
63
|
+
worktree metadata, a source epoch, a prior-snapshot link, and explicit scan
|
|
64
|
+
completeness.
|
|
65
|
+
- Current files, symbols, edges, and current observation-code refs are marked
|
|
66
|
+
with the latest completed snapshot. Existing CodeGraph rows survive the
|
|
67
|
+
additive schema migration.
|
|
68
|
+
- Project Context, the CodeGraph MCP status payload, and the codegraph CLI
|
|
69
|
+
status output expose the latest snapshot. A non-Git directory reports
|
|
70
|
+
unavailable instead of clean.
|
|
71
|
+
|
|
72
|
+
## Phase 2 Claim Ledger
|
|
73
|
+
- SQLite now has additive, transactional tables for claims, evidence
|
|
74
|
+
references, and lifecycle events. Every stored claim requires at least one
|
|
75
|
+
source reference and credential values are sanitized before durable writes.
|
|
76
|
+
- Exact normalized assertions reuse their record and attach more evidence;
|
|
77
|
+
competing approved assertions remain disputed rather than being overwritten.
|
|
78
|
+
Evidence-aware supersession preserves an audit trail.
|
|
79
|
+
- Explicit memories and Git-ingested facts can derive conservative claims.
|
|
80
|
+
Hook/model output does not become approved knowledge automatically.
|
|
81
|
+
- Observation code references inherit the latest Code State Snapshot when they
|
|
82
|
+
are created. CodeGraph refresh requalifies bound claims: changed or deleted
|
|
83
|
+
symbols become unknown, and incomplete scans force review instead of false
|
|
84
|
+
certainty.
|
|
85
|
+
- Unit and integration tests cover evidence validation, redaction, conflict,
|
|
86
|
+
supersession, model-review policy, snapshot binding, changed-symbol
|
|
87
|
+
requalification, and compact task selection.
|
|
88
|
+
|
|
89
|
+
## Phase 3 Knowledge Workspace
|
|
90
|
+
- Memorix now initializes a private local Markdown workspace by default. A
|
|
91
|
+
versioned workspace requires an explicit absolute path inside the Git project
|
|
92
|
+
and refuses ignored or unsafe target directories.
|
|
93
|
+
- Approved active claims compile into Markdown proposals with frontmatter,
|
|
94
|
+
source claim ids, evidence references, snapshot context, a catalog, and an
|
|
95
|
+
append-only change log. Proposed pages are not silently published.
|
|
96
|
+
- The knowledge init, status, compile, apply, and lint commands provide the
|
|
97
|
+
operator path. Applying a proposal protects a manual page edit by default;
|
|
98
|
+
an explicit force flag is the only overwrite path and is logged.
|
|
99
|
+
- Workspace lint detects malformed frontmatter, broken links, orphan pages,
|
|
100
|
+
missing claims/evidence, superseded claims, unresolved conflicts, stale code
|
|
101
|
+
snapshots, and protected manual edits.
|
|
102
|
+
- The compiled CLI was smoke-tested in an isolated Git project through init,
|
|
103
|
+
compile, apply, and lint with a source-backed claim.
|
|
104
|
+
|
|
105
|
+
## 1.2 Delivery Complete, Release Checks In Progress
|
|
106
|
+
- Phase 4 added canonical Markdown workflows, safe adapter preview/apply, import,
|
|
107
|
+
selection, and verification receipts. Agent instruction files are render
|
|
108
|
+
targets, not the workflow source of truth.
|
|
109
|
+
- Phase 5 routes Project Context and Context Pack through one bounded Workset
|
|
110
|
+
assembler. It ranks current facts, claims, knowledge pages, workflows, and
|
|
111
|
+
cautions instead of dumping unrelated narrative memory.
|
|
112
|
+
- Phase 6 makes refresh, claim derivation/requalification, knowledge
|
|
113
|
+
compile/lint, workflow indexing, retention, and consolidation durable
|
|
114
|
+
maintenance work. Interactive MCP requests do not scan an entire corpus.
|
|
115
|
+
- Phase 7 adds an optional local semantic CodeGraph boundary. Lite remains the
|
|
116
|
+
durable local fallback; external output is used only from a healthy existing
|
|
117
|
+
`.codegraph` index, is validated, bounded, and never persisted as raw code.
|
|
118
|
+
- The advanced `memorix_knowledge` MCP action tool now exposes explicit
|
|
119
|
+
workspace/proposal/workflow management only in `team` and `full` profiles.
|
|
120
|
+
- Completed local release gates: lint, full test suite, production build,
|
|
121
|
+
package-content audit, isolated Windows npm install, stdio MCP smoke, and
|
|
122
|
+
HTTP dashboard/lifecycle smoke.
|
|
123
|
+
- Release audit also incorporated #130 before publication: the optional SQLite
|
|
124
|
+
runtime now uses the Node-26-compatible `better-sqlite3` 12.x line, with a
|
|
125
|
+
dedicated Node 26 CI smoke that opens an in-memory database.
|
|
126
|
+
- Remaining remote gates: GitHub CI, npm publish, tag, and GitHub release.
|
package/llms-full.txt
CHANGED
|
@@ -2,10 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
> Local-first shared memory layer for AI coding agents.
|
|
4
4
|
|
|
5
|
-
Memorix is a TypeScript/Node.js project that gives AI coding agents persistent, project-aware memory. It targets software development workflows, not generic chat. It works across Claude Code, Codex, Cursor, Windsurf, GitHub Copilot CLI, Gemini CLI, OpenCode, Pi, Kiro, Antigravity, Trae, and any agent that can speak MCP over stdio or HTTP. Integrations usually start with `memorix setup --agent <agent> --global`, which installs the recommended user-level package or config for that agent: plugin packages when supported, package or extension entries, MCP config, generated guidance, hooks, skills, or the bundled terminal agent.
|
|
5
|
+
Memorix is a TypeScript/Node.js project that gives AI coding agents persistent, project-aware memory. It targets software development workflows, not generic chat. It works across Claude Code, Codex, Cursor, Windsurf, GitHub Copilot CLI, Gemini CLI, OpenCode, OpenClaw, Hermes Agent, Oh-my-Pi, Pi, Kiro, Antigravity, Trae, and any agent that can speak MCP over stdio or HTTP. Integrations usually start with `memorix setup --agent <agent> --global`, which installs the recommended user-level package or config for that agent: plugin packages when supported, package or extension entries, MCP config, generated guidance, hooks, skills, or the bundled terminal agent.
|
|
6
6
|
|
|
7
7
|
If you are an AI coding agent helping a user install, operate, or troubleshoot Memorix, read `docs/AGENT_OPERATOR_PLAYBOOK.md` before taking action. It is the main reference for install, runtime selection, Git/project binding, MCP integration, hooks, and troubleshooting.
|
|
8
8
|
|
|
9
|
+
## 1.2 Multi-Dimensional Memory Model
|
|
10
|
+
|
|
11
|
+
Memorix is not a transcript dump. The normal agent path is `memorix_project_context` or `memorix context --task "..."`, which assembles a bounded task Workset: current Git/package facts, selected observations and reasoning, Code State freshness, source-backed claims, matching knowledge/workflow starts, cautions, and verification hints.
|
|
12
|
+
|
|
13
|
+
- **Observation, Reasoning, and Git Memory** preserve durable engineering facts.
|
|
14
|
+
- **Code State** records versioned local file, symbol, import, and memory-to-code links so prior evidence can be requalified when code moves.
|
|
15
|
+
- **Claim Ledger** keeps provenance, confidence, conflicts, and lifecycle state separate from prose.
|
|
16
|
+
- **Knowledge Workspace** compiles claims into reviewable Markdown proposals; it does not silently overwrite manually edited pages.
|
|
17
|
+
- **Canonical Workflows** represent project process once and render conservative agent-specific adapters only on explicit request.
|
|
18
|
+
- **Lifecycle maintenance** uses durable, resumable jobs so indexing, claim requalification, knowledge compile/lint, retention, and consolidation do not turn an interactive MCP request into a corpus-sized foreground job.
|
|
19
|
+
|
|
20
|
+
The built-in CodeGraph Lite provider is a structural local fallback, not a complete semantic graph. If a project already has a healthy local CodeGraph index, `[codegraph].external_context = "auto"` can add a small validated semantic outline. Memorix never runs `codegraph init`, `index`, or `sync`, does not transmit the repository, and does not persist raw external code output.
|
|
21
|
+
|
|
9
22
|
## Entry Points
|
|
10
23
|
|
|
11
24
|
### Setup package
|
|
@@ -348,7 +361,7 @@ Docker is for the HTTP service. The container must have access to the repositori
|
|
|
348
361
|
|
|
349
362
|
## Supported Clients
|
|
350
363
|
|
|
351
|
-
Memorix supports Claude Code, Codex, Cursor, Windsurf, GitHub Copilot CLI, Gemini CLI, OpenCode, Pi, Kiro, Antigravity, Trae, memcode, and other stdio or HTTP MCP clients.
|
|
364
|
+
Memorix supports Claude Code, Codex, Cursor, Windsurf, GitHub Copilot CLI, Gemini CLI, OpenCode, OpenClaw, Hermes Agent, Oh-my-Pi, Pi, Kiro, Antigravity, Trae, memcode, and other stdio or HTTP MCP clients.
|
|
352
365
|
|
|
353
366
|
Support depth differs by client:
|
|
354
367
|
|
|
@@ -356,6 +369,7 @@ Support depth differs by client:
|
|
|
356
369
|
- MCP is the common integration layer.
|
|
357
370
|
- Claude Code, Codex, and GitHub Copilot CLI receive local plugin packages.
|
|
358
371
|
- Pi receives a user-level package when setup runs with `--global`; Gemini CLI receives a local extension package.
|
|
372
|
+
- OpenClaw receives a compatible bundle; Hermes Agent receives a plugin package; Oh-my-Pi receives a package/extension entry.
|
|
359
373
|
- Project instructions and rules include AGENTS.md, GEMINI.md, Cursor rules, Windsurf rules, Kiro steering, and Trae rules.
|
|
360
374
|
- Hooks are generated for agents that expose usable hook events.
|
|
361
375
|
- OpenCode receives a local plugin file at `.opencode/plugins/memorix.js`, an OpenCode skill at `.opencode/skills/memorix-memory/SKILL.md`, plus `opencode.json` MCP config.
|
package/llms.txt
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Local-first shared memory layer for AI coding agents.
|
|
4
4
|
|
|
5
|
-
Memorix gives coding agents persistent, project-aware memory across sessions, IDEs, terminals, and MCP clients. It stores project knowledge once so multiple agents can retrieve it
|
|
5
|
+
Memorix gives coding agents persistent, project-aware memory across sessions, IDEs, terminals, and MCP clients. It stores project knowledge once so multiple agents can retrieve it through plugin packages, MCP, CLI, SDK, generated rules/instructions, hooks, skills, local plugins, or the bundled terminal agent. It works with Claude Code, Codex, Cursor, Windsurf, GitHub Copilot CLI, Gemini CLI, OpenCode, OpenClaw, Hermes Agent, Oh-my-Pi, Pi, Kiro, Antigravity, Trae, and other MCP-capable agents.
|
|
6
6
|
|
|
7
7
|
## Entry Points
|
|
8
8
|
|
|
@@ -10,20 +10,25 @@ Memorix gives coding agents persistent, project-aware memory across sessions, ID
|
|
|
10
10
|
- `memorix setup --list` lists supported agent entry points.
|
|
11
11
|
- `memorix serve` starts the manual stdio MCP server for IDEs and agents.
|
|
12
12
|
- `memorix background start` starts the HTTP MCP service and dashboard.
|
|
13
|
-
- `memorix memory`, `reasoning`, `session`, `team`, `task`, `handoff`, `poll`, `receipt`, `sync`, `ingest`, and `orchestrate` expose the CLI command set.
|
|
13
|
+
- `memorix memory`, `codegraph`, `knowledge`, `reasoning`, `session`, `team`, `task`, `handoff`, `poll`, `receipt`, `sync`, `ingest`, and `orchestrate` expose the CLI command set.
|
|
14
14
|
- `memorix integrate --agent <agent>` and `memorix hooks install --agent <agent>` are manual/fallback generation commands.
|
|
15
15
|
- `memorix` and `memcode` open memcode, the bundled terminal agent that uses the same project memory pool.
|
|
16
16
|
- `memorix dashboard` opens the local read-mostly dashboard.
|
|
17
17
|
|
|
18
18
|
## Memory Model
|
|
19
19
|
|
|
20
|
-
Memorix combines
|
|
20
|
+
Memorix combines durable memory with a bounded task Workset:
|
|
21
21
|
|
|
22
22
|
- **Observation Memory**: facts, gotchas, fixes, implementation notes, what changed
|
|
23
23
|
- **Reasoning Memory**: why decisions were made, alternatives, constraints, risks
|
|
24
24
|
- **Git Memory**: commit-derived engineering facts with source provenance
|
|
25
|
+
- **Code State**: versioned local file/symbol/import facts and freshness links that keep memory tied to the current checkout
|
|
26
|
+
- **Claim Ledger and Knowledge Workspace**: source-backed claims compiled into reviewable Markdown proposals, never silent overwrites
|
|
27
|
+
- **Canonical Workflows**: project workflows with safe per-agent adapters and recorded verification outcomes
|
|
25
28
|
|
|
26
|
-
Search is project-scoped by default. Use global scope only when cross-project recall is intentional.
|
|
29
|
+
For non-trivial coding work, agents normally call `memorix_project_context` (or `memorix context --task "...")`. It selects a small task Workset with current facts, relevant evidence, start files, cautions, and verification hints instead of dumping all old text memory. Search is project-scoped by default. Use global scope only when cross-project recall is intentional.
|
|
30
|
+
|
|
31
|
+
The built-in CodeGraph Lite index is structural and intentionally not presented as a complete semantic graph. A project that already has a healthy local CodeGraph index can contribute a small validated semantic outline through `[codegraph].external_context = "auto"`; Memorix never initializes, syncs, exports, or remotely uploads that index.
|
|
27
32
|
|
|
28
33
|
## memcode
|
|
29
34
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memorix",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Local-first shared memory layer for AI coding agents across MCP clients, Git history, reasoning context, and project sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"test:watch": "vitest",
|
|
62
62
|
"test:llm-live": "MEMORIX_RUN_LIVE_LLM_TESTS=1 vitest run tests/integration/formation-llm-quality.test.ts",
|
|
63
63
|
"test:e2e": "vitest run tests/e2e/",
|
|
64
|
+
"benchmark:codegraph": "node scripts/benchmark-codegraph-provider.cjs",
|
|
64
65
|
"lint": "tsc --noEmit",
|
|
65
66
|
"prepublishOnly": "npm run build && npm test"
|
|
66
67
|
},
|
|
@@ -137,7 +138,7 @@
|
|
|
137
138
|
},
|
|
138
139
|
"optionalDependencies": {
|
|
139
140
|
"@huggingface/transformers": "^3.0.0",
|
|
140
|
-
"better-sqlite3": "^11.
|
|
141
|
+
"better-sqlite3": "^12.11.1"
|
|
141
142
|
},
|
|
142
143
|
"overrides": {
|
|
143
144
|
"tar": "^7.5.16",
|
|
@@ -6,6 +6,7 @@ export const CLI_NATIVE_PARITY: Record<string, string> = Object.freeze({
|
|
|
6
6
|
memorix_project_context: 'memorix context',
|
|
7
7
|
memorix_context_pack: 'memorix codegraph context-pack',
|
|
8
8
|
memorix_codegraph_status: 'memorix codegraph status',
|
|
9
|
+
memorix_knowledge: 'memorix knowledge init|status|compile|lint|apply|workflow',
|
|
9
10
|
memorix_resolve: 'memorix memory resolve',
|
|
10
11
|
memorix_timeline: 'memorix memory timeline',
|
|
11
12
|
memorix_suggest_topic_key: 'memorix memory suggest-topic-key',
|
|
@@ -1,20 +1,54 @@
|
|
|
1
1
|
import { defineCommand } from 'citty';
|
|
2
2
|
import { CodeGraphStore } from '../../codegraph/store.js';
|
|
3
3
|
import { refreshProjectLite } from '../../codegraph/lite-provider.js';
|
|
4
|
-
import { assembleContextPackForTask, buildContextPackPrompt } from '../../codegraph/context-pack.js';
|
|
4
|
+
import { assembleContextPackForTask, attachTaskWorkset, buildContextPackPrompt } from '../../codegraph/context-pack.js';
|
|
5
5
|
import { backfillMissingObservationCodeRefs } from '../../codegraph/binder.js';
|
|
6
|
+
import { collectCurrentProjectFacts } from '../../codegraph/current-facts.js';
|
|
7
|
+
import { resolveTaskLens } from '../../codegraph/task-lens.js';
|
|
8
|
+
import { getExternalCodeGraphContext, inspectExternalCodeGraph } from '../../codegraph/external-provider.js';
|
|
9
|
+
import type { CodeGraphProviderQuality } from '../../codegraph/types.js';
|
|
6
10
|
import { getResolvedConfig } from '../../config/resolved-config.js';
|
|
7
11
|
import { getAllObservations } from '../../memory/observations.js';
|
|
8
12
|
import { emitError, emitResult, getCliProjectContext, parsePositiveInt } from './operator-shared.js';
|
|
9
13
|
|
|
10
|
-
function
|
|
14
|
+
function formatSnapshotStatus(status: ReturnType<CodeGraphStore['status']>): string[] {
|
|
15
|
+
const snapshot = status.latestSnapshot;
|
|
16
|
+
if (!snapshot) return ['- Code state: no completed snapshot yet'];
|
|
17
|
+
const revision = snapshot.baseRevision ? snapshot.baseRevision.slice(0, 12) : 'Git unavailable';
|
|
18
|
+
const completeness = snapshot.completeness;
|
|
19
|
+
const scanState = completeness.skippedOversizedFiles > 0
|
|
20
|
+
|| (completeness.unreadableFiles ?? 0) > 0
|
|
21
|
+
|| completeness.removalScanDeferred
|
|
22
|
+
? 'incomplete'
|
|
23
|
+
: 'complete';
|
|
11
24
|
return [
|
|
25
|
+
'- Code state: ' + revision
|
|
26
|
+
+ ', ' + snapshot.worktreeState + ' worktree'
|
|
27
|
+
+ ', ' + snapshot.changedPathCount + ' changed path(s)'
|
|
28
|
+
+ ', epoch ' + snapshot.sourceEpoch,
|
|
29
|
+
'- Scan completeness: ' + scanState
|
|
30
|
+
+ ' (' + completeness.scannedFiles + '/' + completeness.maxFiles + ' paths'
|
|
31
|
+
+ ', ' + completeness.skippedOversizedFiles + ' oversized skipped'
|
|
32
|
+
+ ', ' + (completeness.unreadableFiles ?? 0) + ' unreadable)',
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function formatStatus(status: ReturnType<CodeGraphStore['status']>, quality?: CodeGraphProviderQuality): string {
|
|
37
|
+
return [
|
|
38
|
+
...formatSnapshotStatus(status),
|
|
12
39
|
`CodeGraph Memory: ${status.provider}`,
|
|
13
40
|
`- Files: ${status.files}`,
|
|
14
41
|
`- Symbols: ${status.symbols}`,
|
|
15
42
|
`- Edges: ${status.edges}`,
|
|
16
43
|
`- Memory refs: ${status.refs}`,
|
|
17
44
|
status.indexedAt ? `- Indexed at: ${status.indexedAt}` : '- Indexed at: never',
|
|
45
|
+
...(quality
|
|
46
|
+
? [
|
|
47
|
+
`- Persistent provider: ${status.provider} (heuristic local index)`,
|
|
48
|
+
`- External semantic CodeGraph: ${quality.external.state}`
|
|
49
|
+
+ (quality.external.reason ? ` (${quality.external.reason})` : ''),
|
|
50
|
+
]
|
|
51
|
+
: []),
|
|
18
52
|
].join('\n');
|
|
19
53
|
}
|
|
20
54
|
|
|
@@ -29,6 +63,19 @@ function formatUsageHint(): string {
|
|
|
29
63
|
].join('\n');
|
|
30
64
|
}
|
|
31
65
|
|
|
66
|
+
function compactFacts(project: { rootPath: string }): { facts: string[]; dirty: boolean } {
|
|
67
|
+
const current = collectCurrentProjectFacts({ project, now: new Date() });
|
|
68
|
+
const facts: string[] = [];
|
|
69
|
+
if (current.packageVersion) facts.push('Package version: ' + current.packageVersion);
|
|
70
|
+
if (current.latestChangelog) {
|
|
71
|
+
facts.push('Latest changelog: ' + current.latestChangelog.version
|
|
72
|
+
+ (current.latestChangelog.date ? ' (' + current.latestChangelog.date + ')' : ''));
|
|
73
|
+
}
|
|
74
|
+
facts.push('Git: ' + (current.git.branch ? 'branch ' + current.git.branch + ', ' : '')
|
|
75
|
+
+ (current.git.dirty ? 'dirty worktree' : 'clean worktree'));
|
|
76
|
+
return { facts, dirty: current.git.dirty };
|
|
77
|
+
}
|
|
78
|
+
|
|
32
79
|
export default defineCommand({
|
|
33
80
|
meta: {
|
|
34
81
|
name: 'codegraph',
|
|
@@ -56,10 +103,16 @@ export default defineCommand({
|
|
|
56
103
|
switch (action) {
|
|
57
104
|
case 'status': {
|
|
58
105
|
const status = store.status(project.id);
|
|
106
|
+
const providerQuality = await inspectExternalCodeGraph({
|
|
107
|
+
projectRoot: project.rootPath,
|
|
108
|
+
mode: codegraphConfig.externalContext,
|
|
109
|
+
command: codegraphConfig.externalCommand,
|
|
110
|
+
timeoutMs: codegraphConfig.externalTimeoutMs,
|
|
111
|
+
});
|
|
59
112
|
const text = explicitAction || asJson
|
|
60
|
-
? formatStatus(status)
|
|
61
|
-
: `${formatStatus(status)}\n\n${formatUsageHint()}`;
|
|
62
|
-
emitResult({ project, status }, text, asJson);
|
|
113
|
+
? formatStatus(status, providerQuality.quality)
|
|
114
|
+
: `${formatStatus(status, providerQuality.quality)}\n\n${formatUsageHint()}`;
|
|
115
|
+
emitResult({ project, status, providerQuality: providerQuality.quality }, text, asJson);
|
|
63
116
|
return;
|
|
64
117
|
}
|
|
65
118
|
|
|
@@ -73,12 +126,25 @@ export default defineCommand({
|
|
|
73
126
|
const activeObservations = getAllObservations()
|
|
74
127
|
.filter(obs => obs.projectId === project.id && (obs.status ?? 'active') === 'active');
|
|
75
128
|
const backfill = await backfillMissingObservationCodeRefs(store, activeObservations);
|
|
129
|
+
const { enqueueClaimRequalification } = await import('../../runtime/lifecycle.js');
|
|
130
|
+
enqueueClaimRequalification({
|
|
131
|
+
dataDir,
|
|
132
|
+
projectId: project.id,
|
|
133
|
+
source: 'manual-codegraph-refresh',
|
|
134
|
+
snapshotId: refresh.snapshot.id,
|
|
135
|
+
});
|
|
76
136
|
const status = store.status(project.id);
|
|
137
|
+
const providerQuality = await inspectExternalCodeGraph({
|
|
138
|
+
projectRoot: project.rootPath,
|
|
139
|
+
mode: codegraphConfig.externalContext,
|
|
140
|
+
command: codegraphConfig.externalCommand,
|
|
141
|
+
timeoutMs: codegraphConfig.externalTimeoutMs,
|
|
142
|
+
});
|
|
77
143
|
emitResult(
|
|
78
|
-
{ project, status, refresh, backfill },
|
|
144
|
+
{ project, status, providerQuality: providerQuality.quality, refresh, backfill },
|
|
79
145
|
[
|
|
80
146
|
'CodeGraph Memory refreshed.',
|
|
81
|
-
formatStatus(status),
|
|
147
|
+
formatStatus(status, providerQuality.quality),
|
|
82
148
|
`- Files: ${refresh.changedFiles} changed, ${refresh.unchangedFiles} unchanged, ${refresh.removedFiles} removed`,
|
|
83
149
|
`- Backfilled memories: ${backfill.observationsBackfilled}`,
|
|
84
150
|
`- Backfilled refs: ${backfill.refsBackfilled}`,
|
|
@@ -98,7 +164,7 @@ export default defineCommand({
|
|
|
98
164
|
const observations = getAllObservations()
|
|
99
165
|
.filter(obs => obs.projectId === project.id && (obs.status ?? 'active') === 'active')
|
|
100
166
|
.reverse();
|
|
101
|
-
const
|
|
167
|
+
const basePack = assembleContextPackForTask({
|
|
102
168
|
store,
|
|
103
169
|
projectId: project.id,
|
|
104
170
|
task,
|
|
@@ -106,7 +172,44 @@ export default defineCommand({
|
|
|
106
172
|
limit,
|
|
107
173
|
exclude,
|
|
108
174
|
});
|
|
109
|
-
|
|
175
|
+
const status = store.status(project.id);
|
|
176
|
+
const facts = compactFacts(project);
|
|
177
|
+
const snapshot = status.latestSnapshot;
|
|
178
|
+
const external = await getExternalCodeGraphContext({
|
|
179
|
+
projectRoot: project.rootPath,
|
|
180
|
+
task,
|
|
181
|
+
exclude,
|
|
182
|
+
mode: codegraphConfig.externalContext,
|
|
183
|
+
command: codegraphConfig.externalCommand,
|
|
184
|
+
timeoutMs: codegraphConfig.externalTimeoutMs,
|
|
185
|
+
});
|
|
186
|
+
const pack = await attachTaskWorkset({
|
|
187
|
+
pack: basePack,
|
|
188
|
+
projectId: project.id,
|
|
189
|
+
dataDir,
|
|
190
|
+
lens: resolveTaskLens(task).id,
|
|
191
|
+
worktreeDirty: facts.dirty,
|
|
192
|
+
currentFacts: facts.facts,
|
|
193
|
+
codeState: formatSnapshotStatus(status).join(' '),
|
|
194
|
+
...(snapshot
|
|
195
|
+
? {
|
|
196
|
+
snapshot: {
|
|
197
|
+
id: snapshot.id,
|
|
198
|
+
sourceEpoch: snapshot.sourceEpoch,
|
|
199
|
+
worktreeState: snapshot.worktreeState,
|
|
200
|
+
incomplete: snapshot.completeness.skippedOversizedFiles > 0
|
|
201
|
+
|| (snapshot.completeness.unreadableFiles ?? 0) > 0
|
|
202
|
+
|| snapshot.completeness.removalScanDeferred,
|
|
203
|
+
},
|
|
204
|
+
}
|
|
205
|
+
: {}),
|
|
206
|
+
...(external.outline ? { semanticCode: external.outline } : {}),
|
|
207
|
+
providerQuality: external.quality,
|
|
208
|
+
...(external.caution
|
|
209
|
+
? { runtimeCautions: [{ kind: 'external-codegraph-fallback' as const, message: external.caution }] }
|
|
210
|
+
: {}),
|
|
211
|
+
});
|
|
212
|
+
emitResult({ project, pack, providerQuality: external.quality }, buildContextPackPrompt(pack), asJson);
|
|
110
213
|
return;
|
|
111
214
|
}
|
|
112
215
|
|
|
@@ -45,6 +45,8 @@ export default defineCommand({
|
|
|
45
45
|
currentFacts: context.currentFacts,
|
|
46
46
|
overview: context.overview,
|
|
47
47
|
refresh: context.refresh,
|
|
48
|
+
providerQuality: context.providerQuality,
|
|
49
|
+
workset: context.workset,
|
|
48
50
|
...(context.task ? { task: context.task } : {}),
|
|
49
51
|
},
|
|
50
52
|
formatAutoProjectContextPrompt(context),
|
|
@@ -319,9 +319,11 @@ export default defineCommand({
|
|
|
319
319
|
const { CodeGraphStore } = await import('../../codegraph/store.js');
|
|
320
320
|
const { buildProjectContextOverview } = await import('../../codegraph/project-context.js');
|
|
321
321
|
const { getResolvedConfig } = await import('../../config/resolved-config.js');
|
|
322
|
+
const { inspectExternalCodeGraph } = await import('../../codegraph/external-provider.js');
|
|
322
323
|
const codeStore = new CodeGraphStore();
|
|
323
324
|
await codeStore.init(dataDir);
|
|
324
|
-
const
|
|
325
|
+
const codegraphConfig = getResolvedConfig({ projectRoot: projectRoot || process.cwd() }).codegraph;
|
|
326
|
+
const exclude = codegraphConfig.excludePatterns;
|
|
325
327
|
const overview = buildProjectContextOverview({
|
|
326
328
|
project: {
|
|
327
329
|
id: projectId,
|
|
@@ -335,6 +337,12 @@ export default defineCommand({
|
|
|
335
337
|
const languageText = overview.code.languages.length > 0
|
|
336
338
|
? overview.code.languages.map((item: any) => `${item.language} ${item.files}`).join(', ')
|
|
337
339
|
: 'none indexed yet';
|
|
340
|
+
const providerQuality = await inspectExternalCodeGraph({
|
|
341
|
+
projectRoot: projectRoot || process.cwd(),
|
|
342
|
+
mode: codegraphConfig.externalContext,
|
|
343
|
+
command: codegraphConfig.externalCommand,
|
|
344
|
+
timeoutMs: codegraphConfig.externalTimeoutMs,
|
|
345
|
+
});
|
|
338
346
|
|
|
339
347
|
if (overview.code.files > 0) {
|
|
340
348
|
lines.push(ok(`Code memory: ${overview.code.files} files, ${overview.code.symbols} symbols, ${overview.code.refs} memory links`));
|
|
@@ -344,6 +352,15 @@ export default defineCommand({
|
|
|
344
352
|
tips.push('Run `memorix codegraph refresh` once to seed project context.');
|
|
345
353
|
}
|
|
346
354
|
|
|
355
|
+
lines.push(info(
|
|
356
|
+
`Code provider: Lite durable index; external semantic graph ${providerQuality.health.state}`,
|
|
357
|
+
));
|
|
358
|
+
if (providerQuality.health.state !== 'ready'
|
|
359
|
+
&& providerQuality.health.state !== 'not-detected'
|
|
360
|
+
&& providerQuality.health.state !== 'disabled') {
|
|
361
|
+
lines.push(warn(`External CodeGraph: ${providerQuality.health.reason ?? providerQuality.health.state}`));
|
|
362
|
+
}
|
|
363
|
+
|
|
347
364
|
if (overview.freshness.stale > 0 || overview.freshness.suspect > 0) {
|
|
348
365
|
lines.push(warn(`Freshness: ${overview.freshness.current} current, ${overview.freshness.suspect} suspect, ${overview.freshness.stale} stale`));
|
|
349
366
|
} else {
|
|
@@ -362,6 +379,7 @@ export default defineCommand({
|
|
|
362
379
|
refs: overview.code.refs,
|
|
363
380
|
languages: overview.code.languages,
|
|
364
381
|
freshness: overview.freshness,
|
|
382
|
+
providerQuality: providerQuality.quality,
|
|
365
383
|
...(overview.code.indexedAt ? { indexedAt: overview.code.indexedAt } : {}),
|
|
366
384
|
};
|
|
367
385
|
} catch (e) {
|
|
@@ -373,7 +391,58 @@ export default defineCommand({
|
|
|
373
391
|
lines.push(info('Project context unavailable without a detected project.'));
|
|
374
392
|
}
|
|
375
393
|
|
|
376
|
-
// ── 6.
|
|
394
|
+
// ── 6. Knowledge Lifecycle ──────────────────────────────────
|
|
395
|
+
lines.push('');
|
|
396
|
+
lines.push('┌─ Knowledge Lifecycle ─────────────────────────────');
|
|
397
|
+
|
|
398
|
+
if (projectId && dataDir) {
|
|
399
|
+
try {
|
|
400
|
+
const { collectLifecycleDiagnostics } = await import('../../runtime/lifecycle-status.js');
|
|
401
|
+
const lifecycle = await collectLifecycleDiagnostics({ dataDir, projectId });
|
|
402
|
+
report.lifecycle = lifecycle;
|
|
403
|
+
|
|
404
|
+
const queued = lifecycle.maintenance.summary.pending + lifecycle.maintenance.summary.retrying;
|
|
405
|
+
const running = lifecycle.maintenance.summary.running;
|
|
406
|
+
if (lifecycle.maintenance.summary.failed > 0) {
|
|
407
|
+
lines.push(warn(`Maintenance: ${lifecycle.maintenance.summary.failed} failed job(s)`));
|
|
408
|
+
for (const job of lifecycle.maintenance.failedJobs) {
|
|
409
|
+
lines.push(info(`Failed: ${job.kind} after ${job.attempts} attempt(s)`));
|
|
410
|
+
}
|
|
411
|
+
issues.push('Knowledge maintenance has failed work. Run `memorix doctor --json` to inspect the affected job kind.');
|
|
412
|
+
} else if (queued > 0 || running > 0) {
|
|
413
|
+
lines.push(info(`Maintenance: ${queued} queued, ${running} running`));
|
|
414
|
+
} else {
|
|
415
|
+
lines.push(ok('Maintenance: idle'));
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
lines.push(info(
|
|
419
|
+
`Claims: ${lifecycle.claims.active} active, ${lifecycle.claims.needsReview} need review, ${lifecycle.claims.unknown} unknown`,
|
|
420
|
+
));
|
|
421
|
+
if (lifecycle.claims.conflicts > 0) {
|
|
422
|
+
lines.push(warn(`Claim conflicts: ${lifecycle.claims.conflicts}`));
|
|
423
|
+
issues.push('Source-backed claims conflict and need review before they guide work.');
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
if (lifecycle.workspaces.length === 0) {
|
|
427
|
+
lines.push(info('Knowledge workspace: not initialized'));
|
|
428
|
+
} else {
|
|
429
|
+
for (const workspace of lifecycle.workspaces) {
|
|
430
|
+
lines.push(info(
|
|
431
|
+
`${workspace.mode} workspace: ${workspace.pages} pages, ${workspace.pendingProposals} pending proposal(s), ${workspace.status}`,
|
|
432
|
+
));
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
lines.push(info(`Workflows: ${lifecycle.workflows.active}/${lifecycle.workflows.total} active, ${lifecycle.workflows.failedRuns} failed run(s)`));
|
|
436
|
+
} catch (e) {
|
|
437
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
438
|
+
lines.push(warn(`Knowledge lifecycle unavailable: ${message}`));
|
|
439
|
+
report.lifecycle = { error: message };
|
|
440
|
+
}
|
|
441
|
+
} else {
|
|
442
|
+
lines.push(info('Knowledge lifecycle unavailable without a detected project.'));
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// ── 7. Conflict Check ────────────────────────────────────────
|
|
377
446
|
lines.push('');
|
|
378
447
|
lines.push('┌─ Conflict Check ──────────────────────────────────');
|
|
379
448
|
|
|
@@ -403,7 +472,7 @@ export default defineCommand({
|
|
|
403
472
|
}
|
|
404
473
|
report.conflicts = { found: conflictsFound };
|
|
405
474
|
|
|
406
|
-
// ──
|
|
475
|
+
// ── 8. LLM Status ────────────────────────────────────────────
|
|
407
476
|
lines.push('');
|
|
408
477
|
lines.push('┌─ LLM Enhanced Mode ───────────────────────────────');
|
|
409
478
|
|
|
@@ -427,7 +496,7 @@ export default defineCommand({
|
|
|
427
496
|
report.llm = { enabled: false };
|
|
428
497
|
}
|
|
429
498
|
|
|
430
|
-
// ──
|
|
499
|
+
// ── 9. Auto-Update Status ──────────────────────────────────
|
|
431
500
|
lines.push('');
|
|
432
501
|
lines.push('┌─ Auto-Update ─────────────────────────────────────');
|
|
433
502
|
|