cogni-code
v3.5.1
Published
Persistent, self-evolving memory for AI agents. Gives Claude Code, Codex CLI, OpenCode, and pi a knowledge graph that grows from conversations.
Downloads
699
Maintainers
Readme
cogni-code
Persistent, self-evolving memory for AI agents. Gives Claude Code, Codex CLI, OpenCode, and pi a knowledge graph that grows from conversations.
🌐 Docs & landing site: cognicode.app
o----o----o
/ \ / \ \
o---oo---o----o
\ / \ | /
o----o-o--o
\ /
o
C O G N I - C O D EQuick Start
npm install -g cogni-code
cogni-code install # auto-detects your harness(es)Permission denied (EACCES)? Locked-down containers may block global installs. Use a local install instead:
npm install cogni-code && npx cogni-code install
Or specify a harness:
cogni-code install --codex
cogni-code install --claude
cogni-code install --opencodeUpdates are automatic — npm update -g cogni-code updates the code and all hooks use the new version immediately (hooks call the cogni-code CLI, not absolute file paths).
To also set up the Docker daemon for background pipeline processing:
cogni-code install --docker # auto-detects worker provider
cogni-code install --docker --worker codex # specify worker explicitlyNo Docker? Direct API Mode
If your environment has no Docker or Podman (e.g. a NanoClaw container, sandbox, or CI runner), the api worker runs the full pipeline (scribe, auditor, librarian, dreamer) via direct HTTP — no CLI agent binary, no subprocess:
cogni-code install --docker --worker apiThe api worker respects the standard Anthropic env-var surface, so it routes through whatever credential infrastructure your agent already uses:
| Env var | Auth method | Use case |
|---|---|---|
| ANTHROPIC_API_KEY | x-api-key header | Direct API key (bills per-token) |
| ANTHROPIC_AUTH_TOKEN + ANTHROPIC_BASE_URL | Authorization: Bearer | Credential proxy (e.g. OneCLI Agent Vault in NanoClaw) — routes to your subscription, no API billing |
It auto-activates when credentials are present and no CLI harness is on PATH. Start the daemon directly without Docker:
node "$(npm root -g)/cogni-code/dist/graph-memory/pipeline/daemon.js"What It Does
- remembers preferences, decisions, project context, and recurring patterns across sessions
- exposes a
graph_memorytool for search, recall, remember, inspection, and maintenance - loads compact context into new sessions via mental model injection, with the older full-context path kept as a fallback
- supports Claude Code (MCP + hooks), Codex CLI (MCP + hooks), OpenCode (native plugin), and pi (extension)
- runs a background pipeline that extracts observations, compresses mental models, and generates creative associations
- keeps git history for memory changes so you can inspect or revert them
From Source (Git Clone)
If you cloned the repo, install from graph-memory-plugin/:
cd graph-memory-plugin
npm install && npm run build
./bin/install.sh # Claude Code
./bin/install-codex.sh # Codex CLI
./bin/install-opencode.sh # OpenCodeArchitecture
Unified Architecture
The system is a single unified architecture:
- Knowledge graph (
nodes/), MAP, WORKING, DREAMS, pinned nodes, decay, context regeneration - Mental models (
mind/), observations, session logs, project lenses - Single canonical node store:
nodes/— the oldergraph/directory has been archived toarchive/v3-graph-backup/
The durable graph is stored once in nodes/; the mental-model layers compress that graph into low-token session context.
Layers:
| Layer | Storage | Purpose |
|-------|---------|---------|
| Layer 1: Global Mind | mind/model.json, mind/whisper.txt | Cognitive style, preferences, guardrails, emotional profile |
| Layer 2: Project Lenses | lenses/{project}/ | Per-project tech stack, conventions, active work, open threads |
| Layer 3: Session Logs | sessions/{project}.jsonl | Per-session records of shipped work, decisions, next-session hints |
| Layer 4: Graph | nodes/ | Durable knowledge nodes with edges, confidence, and decay |
Pipeline
Session → Scribe → Auditor → Librarian → Dreamer
↓ ↓
recommendations graph updates
context regenerationAll four pipeline prompts were improved to capture "true memory" — evolving opinions, frustrations, contradictions, half-formed ideas — not just hard facts. The auditor now prioritizes stale/contradictory node detection, and the librarian follows a prune-over-preserve philosophy.
Session Start
Session-start uses a single injection path:
mental-model (model.json direct, unconditional) → MAP (per-project) → PINNED (project-gated) → WORKING
Pipeline Stages
The scribe → auditor → librarian → dreamer pipeline is the proven core. Observer and compressor also run by default (observer produces observations/session logs/node upserts on scribe and buffer thresholds; compressor folds observations into mental models afterward). The separate dreamer-v3 / dreamer-models variant is present in code but not wired. All stages read and write the same durable node files in nodes/, while mind/, lenses/, and sessions/ hold compressed context layers. LLM-backed stages retry on the configured fallback worker if the primary provider fails or hits a usage limit.
Notion Sync
Two-way sync between graph-memory and a Notion workspace for human-readable access. Five steward agents manage scoped areas:
| Steward | Scope | |---------|-------| | Knowledge | Knowledge nodes → Notion wiki pages | | Project | Project lenses → Notion project pages | | Tasks | Working state → Notion task database | | Enrichment | Dreams, briefs → Notion databases | | Workspace | Workspace manifest, structure |
Outbound sync uses a diff + plan + execute cycle, chunked at 100 items per batch. The daemon auto-enqueues the next batch after each completed cycle.
Inbound sync detects human edits in Notion via webhooks and creates observations/deltas (not direct node mutations). Ngrok tunnels webhook traffic to the daemon on port 3100.
Three-way merge — when both sides change, human intent wins with agent info preserved as callouts.
Commands: /notion-setup, /notion-sync, /notion-consolidate
Harness Adapters
The core is harness-agnostic via an adapter system:
adapters/
types.ts — HarnessAdapter interface, HarnessType, AdapterConfig
claude-code.ts — Claude Code (hooks + MCP)
opencode.ts — OpenCode (plugin events + MCP)
pi.ts — Pi (plugin events + MCP)
codex.ts — Codex (hooks + MCP)
factory.ts — Adapter instantiation
shared.ts — Shared adapter logicEach adapter declares capabilities and handles platform-specific session lifecycle.
Install
Claude Code
From the repository root:
cd graph-memory-plugin
./bin/install.shThen start Claude Code and run:
/memory-onboardCodex CLI
From the repository root:
cd graph-memory-plugin
./bin/install-codex.shThen start Codex CLI and run /hooks to review and trust the graph-memory hooks. Codex supports lifecycle hooks (SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PreCompact, Stop) with the same stdin/stdout contract as Claude Code.
OpenCode
From the repository root:
cd graph-memory-plugin
./bin/install-opencode.shThen start OpenCode and run:
/memory-onboardWindows
All supported installers are bash scripts — run them from Git Bash (installed with Git for Windows), not PowerShell or cmd.exe. PowerShell/cmd can't interpret the #!/usr/bin/env bash shebang.
Two things to have in place first:
- Node ≥ 18 must resolve first on
PATH. If you have an older bundled Node (e.g. from a system-wide installer) ahead of a newer one inPATH, the build step (tsc) will fail with syntax errors on modern JS. Check withnode --versionfrom Git Bash before installing. cygpathmust be onPATH. It ships with Git for Windows and is used to convert paths into a form Windows-native processes (Claude Code, OpenCode, Codex) can spawn directly.
What the installers do differently on Windows:
- The plugin directory is linked into
~/.claude/plugins/with a directory junction (mklink /J, unprivileged) instead of a symlink — real symlinks need admin rights or Developer Mode. - Slash commands are copied instead of symlinked, and kept in sync by content comparison — re-run the installer after pulling repo changes to refresh them.
- Hook and MCP server commands invoke
node.exedirectly instead of the.shwrapper scripts. This isn't just a missing-file-association issue:bash.exe, when a non-Git-Bash process (Claude Code, OpenCode, Codex) spawns it directly rather than through the Git Bash launcher, doesn't have Git'susr/binon itsPATH— it can't even rundirname, so the.shwrappers fail before they reachnode. The installers resolvenode's absolute path while running inside a properly-initialized Git Bash and bake it directly into~/.claude/settings.json/~/.claude.json/config.toml, bypassing bash entirely for these paths. Re-running an installer replaces any stale.sh-based entries a previous install left behind (e.g. from before this fix) rather than leaving duplicates.
These are handled automatically; you shouldn't need to do anything beyond running the installer from Git Bash. If a step fails, the script's error message will say which prerequisite is missing (cygpath, bash, or node).
Detailed clone-to-first-run instructions are in ../docs/setup-from-clone.md.
Seeding the Mental Model from Existing Nodes (Legacy)
The migration script src/graph-memory/scripts/migrate-mental-model.ts was used during the initial transition to populate the mental model structure from existing nodes. It is now legacy — new installations build the mental model organically through the pipeline. The script does not remove or alter existing node data.
Runtime Model
Manual mode
- tool and graph storage only
- no daemon container
- useful for lightweight local testing
- works with Claude Code, Codex CLI, OpenCode, and pi
Docker daemon mode
- recommended for normal use
- host agent stays on the host
- graph root stays on the host filesystem
- daemon and bounded workers run in Docker against the mounted graph root
- also works with Podman as a drop-in replacement —
runtime-env.shdetects whichever ofdocker/podmanis onPATHand, if it's podman, defines adockershell function that forwards to it, so everydocker-*.shscript works unmodified.docker-bootstrap.shanddocker-start.shadditionally start the podman machine if it isn't already running (podman doesn't auto-start its VM the way Docker Desktop does).
Useful helpers (harness-agnostic):
bin/docker-bootstrap.shbin/docker-doctor.shbin/docker-auth-check.sh
Worker-specific helpers:
bin/docker-codex-import-host-auth.sh/bin/docker-codex-login.sh/bin/docker-codex-login-api-key.shbin/docker-pi-import-host-auth.sh/bin/docker-pi-auth-status.shbin/docker-opencode-import-host-auth.sh/bin/docker-opencode-auth-status.sh
General:
bin/docker-stop.sh
Ngrok (Notion Webhooks)
If you are using Notion sync with webhooks, start an ngrok tunnel pointing at the daemon port:
ngrok http 3100Free-tier ngrok URLs change on every restart — update the webhook URL in your Notion integration settings after restarting. See docs/notion-webhook-troubleshooting.md for full details.
Commands
Installed slash commands (available in both Claude Code and OpenCode):
| Command | Description |
|---------|-------------|
| /memory-onboard | Initialize storage, choose runtime mode, and seed first memory nodes |
| /memory-status | Report graph health, runtime state, counts, and warnings |
| /memory-search <query> | Search the graph index |
| /memory-morning-kickoff | Turn the latest brief into a focused daily kickoff |
| /memory-connect-inputs | Configure host-side external inputs for briefs and context enrichment |
| /memory-input-refresh | Refresh configured external inputs and ingest new data |
| /memory-switch-harness | Switch the background pipeline worker between codex, claude, pi, opencode, and api |
| /memory-wire-project | Wire (or refresh) the graph-memory section in this project's CLAUDE.md |
| /notion-setup | Configure Notion sync for a parent page or database |
| /notion-sync | Sync graph-memory content to Notion |
| /notion-consolidate | Merge batched wiki pages into category pages, apply reviewed Notion edits back into memory |
| /refresh-skill | Manually refresh a skillforged skill whose source node has drifted |
| /skill-install | Install skillforged skills from graph memory into the current project |
Claude Code also provides /recall <query> as a skill command with deeper graph lookup and edge traversal.
Skillforge
Skillforge is an automatic pipeline stage that converts frequently-accessed memory nodes into executable slash-command skills. When a node crosses a scoring threshold (based on access count, recall actions, session span, pinned status, and procedural content), the daemon enqueues a skillforge job that:
- Reads the source node and its connected nodes
- Generates a structured workflow skill file
- Writes it to
.claude/commands/and.opencode/commands/in the project root - Creates a manifest in
<graphRoot>/.skillforge/for tracking
Skills are automatically refreshed when their source node content changes (drift detection). The daemon compares content hashes each tick and enqueues skillforge_refresh jobs for drifted manifests.
Key config (CONFIG.skillforge):
| Setting | Default | Description |
|---------|---------|-------------|
| enabled | true | Enable/disable skillforge scoring and job enqueueing |
| scoreThreshold | 0.55 | Minimum score to become a skillforge candidate |
| cooldownDays | 14 | Days before a skillforged node can be re-scored |
| maxSkillsPerProject | 15 | Cap on skills per project |
| maxJobsPerTick | 2 | Max skillforge jobs enqueued per daemon tick |
Project Document Bootstrapping
The daemon can auto-generate project documentation files (CLAUDE.md / AGENT.md) from mental model data:
- Generates sections for mental model context, inject flow, and project working state
- Preserves custom sections between regenerations
- Detects drift between current model state and existing doc content
- Triggers automatically after enough project observations accumulate
Tool
The plugin exposes one tool: graph_memory. In Claude Code it is registered as an MCP server; in OpenCode it is registered directly by the plugin extension.
Supported actions:
| Action | Description |
|--------|-------------|
| initialize | Create the graph structure and global pointer file |
| configure_runtime | Choose manual or Docker runtime and write runtime config |
| status | Report initialization state, runtime, counts, and warnings |
| remember | Create or update a durable graph node |
| write_note | Save a working note into the buffer |
| search | Keyword search over the graph index |
| recall | Search plus edge traversal |
| read_node | Read a node by path |
| list_edges | Inspect node connections |
| read_dream | Read dream fragments |
| consolidate | Run the consolidation path manually |
| history | Show recent git history |
| revert | Roll the graph back to an earlier commit |
| resurface | Move an archived node back into the active graph |
| notion_setup | Create Notion workspace structure (databases + wiki pages) |
| notion_sync | Run outbound sync (diff + plan + execute) |
| notion_consolidate | Merge batched wiki pages into category pages (supports dryRun option) |
Resources:
| Resource | Description |
|----------|-------------|
| graph://map | compressed knowledge map |
| graph://priors | learned behavioral priors |
Pipeline Job Types
| Job Type | Description |
|----------|-------------|
| scribe | Extract deltas from conversation buffer |
| observer | v3: produce observations, session logs, node upserts |
| compressor | Fold observations into mental models, generate whispers |
| auditor | Mechanical triage of scribe deltas |
| librarian | Judgment-heavy graph updates and context regeneration |
| dreamer | Creative cross-node associations |
| working_update | Update per-project working state from session activity |
| skillforge | Convert high-access nodes into slash commands |
| skillforge_refresh | Update drifted skillforged skills |
| bootstrap_project_doc | Auto-generate project documentation |
| memory_analysis | Daily brief and analysis generation |
| notion_sync | Outbound sync to Notion |
| notion_inbound_triage | Triage incoming Notion edits |
| notion_inbound_enrich | Enrich triaged Notion edits |
Configuration
| Config | Source | Default |
|--------|--------|---------|
| graph root pointer | ~/.graph-memory-config.yml | ~/.graph-memory/ |
| per-graph settings | <graphRoot>/config.yml | git enabled |
| runtime config | <graphRoot>/.runtime-config.json | manual |
Storage Layout
~/.graph-memory/
nodes/ # Active durable knowledge nodes (canonical store, 22 category dirs)
archive/ # Archived nodes + legacy docs
v3-graph-backup/ # Archived diverged v3 graph directory
dreams/ # pending/, integrated/, archived/, projects/
briefs/ # Daily brief outputs
daily/
mind/ # Global mental model
model.json # cognitive style, preferences, guardrails
whisper.txt # pre-generated injection paragraph
observations.jsonl # append-only observation feed
lenses/ # Per-project models
{project}/
model.json # project model
whisper.txt # project whisper
observations.jsonl # project observations
_archived/ # decommissioned project lenses
sessions/ # Session logs
{project}.jsonl
working/ # Per-project working state
global.md
projects/{project}.md
.deltas/ # Scribe output
.jobs/ # Background queue state
.pipeline-logs/ # Worker logs
.pipeline/ # Pipeline intermediate state
observations/absorbed/ # Absorbed observation deltas
.logs/ # Activity log + input-refresh logs
.inputs/ # External brief inputs
gmail/, calendar/, slack/ # Per-source classified/normalized/
config.json
.skillforge/ # Generated skill manifests
.notion-sync-state.json # Notion workspace sync state
.notion-sync-input.json # Notion sync input staging
.notion-sync-plan.json # Notion sync execution plan
MAP.md # Knowledge graph index (context file)
WORKING.md # Project handoff state (context file)
DREAMS.md # Speculative fragments (context file)
PRIORS.md, SOMA.md # Legacy context files (superseded by mental model)Dashboard
The optional memory-dashboard/ provides a real-time inspection UI:
- Architecture view — mental model inspector (global model, project models, whisper preview, inject flow)
- Graph explorer — interactive node graph with detail panel and inline editing
- Session replay — per-session event timeline with tool traces
- Activity rail — real-time SSE feed of pipeline events, jobs, and health metrics
- Memory health — 4-factor health score with node count, confidence, coverage, staleness
Server: Express on port 3001. Frontend: React + Vite on port 5173.
Development Notes
- build:
npm run build - test:
npm test - type-check:
npx tsc --noEmit - Claude Code plugin manifest:
.claude-plugin/plugin.json - OpenCode extension:
extensions/graph-memory-opencode.ts - pi extension:
extensions/graph-memory.ts - memory section templates:
templates/ - agent instructions:
agents/ - optional pipeline agents: observer, compressor, dreamer
- migration script:
src/graph-memory/scripts/migrate-mental-model.ts(legacy) - Notion sync design spec:
docs/notion-sync-spec.md - examples:
../examples/
