chronicle-of-worlds
v0.1.0
Published
Call graph and agent navigation index for Feature-Sliced Design projects. Gives AI agents precise impact analysis and symbol navigation in FSD codebases.
Downloads
31
Maintainers
Readme
chronicle-of-worlds
Give your AI agent a map of your FSD codebase.
AI agents are blind without context. In a Feature-Sliced Design project they waste tokens hopping through barrel exports, guessing blast radius, and re-reading files they already know. chronicle-of-worlds generates a precise call graph and symbol index from your TypeScript source, then serves them as MCP tools — so agents answer "what breaks if I change this?" and "where is this symbol?" in milliseconds without reading a single extra file.
Works with solo FSD projects (src/{layer}/{slice}/...) and FSD monorepos (apps/*/src/... + packages/*/src/...). Integrates with Cursor, Claude Code, Codex, and Kimi out of the box.
npm install -D chronicle-of-worlds
chronicle init --tools cursor,claude --preset fsd-solo
chronicle graph && chronicle index
chronicle query symbol useAuthWhat it builds
| Artifact | File | What agents use it for |
|----------|------|------------------------|
| Call graph | graph.json | Blast-radius analysis — who calls this, who imports it |
| Agent index | index.json | Symbol → file/line/slice lookup without barrel-hopping |
Both are plain JSON. Agents can query them via MCP tools, CLI, or direct JSON grep as fallback.
Installation
# npm
npm install -D chronicle-of-worlds
# pnpm
pnpm add -D chronicle-of-worlds
# yarn
yarn add -D chronicle-of-worldsRequires Node.js ≥ 20.
Quick start
Solo FSD project (single app, layers at src/{layer}/{slice})
chronicle init --preset fsd-solo --tools cursor,claude
# → creates chronicle.config.json with workspaces: [{ root: "src", src: "." }]
# → writes .cursor/mcp.json and .mcp.json for Claude Code
chronicle graph && chronicle index
chronicle query symbol useCurrentUserFSD monorepo (apps/*/src + packages/*/src)
chronicle init --preset fsd-monorepo --tools cursor,codex,kimi
# → creates chronicle.config.json with monorepo workspaces
chronicle graph && chronicle index
chronicle query impact Button --slice platform/entities/authConfiguration
chronicle.config.json in the project root. Schema with autocomplete: schema/chronicle.config.schema.json.
Solo project example
{
"$schema": "./node_modules/chronicle-of-worlds/schema/chronicle.config.schema.json",
"workspaces": [{ "root": "src", "src": "." }],
"slice": { "preset": "fsd-solo" },
"imports": { "aliasPrefixes": ["@/", "~/"] },
"outputs": {
"graph": ".chronicle/analyze-impact/graph.json",
"index": ".chronicle/agent-navigation/index.json"
},
"query": { "artifactRoots": [".chronicle"] }
}Monorepo example
{
"$schema": "./node_modules/chronicle-of-worlds/schema/chronicle.config.schema.json",
"workspaces": [
{ "root": "apps", "src": "src" },
{ "root": "packages", "src": "src" }
],
"exclude": ["tooling", "scripts"],
"slice": {
"preset": "fsd-monorepo",
"apps": ["web", "mobile"]
},
"imports": {
"workspacePrefixes": ["@myorg/"],
"aliasPrefixes": ["~/"]
},
"framework": {
"serverFnCallee": "createServerFn",
"routeCallee": "createFileRoute"
},
"outputs": {
"graph": ".chronicle/analyze-impact/graph.json",
"index": ".chronicle/agent-navigation/index.json"
},
"query": { "artifactRoots": [".chronicle"] }
}All config fields
| Field | Default | Description |
|-------|---------|-------------|
| workspaces | [{root:"apps",src:"src"},{root:"packages",src:"src"}] | Source roots to scan |
| exclude | [] | Workspace subdirectory names to skip |
| slice.preset | "fsd-monorepo" | "fsd-monorepo" or "fsd-solo" |
| slice.apps | [] | App names under apps/ (monorepo only) |
| imports.workspacePrefixes | [] | Package name prefixes for cross-slice dep tracking (@org/, pkg-) |
| imports.aliasPrefixes | ["~/"] | Path aliases that resolve within the project |
| framework.serverFnCallee | "createServerFn" | Marks a function as ServerFunction kind |
| framework.routeCallee | "createFileRoute" | Marks a function as Route kind |
| outputs.graph | .chronicle/analyze-impact/graph.json | Call graph output path |
| outputs.index | .chronicle/agent-navigation/index.json | Agent index output path |
| query.artifactRoots | [".chronicle"] | Directories searched when resolving artifact paths |
CLI reference
# Generate artifacts
chronicle graph # Build call graph → outputs.graph
chronicle index # Build agent index → outputs.index
# Query (outputs JSON to stdout)
chronicle query symbol NAME # Find symbol in index
chronicle query symbol NAME --slice platform/entities/auth
chronicle query symbol NAME --app platform
chronicle query symbol NAME --file src/features/auth/lib/use-auth.ts
chronicle query impact NAME # Blast radius from graph
chronicle query impact NAME --file <path>
chronicle query slice SLICE_ID # Slice metadata + exports
chronicle query file RELATIVE_PATH # Reverse deps for a file
# Scaffold
chronicle init # monorepo + cursor,kimi
chronicle init --preset fsd-solo # solo project
chronicle init --tools cursor,claude,codex,kimi # all tools
chronicle init --preset fsd-solo --tools claude # solo + Claude Code onlyGlobal options: --config <path>, --cwd <path>
Agent tool integrations
chronicle init --tools <list> writes the per-tool config automatically. All tools use the same MCP server launched via npx chronicle-mcp.
Cursor
Writes .cursor/mcp.json. Tools available in Cursor agent: query_symbol, query_impact, query_slice, query_file.
Claude Code
Writes project-scoped .mcp.json. The server receives the project root via CHRONICLE_CONFIG env using ${CLAUDE_PROJECT_DIR} expansion.
{
"mcpServers": {
"chronicle": {
"type": "stdio",
"command": "npx",
"args": ["chronicle-mcp"],
"env": { "CHRONICLE_CONFIG": "${CLAUDE_PROJECT_DIR:-./}/chronicle.config.json" }
}
}
}Codex
Appends to .codex/config.toml:
[mcp_servers.chronicle]
command = "npx"
args = ["chronicle-mcp"]Kimi Code CLI
Copies skill templates to .kimi/skills/. Plugin wiring still requires a manual .kimi/plugins/<name>/plugin.json pointing to kimi-bridge.mjs — see the plugin template in templates/.
Manual MCP (any client)
# Launch via npx (recommended — resolves from project)
npx chronicle-mcp
# Or via CHRONICLE_CONFIG env for non-standard locations
CHRONICLE_CONFIG=/path/to/chronicle.config.json npx chronicle-mcpMCP tools
All four tools accept optional file, slice_id, app filters for disambiguation when a symbol name is not unique.
| Tool | Input | Returns |
|------|-------|---------|
| query_symbol | name | File, line, kind, sliceId for the symbol |
| query_impact | name | All callers and import dependents |
| query_slice | slice_id | Slice metadata, exports, dependencies |
| query_file | path | Reverse deps (who calls / imports this file) |
CI / pre-commit integration
Regenerate artifacts on every commit so agents always have fresh data:
# lefthook.yml
pre-commit:
jobs:
- name: Generate Call Graph
run: chronicle graph && git add .chronicle/analyze-impact/graph.json
- name: Generate Agent Index
run: chronicle index && git add .chronicle/agent-navigation/index.jsonOr as a combined step:
chronicle graph && chronicle indexProgrammatic API
import {
loadConfig,
generateGraph,
generateIndex,
querySymbol,
queryImpact,
resolvePreset,
} from 'chronicle-of-worlds';
const { config, rootDir } = loadConfig({ cwd: process.cwd() });
// Generate
generateGraph({ config, rootDir });
generateIndex({ config, rootDir });
// Query
const sym = querySymbol(config, rootDir, 'useAuth');
const impact = queryImpact(config, rootDir, 'Button', { slice: 'platform/shared/ui' });
// Preset utilities
const { getSliceId, getSegment } = resolvePreset(config);
console.log(getSliceId('/project/src/entities/auth/lib/use-auth.ts', '/project'));
// → "entities/auth"Adding a custom preset
Drop a new file in src/presets/ exporting getSliceId, getSegment, getSliceDirPath, and register it in src/presets/index.mjs. The preset name becomes a valid value for slice.preset in config.
Known limitations
- Dynamic imports with variable paths are not tracked
export * fromre-export chains may be incompleteimport type { T }(type-only) is not indexedexport defaultis only partially detected- Wrapper patterns like
useServerFn(fn)obscure the callee name - No incremental build — full rescan on every run (planned)
Agent rules
See AGENTS.md for the required agent workflow: query before editing exports, disambiguation patterns, known limits, and fallback grep strategy.
