Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions .cursor/hooks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"hooks": {
"afterFileEdit": [
{
"command": "'/home/zack/projects/tokensave/target/debug/tokensave' hook-cursor-after-file-edit",
"matcher": "Write",
"timeout": 30
}
],
"afterShellExecution": [
{
"command": "'/home/zack/projects/tokensave/target/debug/tokensave' hook-cursor-after-shell",
"timeout": 60
}
],
"beforeSubmitPrompt": [
{
"command": "'/home/zack/projects/tokensave/target/debug/tokensave' hook-cursor-before-submit-prompt",
"timeout": 5
}
],
"sessionStart": [
{
"command": "'/home/zack/projects/tokensave/target/debug/tokensave' hook-cursor-session-start",
Comment thread
ScriptedAlchemy marked this conversation as resolved.
"timeout": 5
}
],
"subagentStart": [
{
"command": "'/home/zack/projects/tokensave/target/debug/tokensave' hook-cursor-subagent-start",
"timeout": 5
}
],
"workspaceOpen": [
{
"command": "'/home/zack/projects/tokensave/target/debug/tokensave' hook-cursor-workspace-open",
"timeout": 60
}
]
},
"version": 1
}
3 changes: 2 additions & 1 deletion .cursor/mcp.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"args": [
"serve"
],
"command": "/home/zack/projects/tokensave/target/debug/tokensave"
"command": "/home/zack/projects/tokensave/target/debug/tokensave",
"type": "stdio"
}
}
}
69 changes: 69 additions & 0 deletions .cursor/permissions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"mcpAllowlist": [
"tokensave:tokensave_search",
"tokensave:tokensave_context",
"tokensave:tokensave_callers",
"tokensave:tokensave_callees",
"tokensave:tokensave_impact",
"tokensave:tokensave_node",
"tokensave:tokensave_status",
"tokensave:tokensave_files",
"tokensave:tokensave_affected",
"tokensave:tokensave_dead_code",
"tokensave:tokensave_diff_context",
"tokensave:tokensave_module_api",
"tokensave:tokensave_circular",
"tokensave:tokensave_hotspots",
"tokensave:tokensave_similar",
"tokensave:tokensave_rename_preview",
"tokensave:tokensave_unused_imports",
"tokensave:tokensave_rank",
"tokensave:tokensave_largest",
"tokensave:tokensave_coupling",
"tokensave:tokensave_inheritance_depth",
"tokensave:tokensave_distribution",
"tokensave:tokensave_recursion",
"tokensave:tokensave_complexity",
"tokensave:tokensave_doc_coverage",
"tokensave:tokensave_god_class",
"tokensave:tokensave_changelog",
"tokensave:tokensave_port_status",
"tokensave:tokensave_port_order",
"tokensave:tokensave_commit_context",
"tokensave:tokensave_pr_context",
"tokensave:tokensave_simplify_scan",
"tokensave:tokensave_test_map",
"tokensave:tokensave_type_hierarchy",
"tokensave:tokensave_branch_search",
"tokensave:tokensave_branch_diff",
"tokensave:tokensave_branch_list",
"tokensave:tokensave_gini",
"tokensave:tokensave_dependency_depth",
"tokensave:tokensave_health",
"tokensave:tokensave_redundancy",
"tokensave:tokensave_runtime",
"tokensave:tokensave_dsm",
"tokensave:tokensave_test_risk",
"tokensave:tokensave_body",
"tokensave:tokensave_todos",
"tokensave:tokensave_callers_for",
"tokensave:tokensave_by_qualified_name",
"tokensave:tokensave_signature",
"tokensave:tokensave_impls",
"tokensave:tokensave_diagnose",
"tokensave:tokensave_derives",
"tokensave:tokensave_session_recall",
"tokensave:tokensave_read",
"tokensave:tokensave_outline",
"tokensave:tokensave_implementations",
"tokensave:tokensave_unsafe_patterns",
"tokensave:tokensave_diagnostics",
"tokensave:tokensave_config",
"tokensave:tokensave_signature_search",
"tokensave:tokensave_constructors",
"tokensave:tokensave_field_sites",
"tokensave:tokensave_call_chain",
"tokensave:tokensave_file_dependents",
"tokensave:tokensave_find_exact_symbol"
]
}
10 changes: 10 additions & 0 deletions .cursor/rules/tokensave.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
description: Prefer tokensave MCP tools for codebase exploration
alwaysApply: true
---

# Prefer tokensave MCP tools

