Enrich a graphify knowledge graph with temporal metadata from filesystem timestamps.
Adds file_mtime, file_birthtime, dir_mtime to nodes and deterministic preceded_by edges — making your knowledge graph time-aware without any LLM cost.
graphify-temporal can resolve three distinct timestamps from the filesystem:
| Attribute | Flag | Meaning |
|---|---|---|
file_mtime |
(default) | Last content modification |
file_mtime |
--use-ctime |
Inode metadata change (Unix) / creation (Windows) |
file_mtime |
--use-birthtime |
True creation time — when the file was born on disk |
dir_mtime |
--include-dir-mtime |
Parent directory mtime — best proxy for "when did this file arrive here" |
The three timestamps (mtime, birthtime, dir_mtime) are often different, giving
you a timeline: created → arrived in this directory → last modified.
Birth time (st_birthtime) is supported on:
- Linux kernel ≥ 4.11 on ext4 / btrfs / xfs (via
statxsyscall) - macOS ≥ 10.4 (natively via
st_birthtime) - Windows (natively via
st_birthtime)
When birthtime is unavailable the fallback is file_mtime = None — never a crash.
pip install git+https://github.com/todotge/graphify-temporal.gitOr clone and install locally:
git clone https://github.com/todotge/graphify-temporal.git
cd graphify-temporal
pip install .If graphify-temporal is not found after install, use python -m graphify_temporal instead — the binary lives in your venv's bin/ directory.
graphify-temporal is a separate CLI from graphify. The enrichment
subcommand is graphify-temporal enrich, not graphify enrich.
After every /graphify build, run graphify-temporal enrich — the
graph is not complete without temporal stamps.
# Basic: add file_mtime to all nodes + intra-file preceded_by edges
graphify-temporal enrich
# Cross-file temporal edges + filter by date
graphify-temporal enrich --cross-file --since 2026-05-01
# Use true creation time (birthtime) instead of modification time
graphify-temporal enrich --use-birthtime
# See when files arrived in their directories
graphify-temporal enrich --include-dir-mtime
# Full timeline: birthtime as primary + directory arrival time
graphify-temporal enrich --use-birthtime --include-dir-mtime
# Use creation time instead of modification time
graphify-temporal enrich --use-ctime
# Preview on a subdirectory without modifying
graphify-temporal enrich --include "your/archive/**" --dry-run
# Exclude archive directories
graphify-temporal enrich --exclude "**/archive/**" --exclude "**/old/**"| Flag | Description |
|---|---|
PATH |
Project root (default .) |
--use-ctime |
Use st_ctime instead of st_mtime (metadata-change on Unix, creation on Windows) |
--use-birthtime |
Use st_birthtime instead of st_mtime (true creation time). Mutually exclusive with --use-ctime |
--include-dir-mtime |
Also add dir_mtime (parent directory mtime) to nodes — arrival proxy |
--cross-file |
Create preceded_by edges across different files |
--dry-run |
Show stats without modifying graph.json |
--since DATE |
Only process files modified after DATE (YYYY-MM-DD) |
--include GLOB |
Only process files matching glob (repeatable) |
--exclude GLOB |
Exclude files matching glob (repeatable) |
--no-regenerate |
Skip regenerating HTML/wiki |
--quiet, -q |
Minimal output |
- Reads
graphify-out/graph.jsonfrom your project - For each node with a
source_file, stats the filesystem:file_mtime(ISO 8601) — modification time (or ctime / birthtime depending on flag)dir_mtime(ISO 8601) — parent directory mtime, when--include-dir-mtimeis set
- Creates
preceded_byedges within each file (ordered by line number) - Optionally creates cross-file chronological edges
- Regenerates
graph.htmlandwiki/
graphify-temporal v1.0.0
Files analyzed: 1,220
Nodes enriched: 14,173 (85%)
Files not found: 12
Edges added: 12,946 (intra-file: 12,911, cross-file: 35)
html: ✓
wiki: ✓
Enrichment is idempotent — you can re-run enrich with different flags anytime.
It updates file_mtime in-place and deduplicates edges, so you never get double
edges or corrupted data.
# First pass: default modification time
graphify-temporal enrich
# Now you want to know when files arrived in their directories
graphify-temporal enrich --include-dir-mtime
# Or switch primary timestamp to true creation time
graphify-temporal enrich --use-birthtime
# Full timeline: birthtime as primary + directory arrival
graphify-temporal enrich --use-birthtime --include-dir-mtimeNo need to rebuild the graph — just run the enrichment again with the flags you need.
Once the graph is enriched with temporal metadata, you can filter and explore it by time. All time filters require explicit dates (YYYY-MM-DD) — the tool does not understand "last week" or "yesterday". You (or your AI agent) must compute the date range before calling the command.
query and timeline default to one entry per file (not per node). Use
--full to see every node. Files inside graphify-out/ are automatically
excluded from enrichment.
# Find nodes by name (one per file)
graphify-temporal query "auth"
# All nodes, no file-level collapse
graphify-temporal query "auth" --full
# Filter by date range
graphify-temporal query "auth" --since 2026-05-01 --before 2026-06-01
# Sort chronologically
graphify-temporal query "auth" --order newest-first
# Walk the preceded_by chain (one per file)
graphify-temporal timeline
# Every node in the chain
graphify-temporal timeline --full
# Start the timeline from a specific node
graphify-temporal timeline "enricher_enrich"
# See temporal coverage stats
graphify-temporal statsAI agent note: When a user asks "what happened last week", compute the date
range first with date -I or datetime, then pass it to --since/--before.
See docs/cli-reference.md for a full table of realistic prompts.
graphify-temporal auto-detects which AI coding assistant you're using and injects instructions so the agent knows how to run temporal enrichment.
# Auto-detect all clients and install instructions
graphify-temporal install
# Install for a specific client
graphify-temporal install --platform opencode
graphify-temporal install --platform claude
# Remove instructions from all clients
graphify-temporal uninstall| Client | Instruction file | Plugin |
|---|---|---|
| Claude Code | CLAUDE.md |
— |
| OpenCode | AGENTS.md |
.opencode/plugins/graphify-temporal.js |
| Codex | AGENTS.md |
— |
| Gemini CLI | GEMINI.md |
— |
| Cursor | .cursor/rules/graphify-temporal.mdc |
— |
| CodeBuddy | CODEBUDDY.md |
— |
| Copilot | .github/copilot-instructions.md |
— |
| Windsurf | .windsurf/rules/graphify-temporal.md |
— |
| Aider | AGENTS.md |
— |
| Kilo Code | AGENTS.md |
— |
| Trae | AGENTS.md |
— |
The OpenCode plugin checks whether graph.json exists but lacks file_mtime
and reminds the agent to run enrichment before it reaches for raw file reads.
- Python >= 3.10
- An existing
graphify-out/graph.json(rungraphify .first) - graphify CLI (for output regeneration)
| Document | Contents |
|---|---|
| docs/cli-reference.md | Complete CLI: every flag, subcommand, example, error code |
| docs/timestamps.md | Timestamp semantics, birthtime support, switching modes, schema |
| docs/team-setup.md | install/uninstall, client detection, OpenCode plugin, team workflow |
| docs/spec.md | Architecture overview, data flow, test plan, dependencies, non-goals |
Issues and PRs welcome — bug reports, edge cases on unusual filesystems, and platform quirks around birthtime resolution are especially useful.
git clone https://github.com/todotge/graphify-temporal.git
cd graphify-temporal
pip install -e ".[dev]"
pytestOpen an issue before a large PR so we can align on approach first. Small fixes and test additions can go straight to a PR.
If graphify-temporal saves you time, consider buying me a coffee — it goes straight back into building and maintaining tools like this one.
MIT