NeuroWeave Timeline (NWT)
Process memory for AI agents and humans. NWT remembers how a project became what it is — not just what it is now.
Most tools remember results. NWT remembers evolution.
Traditional memory: User → Context → Summary → Memory
Timeline memory: User → Action → Timeline Event → Evolution Graph
Every meaningful action in your project — a decision, a refactor, a file creation, a bug fix — becomes a node in a durable timeline. The links between nodes form an Evolution Graph that explains why the project looks the way it does today.
What you can ask
| Question | One-liner |
|---|---|
| Why does this file exist? | nwt explain activation.py |
| Why was this architecture chosen? | nwt search "architecture decision" |
| What happened three months ago? | nwt history |
| What decisions led to the current design? | nwt story |
| Show me the evolution graph | nwt graph |
| What did that commit actually do? | nwt git-hook-status |
| What changed between two events? | nwt diff 1 5 |
| Merge small consecutive events | nwt compact |
AI agents reach the same answers over MCP — see MCP integration.
Auto-grow: timeline from git commit
The single biggest reason NWT timelines are empty is friction. The v0.2 fix is a post-commit hook that logs an event on every commit — no human or agent typing required.
nwt init
nwt install-git-hook
git commit -m "Refactor retrieval layer" -m "Reason: lookup latency was high"
nwt: logged [12] Refactor retrieval layer
Add --strict to refuse events without a Reason: line, and
--ai-command "claude -p" to let an external model fill the reason
when the human didn't. See docs/git-hook.md.
30-second quick start
pip install -e .
cd your-project
nwt init
nwt log "Add activation engine" \
--files activation.py \
--reason "retrieval was slow"
nwt history
nwt graph
That's it. Storage is plain JSON under .nwt/. No database, no
embeddings, no vendor lock-in, no daemon.
A tour of the output
nwt history — what happened, in order
[1] 2026-06-15 Project scaffolded [setup, milestone]
reason: Kickoff the MVP
files: pyproject.toml, README.md
[2] 2026-06-15 Add memory engine [core, milestone]
reason: Need a place to put things
files: memory.py
[3] 2026-06-15 Add activation spreading [memory, optimization]
reason: Retrieval was sequential and slow
files: activation.py, retriever.py
[4] 2026-06-15 Add decay mechanism [memory]
reason: Stale nodes should fade
files: activation.py
[5] 2026-06-15 Vectorize activation [refactor, performance]
reason: Loop was the hot path in profiling
files: activation.py
nwt graph — the evolution as a tree
○ 1 Project scaffolded
│
│ 2 Add memory engine
├─ sibling → [ 4] Add decay mechanism
└─ extends → [ 3] Add activation spreading
│
│ 3 Add activation spreading
│
│ 5 Vectorize activation
nwt story — 100 events compressed to one page
# memory-engine-demo — evolution summary
span: 2026-06-15 → 2026-06-15 (5 events)
milestones:
- 1 Project scaffolded — Kickoff the MVP
- 2 Add memory engine — Need a place to put things
- 3 Add activation spreading — Retrieval was sequential and slow
- 4 Add decay mechanism — Stale nodes should fade
- 5 Vectorize activation — Loop was the hot path in profiling
spine file: activation.py
decisions (events with stated reasons):
- [1] Project scaffolded: Kickoff the MVP
- [2] Add memory engine: Need a place to put things
...
nwt explain activation.py — why a file exists
# activation.py
created in: event 3
modified in: 4, 5
reason:
Retrieval was sequential and slow
New in v0.2
Events chain automatically
nwt log appends after the latest event by default, so a plain
sequence of logs forms one linear history. Start an explicit branch
with --parent none, or continue after a specific event with
--parent ID.
Event importance
Events now have an importance field: low, normal (default), high, milestone.
nwt log "Fix login bug" --summary "..." --importance high
nwt log "Project launched" --summary "..." --importance milestone
The story command reports events grouped by importance.
nwt diff — compare two events
nwt diff 1 5
# Output:
# Diff: [1] → [5]
# Events: 5 between these points
# Added: new_feature.py
# Removed: old_feature.py
# In both (likely modified): main.py
nwt compact — merge small events
When you have many small consecutive events with the same tags, compact them:
nwt compact
# Compacted: 50 → 35 events (merged 15)
# backup: .nwt/snapshots/pre-compact-20260920T120000
Options:
--time-window 3600— group events within 1 hour (default)--min-group 3— minimum group size to merge (default)--dry-run— preview the merge without touching disk
Compact backs up timeline/, relations/ and the counter to
.nwt/snapshots/ before rewriting, and remaps parents, typed
relations, indices, and the id counter onto the renumbered events.
How it works
NWT lives in your project as a single .nwt/ directory:
your-project/
└── .nwt/
├── metadata.json # project name, schema version
├── .counter.json # next event id
├── timeline/ # one JSON file per event
│ ├── 000001.json
│ ├── 000002.json
│ └── ...
├── relations/ # typed edges out of each source event
├── snapshots/ # pre-compact backups land here
└── indices/ # derived, rebuildable
├── files.json
└── tags.json
Everything is JSON, atomically written. The whole workspace is
grep-friendly and git diff-friendly. See
docs/architecture.md for the rationale.
MCP integration
For agent developers — NWT ships an MCP server exposing the same answers as tools:
| Tool | Returns |
|---|---|
create_event |
A persisted event with id and timestamp |
search_history |
Matching events across task/summary/reason/files/tags |
get_project_story |
Compressed project story (milestones, decisions, spine file) |
explain_file |
Created/modified-in + earliest reason for a file |
Wire it up in your MCP client:
{
"mcpServers": {
"nwt": {
"command": "nwt-mcp",
"env": { "NWT_ROOT": "/absolute/path/to/your/project" }
}
}
}
The server picks the workspace from $NWT_ROOT if set, else its own
cwd. See docs/mcp.md for the recommended agent loop:
- Session start: call
get_project_storyto load context. - For unfamiliar files: call
explain_filerather than reading cold. - As work is done: call
create_eventwith areasonexplaining why. - When uncertain: call
search_historywith a hypothesis from the current code.
安装
# from a clone (editable)
git clone https://github.com/Thatgfsj/neuroweave-timeline
cd neuroweave-timeline
pip install -e .
# from PyPI (coming soon)
pip install NWtimeline
需要 Python 3.10+。CLI 依赖于 click;MCP 服务器依赖于 mcp。两者都是自动安装的。
安装开发依赖(pytest)并运行测试套件:
pip install -e ".[dev]"
pytest -q
Roadmap
v0.2 (this release) is the "auto-grow" cut: git hook integration with
strict mode and AI-filled reasons, automatic event chaining, the
importance field, diff, and compact. The timeline fills itself now.
- v0.3 — snapshots (
nwt snapshot/nwt restore) and deeper git linkage (commit SHAs on every event,nwt rewind). - v0.4 — multi-agent collaboration history (concurrency-safe writes, per-author identity).
- v0.5 — NWC integration, only if NWT earns it on its own.
See docs/roadmap.md and
docs/standalone.md for the full story.
Contributing
Issues and PRs are welcome. The whole project is ~1,500 lines of
Python plus docs — easy to read end-to-end. Start with
docs/architecture.md for the layout and
CONTRIBUTING.md for the workflow.
Security
NWT stores only what you give it, on disk, in your project's .nwt/.
It does not phone home, does not read environment variables other
than NWT_ROOT, and writes nowhere else. The .gitignore refuses
to track tokens, keys, or .env files. See
SECURITY.md for the full policy.
License
MIT — see LICENSE.
Metadata
Release files for NWtimeline 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| nwtimeline-0.2.0.tar.gz | 55.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| nwtimeline-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 105.8 kB
Release files / nwtimeline-0.2.0.tar.gz
| Download URL | nwtimeline-0.2.0.tar.gz |
|---|---|
| Size | 55.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
a0afd580c6c286e9fb2a6111a0c34c1b64acaf7cb379ed2577d8b341e80e4c7c
|
|
BLAKE2b-256 checksum How to use checksums |
6a4c288608f697569352aa78c642a65a2a8aad02c63c5be477b0211363fa834d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.7
|
Release files / nwtimeline-0.2.0-py3-none-any.whl
| Download URL | nwtimeline-0.2.0-py3-none-any.whl |
|---|---|
| Size | 50.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
49b9ac2cbc6e9fa35ca54424d23c18be37d67c494c055302d9d5da4af422c797
|
|
BLAKE2b-256 checksum How to use checksums |
98e194d0b8f4012f9f40a6ae9cc32d1a3107fc765606717dc6eb5e6deffc63b3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.7
|