- For codebase exploration, symbol lookup, call graphs, callers/callees, impact analysis, affected files, and architectural navigation, use the tokensave MCP tools first.
- Prefer tools such as `tokensave_context`, `tokensave_search`, `tokensave_callers`, `tokensave_callees`, `tokensave_impact`, `tokensave_files`, `tokensave_affected`, and related read-only tokensave tools before broad file reads or search.
- Only fall back to regular file reads, search, or shell commands when tokensave cannot answer the question or after tokensave has identified the exact files or symbols to inspect.
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ on:
push:
branches: [master, feature/holographic-memory]
pull_request:
branches: [master, feature/holographic-memory]
branches: ['**']

permissions:
contents: read
Expand All @@ -15,6 +15,7 @@ env:
jobs:
test:
name: Test ${{ matrix.name }}
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON('["master","feature/holographic-memory"]'), github.event.pull_request.base.ref) }}
runs-on: ${{ fromJSON(matrix.runner) }}
strategy:
fail-fast: false
Expand All @@ -41,6 +42,7 @@ jobs:

clippy:
name: Clippy
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON('["master","feature/holographic-memory"]'), github.event.pull_request.base.ref) }}
runs-on: ubuntu-latest
continue-on-error: true
steps:
Expand All @@ -53,6 +55,7 @@ jobs:

fmt:
name: Format
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository || contains(fromJSON('["master","feature/holographic-memory"]'), github.event.pull_request.base.ref) }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ tokensave install --agent vibe # Mistral Vibe
tokensave install --agent zed # Zed
```

Each agent gets its MCP server registered in the native config format. Claude Code additionally gets a PreToolUse hook (blocks wasteful Explore agents), a UserPromptSubmit hook, a Stop hook, prompt rules in CLAUDE.md, and auto-allowed tool permissions. Kiro gets global MCP config, `tokensave.md` steering loaded as a resource, and a tokensave-managed default agent with permissive built-in/tokensave tool approval, delegation guardrail hooks, and post-write sync; user-managed Kiro agents are preserved.
Each agent gets its MCP server registered in the native config format. Claude Code additionally gets a PreToolUse hook (blocks wasteful Explore agents), a UserPromptSubmit hook, a Stop hook, prompt rules in CLAUDE.md, and auto-allowed tool permissions. Kiro gets global MCP config, `tokensave.md` steering loaded as a resource, and a tokensave-managed default agent with permissive built-in/tokensave tool approval, delegation guardrail hooks, and post-write sync; user-managed Kiro agents are preserved. Cursor global install currently registers the MCP server only; the richer Cursor integration is project-local so it can be checked into a repository.

All changes are idempotent -- safe to run again after upgrading. After agent setup, you'll be offered a global git post-commit hook.

Expand All @@ -145,7 +145,18 @@ For project-scoped setup, run from the repository root:
tokensave install --local --agent cursor
```

Local install writes only workspace files such as `.cursor/mcp.json`, `.mcp.json`, `.codex/config.toml`, `.vscode/mcp.json`, or the equivalent project config for Claude, Codex, Gemini, Kiro, OpenCode, Copilot/VS Code, Zed, Roo Code, Kimi, Kilo, and Vibe. Generated MCP configs use the resolved absolute `tokensave` executable path. Local install does not update `~/.tokensave/config.toml`, installed-agent tracking, the last installed version, or the global git post-commit hook. Antigravity and Cline are global-only and return clear unsupported errors for `--local`.
Local install writes only workspace files such as `.cursor/mcp.json`, `.mcp.json`, `.codex/config.toml`, `.vscode/mcp.json`, or the equivalent project config for Claude, Codex, Gemini, Kiro, OpenCode, Copilot/VS Code, Zed, Roo Code, Kimi, Kilo, and Vibe. Generated MCP configs use the resolved absolute `tokensave` executable path. For Cursor, local install also writes `.cursor/rules/tokensave.mdc`, `.cursor/permissions.json`, and `.cursor/hooks.json`: the rule tells Cursor Agent to prefer tokensave MCP tools for codebase exploration, and permissions auto-allow only read-only tokensave MCP tools. The project hooks are:

- `sessionStart` — fire-and-forget; injects context steering the Agent toward tokensave MCP tools and reports index freshness (suggests `tokensave init` when no `.tokensave/` exists).
- `subagentStart` — blocks research/explore subagents until tokensave MCP tools have been tried.
- `beforeSubmitPrompt` — resets the local token counter for the new turn.
- `afterFileEdit` (matcher `Write`) — runs a **targeted single-file** sync of just the edited path(s) via `sync_if_stale_silent`, never a full-tree scan (which would scale with repo size, not edit size).
- `afterShellExecution` — on Agent-run `git checkout`/`switch`/`worktree add`, bootstraps/maintains tokensave branch tracking (`branch add`); on other state-changing git commands (pull/merge/rebase/reset/cherry-pick/stash apply|pop), runs a coalesced incremental sync.
- `workspaceOpen` — ensures the current branch's DB exists (branch add if missing) and runs a catch-up incremental sync.

