pi-codegraphcontext
Pi coding-agent extension for CodeGraphContext (CGC): index lifecycle gate, freshness sync, agent routing guidance, status surfaces, and CLI-gap tools wrapping the cgc binary.
Package details
Install pi-codegraphcontext from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-codegraphcontext- Package
pi-codegraphcontext- Version
0.9.0- Published
- Sep 20, 2026
- Downloads
- 1,304/mo · 1,151/wk
- Author
- raphael_b_01
- License
- MIT
- Types
- extension, skill
- Size
- 2.2 MB
- Dependencies
- 0 dependencies · 2 peers
Pi manifest JSON
{
"skills": [
"./skills",
"!skills/cgc-routing/**"
],
"extensions": [
"./extensions"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-codegraphcontext
A Pi coding-agent extension for CodeGraphContext, keeping a code-graph index healthy for every session and makes it effortless for the agent to use.
What It Is
A single Pi extension that wraps the cgc CLI, evaluates the index lifecycle at session start, syncs drift automatically, and surfaces everything the agent needs: slash commands, a status widget, CLI-gap tools, and routing guidance.
Why It Exists
Code-graph answers are only as good as the index behind them. Without a gate, agents either skip the graph (stale or missing index) or block on it (busy, corrupt). This extension makes the graph always ready or honestly unavailable, never silently wrong.
[!NOTE] Graph relationship tools (
analyze_code_relationships,find_dead_code,find_code, …) are registered by the CGC MCP server, not by this extension. The extension owns everything around them: the lifecycle, the freshness, the status surfaces, and the gaps in the MCP catalog.
Features
| Capability | What you get |
|---|---|
| Index lifecycle gate | Every session start classifies the workspace (unavailable, unindexed, busy, indexing, rebuilding, drift, syncing, clean, corrupt) and routes accordingly — one-time notices, background indexing, or a silent skip |
| Freshness sync | Drift between the working tree and the graph is detected and auto-synced (bounded per session), so graph answers stay trustworthy as code changes |
| Status HUD | A persistent widget shows index state at a glance — no commands needed |
| Slash commands | /cgc status, /cgc index, /cgc sync, /cgc rebuild, /cgc report, /cgc doctor for explicit control |
| Proactive context | A one-shot session note (at most once, even across mid-session readiness transitions) tells the agent what the graph can answer |
| Worktree contexts | Optional isolate mode maps git worktrees to dedicated CGC contexts (--context wt-<id>), with durable identity-verified mappings and fail-closed mismatch handling |
| Output economy | CGC tool output is size-capped, secrets are redacted, and oversized results spill to disk with archive IDs instead of flooding the context window |
| CLI-gap tools | cgc_bundle_export, cgc_context, and cgc_doctor wrap the CGC verbs the MCP catalog does not expose |
| Agent guidance | An always-on routing guideline card (graph-vs-text tool choice) plus an on-by-default (opt-out) cgc-routing skill |
Everything is fail-open: a guard error is recorded, retried at most once per session, and never blocks the agent loop. Detection errors degrade honestly (for example, a malformed .git pointer simply means "not a worktree") instead of producing wrong answers.
Requirements
- Pi coding agent (
@earendil-works/pi-coding-agentis used as a peer dependency). - The CodeGraphContext CLI (
cgc) installed and set up, available onPATH, or pointed at viaCGC_EXECUTABLE. See the CGC indexing guide for installing and preparing the CLI.
Installation
Install and setup CodeGraphContext (see the CodeGraphContext documentation):
cgc --versionAdd the extension to Pi. Either the published package:
# in ~/.pi/agent/settings.json { "packages": ["npm:pi-codegraphcontext"] }…or a local clone:
{ "packages": ["/path/to/pi-codegraphcontext"] }Start (or
/reloadPi). On the first session in a repository you get exactly one honest notice: either "indexing in the background" (lifecycle.autoCreate) or "not indexed — here is how to enable auto-create" (default).
[!TIP] No configuration is required for the default experience. Every behavior below has a working default; the configuration section exists to change defaults, not to enable features.
Usage
Slash Commands
All commands live under /cgc:
| Command | Purpose |
|---|---|
/cgc status |
Workspace state, freshness, and recent activity |
/cgc index |
Force (re)index now |
/cgc sync |
Reconcile graph/disk drift on demand |
/cgc rebuild |
Drop and rebuild the index |
/cgc report |
Write the CGC quality report to a confirmed path |
/cgc doctor |
Bounded diagnostic render (connection, parser, backend health) |
/cgc config |
In-session settings modal (TUI); read-only table elsewhere |
Automatic Behavior
On every session_start the gate classifies the workspace and acts:
- clean → silent skip, zero maintenance invocations
- drift → background sync (bounded by
freshness.maxSyncsPerSession) - unindexed → background indexing if
lifecycle.autoCreate, else one honest notice - busy → skip with a one-time notice (never fights a running index)
- corrupt → one-time report with a rebuild offer; nothing destructive happens uninvited
- unavailable → one-time warning naming every enablement route (
CGC_EXECUTABLE, config files,PATH)
The status HUD reflects all of this live; no command is needed to see the state.
What the Agent Gets
- CGC MCP graph tools (from the CGC MCP server) for relationship, structure, and code health questions — see the MCP tools documentation.
- The always-on guideline card steering tool choice: graph for relationships, built-in search for exact strings.
- The
cgc-routingskill (on by default; opt out withguidance.routingSkill: false) with intent-first tool-choice detail — model-invocable for autonomous routing, user-executable via/skill:cgc-routing. - The CLI-gap tools filling the MCP catalog gaps.
- The agent guide — the deep, intent-first reference the card and skill link to.
Configuration
Configuration is resolved in this order (each layer overrides the previous one):
- Built-in defaults
- Global config file —
$PI_CODING_AGENT_DIR/cgc.json(default~/.pi/agent/cgc.json) - Project config file —
.pi/cgc.json(wins on conflict) - Environment variables (for headless/CI setups)
Only keys present in a config file are applied; invalid values are skipped with a warning and fall back to the lower layer.
In-Session Settings (/cgc config)
/cgc config opens a settings modal inside a TUI session (outside the TUI it renders a read-only key/value/source table instead):
- Every config key is shown with its effective value and source — built-in default, config file (project or global), or environment override.
- Environment-overridden keys are read-only, naming the winning variable: editing a file cannot beat the env layer, so the modal does not offer an edit it cannot make effective.
- Editable keys validate with the exact rules the config loader applies (booleans;
worktree.mode∈off/isolate; timeouts as positive milliseconds; the TCP port as an integer 1–65535; byte budgets and sync counts as positive whole numbers; the executable as a non-empty string). Invalid input is rejected inside the modal and never reaches disk. - A write-target selector chooses where staged edits land: the project
.pi/cgc.json(default) or the global agent-directorycgc.json(PI_CODING_AGENT_DIR-aware). Saves merge only the edited nested keys into the chosen file — unknown sections and keys are preserved verbatim, a malformed target file is refused untouched, and writes are atomic (temp file + rename). - Saved changes apply at the next session start — the running session keeps its loaded behavior; the modal and the completion notice say so explicitly.
The modal degrades fail-open: overlay ctx.ui.custom → non-overlay ctx.ui.custom → the documented dialog flow → the read-only table; every UI or filesystem failure is a bounded notice, never a crashed or blocked session.
Full Configuration Reference
{
"cgc": {
"executable": "cgc",
"timeoutMs": 30000,
"maintenanceTimeoutMs": 600000,
"versionProbeTimeoutMs": 10000,
"api": {
"enabled": true,
"port": 8000
}
},
"lifecycle": {
"autoCreate": false,
"syncOnStart": true
},
"worktree": {
"mode": "off"
},
"proactive": {
"sessionNote": true,
"driftSteers": false,
"resultAnnotations": false
},
"freshness": {
"watch": "off",
"watcherLivenessMs": 15000,
"autoSync": true,
"maxSyncsPerSession": 2
},
"output": {
"maxBytes": 16384,
"spillToTemp": true,
"redactSecrets": true,
"gcf": false
},
"tools": {
"cliGap": {
"enabled": true
}
},
"guidance": {
"routingSkill": true
}
}
| Section | Key | Default | What it controls |
|---|---|---|---|
cgc |
executable |
"cgc" |
The CGC binary (name or absolute path) |
cgc |
timeoutMs / versionProbeTimeoutMs |
30000 / 10000 |
Per-command and version-probe budgets (probes, /cgc doctor, /cgc report) |
cgc |
maintenanceTimeoutMs |
600000 |
Budget for background maintenance runs (/cgc index, /cgc sync) |
cgc |
api.enabled / api.port |
true / 8000 |
Use the CGC HTTP API for the indexedness check (falls back to cgc list). Refer to the How the Status Check Works section |
lifecycle |
autoCreate |
false |
Index a workspace automatically when none exists (consent gate) |
lifecycle |
syncOnStart |
true |
Sync drift detected at session start |
worktree |
mode |
"off" |
"isolate" maps each git worktree to its own CGC context |
proactive |
sessionNote / driftSteers / resultAnnotations |
true / false / false |
Proactive surfaces: the one-shot session note, drift steering, tool-result annotations |
freshness |
watch / watcherLivenessMs / autoSync / maxSyncsPerSession |
"off" / 15000 / true / 2 |
Tri-state watcher mode (off / on / auto — auto spawns only on server backends on already-indexed workspaces; true/false map to on/off), its liveness-verification budget, background syncing, and the per-session sync bound |
freshness.watcherLivenessMs |
15000 |
CGC_FRESHNESS_WATCHER_LIVENESS_MS |
Liveness-verification budget for the managed watcher: the workspace reports fresh only after the watcher survives this window |
output |
maxBytes / spillToTemp / redactSecrets / gcf |
16384 / true / true / false |
Output budget, spill-to-disk, secret redaction, graph-context-format output |
tools |
cliGap.enabled |
true |
Registers the three CLI-gap tools (cgc_bundle_export, cgc_context, cgc_doctor) |
guidance |
routingSkill |
true |
Offers the cgc-routing skill to the agent (opt out with false) |
How the Status Check Works
The extension answers "is this workspace indexed?" on every session start and in /cgc status. How it answers depends on how CGC stores the index for your backend:
- Bundled backend (Kùzu): CGC keeps the index in a
.codegraphcontext/directory inside the workspace — its presence is a fast, definitive "indexed" signal. - Server backends (Neo4j, FalkorDB): the graph lives on the server, so there is no local directory to check — these are the marker-less backends. Here the extension asks CGC itself, in this order:
- The CGC HTTP API (
cgc.api.enabled, default on): a one-shot Cypher lookup against a loopback-only API — the extension spawns one on demand if none is running. Fastest; usescgc.api.port. - The
cgc listCLI probe: lists the registered repositories and matches the workspace path. Slower (a fresh CLI process), identical answer.
- The CGC HTTP API (
Both are read-only, bounded, and fail-open: if neither can answer, the extension says so honestly instead of guessing. The API is optional — without it (or with cgc.api.enabled: false) the CLI probe decides; the only cost is time.
Environment Variables
Every behavior has an environment override (they take precedence over config files).
Booleans accept 1/true/yes/on and 0/false/no/off.
| Variable | Overrides |
|---|---|
CGC_EXECUTABLE |
cgc.executable |
CGC_TIMEOUT_MS / CGC_MAINTENANCE_TIMEOUT_MS / CGC_VERSION_PROBE_TIMEOUT_MS |
cgc time budgets |
CGC_API_ENABLED / CGC_API_PORT |
cgc.api.* |
CGC_LIFECYCLE_AUTO_CREATE / CGC_LIFECYCLE_SYNC_ON_START |
lifecycle.* |
CGC_WORKTREE_MODE |
worktree.mode |
CGC_FRESHNESS_WATCH / CGC_FRESHNESS_AUTO_SYNC / CGC_FRESHNESS_MAX_SYNCS_PER_SESSION |
freshness.* |
CGC_GUIDANCE_ENABLED / CGC_GUIDANCE_ALWAYS_ON / CGC_GUIDANCE_ROUTING_SKILL / CGC_GUIDANCE_GUIDELINES |
guidance.* and the guideline text itself |
CGC_TOOLS_CLI_GAP_ENABLED |
tools.cliGap.enabled |
CGC_ALLOWED_ROOTS |
Path sandbox for CGC operations (absolute roots) |
CGC_COMMAND_NAME / CGC_NAMESPACE |
The /cgc command name and namespace |
Example for a headless CI run:
export CGC_LIFECYCLE_AUTO_CREATE=true
export CGC_FRESHNESS_WATCH=false
export CGC_ALLOWED_ROOTS="$PWD"
Troubleshooting
- "unavailable" notice at session start — the
cgcbinary was not found. CheckPATH, setCGC_EXECUTABLE, or configurecgc.executablein a config file. - "unindexed" notice — enable
lifecycle.autoCreate(orCGC_LIFECYCLE_AUTO_CREATE) or run/cgc index. - Graph answers look stale — run
/cgc sync, or enablefreshness.watch. - Nothing worktree-related happens — worktree contexts are
offby default; setworktree.mode: "isolate"to opt in. - CLI errors — see the CGC troubleshooting guide, then
/cgc doctor.
Development
bun install
bun test # ~935 tests across 32 files
bunx tsc --noEmit # type check
The extension is fully covered by the per-capability specs under openspec/specs/ and the archived change history under openspec/changes/archive/.