All Cursor hooks are fail-open and only act when a `.tokensave/` index already exists. **Blind spot:** Cursor hooks only observe the Cursor Agent's own actions and IDE lifecycle. Manual/external-terminal `git checkout` and in-place branch switches are NOT seen by these hooks (`workspaceOpen` does not fire for an in-place checkout). For those, the git post-commit hook and the on-demand MCP staleness check remain the freshness mechanism. We intentionally do not add `beforeReadFile`/`preToolUse` blocking hooks here (too aggressive/noisy); they may become opt-in later.

Local install does not update `~/.tokensave/config.toml`, installed-agent tracking, the last installed version, or the global git post-commit hook. Antigravity and Cline are global-only and return clear unsupported errors for `--local`.

### 3. Index your project

Expand Down
17 changes: 16 additions & 1 deletion docs/USER-GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ tokensave install --agent kimi # Moonshot Kimi CLI
tokensave install --agent vibe # Mistral Vibe
```

Each agent gets an appropriate configuration: MCP server registration, tool permissions (where the agent supports them), and prompt rules in the agent's instruction file.
Each agent gets an appropriate configuration: MCP server registration, tool permissions (where the agent supports them), and prompt rules in the agent's instruction file. Cursor's global install currently registers the MCP server only; use project-local install for Cursor rules, permissions, and hooks that can live with the repository.

Kiro setup registers tokensave in `~/.kiro/settings/mcp.json`, writes steering to
`~/.kiro/steering/tokensave.md`, and writes a tokensave-managed agent that loads
Expand All @@ -225,6 +225,21 @@ tokensave install --local --agent copilot

Local installs write workspace files instead of user-level agent config. Supported local targets are Claude Code, Codex, Gemini, Kiro, OpenCode, GitHub Copilot / VS Code, Cursor, Zed, Roo Code, Kimi, Kilo, and Mistral Vibe. Examples include `.mcp.json`, `.claude/settings.json`, `.cursor/mcp.json`, `.codex/config.toml`, `.vscode/mcp.json`, `.kiro/settings/mcp.json`, `opencode.json`, `.roo/mcp.json`, `.kimi-code/mcp.json`, `kilo.json`, and `.vibe/config.toml`.

Cursor local install creates a stronger project-local setup:

- `.cursor/mcp.json` registers the tokensave MCP server.
- `.cursor/rules/tokensave.mdc` tells Cursor Agent to prefer tokensave MCP tools for codebase exploration and to fall back to file reads/search only when needed.
- `.cursor/permissions.json` auto-allows read-only tokensave MCP tools using Cursor's `mcpAllowlist` format while leaving mutating edit/session tools subject to normal approval.
- `.cursor/hooks.json` installs Cursor-specific, fail-open project hooks (each acts only when a `.tokensave/` index exists):
- `sessionStart` injects context steering the Agent toward tokensave MCP tools and reports index freshness (suggests `tokensave init` when uninitialized).
- `subagentStart` denies research/explore subagents with Cursor's documented hook response shape.
- `beforeSubmitPrompt` resets the local token counter.
- `afterFileEdit` (matcher `Write`) runs a **targeted single-file** sync of only the edited path(s) — not a full-tree scan — so it stays cheap on large codebases even when the Agent edits many files per turn.
- `afterShellExecution` makes branch handling automatic: Agent-run `git checkout`/`switch`/`worktree add` bootstraps/maintains tokensave branch tracking (`branch add`), while other state-changing git commands (pull/merge/rebase/reset/cherry-pick/stash apply|pop) trigger a coalesced incremental sync.
- `workspaceOpen` ensures the current branch's DB exists (branch add if missing) and runs a catch-up incremental sync.

Blind spot: Cursor hooks only observe the Cursor Agent's own actions and IDE lifecycle. Manual or external-terminal `git checkout` and in-place branch switches are not visible to these hooks (`workspaceOpen` does not fire for an in-place checkout). Use the git post-commit hook and the on-demand MCP staleness check to keep the index fresh for those cases. `beforeReadFile`/`preToolUse` blocking hooks are intentionally omitted for now to avoid noise; they may become opt-in later.

The generated MCP entries use the resolved absolute path to the current `tokensave` executable. A local install does not update `~/.tokensave/config.toml`, installed-agent tracking, the last installed version, or the global git post-commit hook prompt. Antigravity and Cline do not currently have documented project-local config paths, so `tokensave install --local --agent antigravity` and `tokensave install --local --agent cline` are rejected with unsupported-agent errors.

#### Config backups
Expand Down
Loading
Loading