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
45 changes: 45 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Docs

on:
push:
branches: [main]
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Install docs dependencies
run: pip install -r docs/requirements.txt
- name: Build site
run: mkdocs build --strict --site-dir ./site
- name: Configure Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./site

deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
150 changes: 35 additions & 115 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,137 +1,57 @@
![nexum](docs/assets/banner.svg)

# nexum

**nexum** is a Claude Code plugin that cuts context tokens and model cost during Claude Code sessions through three optimization pillars:
[![CI](https://github.com/dropdevrahul/nexum/actions/workflows/ci.yml/badge.svg)](https://github.com/dropdevrahul/nexum/actions/workflows/ci.yml)
[![Docs](https://github.com/dropdevrahul/nexum/actions/workflows/docs.yml/badge.svg)](https://github.com/dropdevrahul/nexum/actions/workflows/docs.yml)
[![Release](https://img.shields.io/github/v/release/dropdevrahul/nexum)](https://github.com/dropdevrahul/nexum/releases)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue)](https://www.python.org/)

1. **Context-savings hooks** — automatically truncate large tool outputs, deduplicate repeated results, and warn on context-blowing scans.
2. **Cost-driven planner & executor** — structure work as steps with contracts and scope guards, route to the right model tier (Haiku/Sonnet/Opus) based on complexity, and verify each step against acceptance criteria.
3. **Lifecycle & hygiene guards** — enforce per-session intent continuity, recommend and maintain ignore files, and prevent unscoped recursive searches.
Long Claude Code sessions burn tokens you never meant to spend — the same file read twice, a giant log pasted in full, a planning task quietly running on Opus when Haiku would have done. **nexum** is a plugin that quietly takes those costs back.

## Install
It works along three lines:

This repository is its own Claude Code plugin marketplace. Install it from within Claude Code:
- **Context-savings hooks** — truncate oversized tool outputs, collapse repeated reads before they re-enter context, and stop unscoped recursive scans from ever reaching the model.
- **A cost-driven planner and executor** — break work into steps with explicit contracts and scope guards, route each step to the cheapest model that can do it (Haiku → Sonnet → Opus), and verify every step against a real acceptance check.
- **Lifecycle and hygiene guards** — keep a session's intent coherent across handoffs, recommend and maintain ignore files, and keep the status line honest about where your tokens and dollars are going.

```
/plugin marketplace add dropdevrahul/nexum
/plugin install nexum@nexum
```
It's pure Python standard library, fails open (a broken hook never breaks your session), and keeps all of its state in a single local SQLite file.

`/plugin install` enables the plugin immediately. Use `/plugin marketplace update nexum` to pull new releases.
## Install

To try it from a local checkout instead:
nexum is its own Claude Code plugin marketplace. From inside Claude Code:

```
/plugin marketplace add ./path/to/nexum
/plugin marketplace add dropdevrahul/nexum
/plugin install nexum@nexum
```

## Commands

- **`/nx-plan`** — Analyze the task and produce a multi-step plan with explicit contracts and scope boundaries.
- **`/nx-build`** — Execute the plan, routing each step to Haiku, Sonnet, or Opus based on complexity, running acceptance checks, and reporting per-step results.
- **`/nx-audit`** — Scan the repo for context risks (unignored large/binary files, missing ignore rules) and optionally apply recommendations.

## Status line

nexum ships `scripts/statusline.py`, a Claude Code `statusLine` command that renders a compact session-usage bar in the Claude Code UI:

```
nexum <model> · <bar> <pct>% · <tokens> tok · $<cost> · saved <n>
```

A plugin cannot register the main `statusLine` itself (a plugin's `settings.json` only supports `agent` and `subagentStatusLine`), so you add it to your own settings. Run `/nx-status` to merge it automatically, or add it manually:

```json
{
"statusLine": {
"type": "command",
"command": "python3 \"$(ls -dt ~/.claude/plugins/cache/nexum/nexum/*/scripts/statusline.py | head -1)\"",
"padding": 0
}
}
```

Put this in `~/.claude/settings.json` (user-level) or `.claude/settings.json` (project-level). The `$(ls -dt … | head -1)` resolves the newest installed nexum version, so the status line keeps working after `/plugin update` instead of breaking on a hardcoded version path. (There is only one `statusLine` slot, so this replaces any existing one.)

The status line reads the session JSON piped in by Claude Code on stdin and takes effect on the next interaction after the setting is saved.
`/plugin install` enables it right away. Pull new releases with `/plugin marketplace update nexum`. To run from a local checkout instead, point the marketplace at the path: `/plugin marketplace add ./path/to/nexum`.

The status line appends a `⚠ /compact` warning to prompt you to run `/compact` before the window fills. The warning fires when EITHER of two configurable thresholds is crossed — whichever comes first:
Full details — including the status-line setup, which needs one line in your own settings — are in the [installation guide](https://dropdevrahul.github.io/nexum/install/).

- `statusline_compaction_warn_pct` (default 80%) — fires when context usage reaches this percentage of the window.
- `statusline_compaction_warn_tokens` (default 80,000) — fires when the absolute context token count reaches this value, regardless of window size (useful for large windows such as Opus's 1M-token window where 80% would be 800k tokens).

Both thresholds are configurable via `config.json` in the nexum data directory. Set either to `0` to disable that trigger.

## Technical Notes

- **Stdlib only** — all Python dependencies are from the standard library (3.9+). No pip installs.
- **Fail-open** — hooks never crash the Claude Code session; errors emit `{}` and exit 0.
- **State** — persistent session state (dedup memo, usage metrics, task history) lives in SQLite at `${CLAUDE_PLUGIN_ROOT}/.nexum-data/nexum.db`.

### Context levers: what works today vs. what is pending

**Working levers (PreToolUse `updatedInput` is honored):**

- **Read-guard** — when a file exceeds `read_guard_min_bytes` (default 262144 bytes) and has no explicit `limit` already set, nexum injects a line limit (default `read_guard_inject_lines` = 2000) via `updatedInput`. This is the reliable context-saving path for large file reads. Configure via `config.json`:
```json
{ "read_guard_enabled": true, "read_guard_min_bytes": 262144, "read_guard_inject_lines": 2000 }
```
- **Scan-guard** — unscoped recursive greps, broad globs, and reads into deny paths are blocked via PreToolUse `permissionDecision: deny`. This prevents context-blowing scans from reaching the model at all.

**Pending / self-test-gated (PostToolUse `updatedToolOutput` is currently ignored):**

PostToolUse `updatedToolOutput` is silently ignored for built-in tools on current Claude Code (see anthropics/claude-code [#65403](https://github.com/anthropics/claude-code/issues/65403) and [#32105](https://github.com/anthropics/claude-code/issues/32105)). As a result, the output truncation (`truncate.py`) and dedup pointer-collapse (`dedup.py`) hooks emit replacements that the harness does not apply.

nexum performs a per-session self-test to detect whether the harness honors `updatedToolOutput`. Savings are only counted in the status line and cost report after the self-test confirms the field is being applied — so the `saved` counter stays at zero until upstream fixes the issue (at which point nexum auto-reactivates without any config change).

- **Pre-emptive dedup** (`scripts/predup.py`) — the working, context-saving complement to the inert PostToolUse dedup. It runs as a PreToolUse hook and denies an identical repeated `Read`, `Grep`, or `Glob` call (and optionally read-only `Bash`) that was already executed in the same session. For `Read` calls an mtime guard is applied first: if the file has changed since the first call, the repeat is allowed through. Because a PreToolUse `deny` is actually honored by Claude Code, the avoided re-injection is a **real** saving — it records an ungated saving so the `saved` figure in the status line moves. Configure via `config.json`:
```json
{
"predup_enabled": true,
"predup_decision": "deny",
"predup_bash_readonly": false
}
```
Set `predup_decision` to `"ask"` to prompt instead of silently denying. Set `predup_bash_readonly` to `true` to also cover read-only Bash commands (`cat`, `grep`, `ls`, `git log/diff/show/status/branch`, etc.).

### /nx-build cost preview

Before dispatching any steps, `/nx-build` prints a projected cost breakdown when `plan_preview_enabled` is true (the default). It runs `scripts/plan_preview.py` against the plan file and shows the estimated cost per tier (Haiku / Sonnet / Opus) and the projected savings vs an all-opus run:

```
[nexum] Plan cost preview (estimate)
Steps: 9 | Per-step heuristic: 8,000 in / 2,000 out tokens
Note: token counts are a per-step heuristic, not measured usage.

Tier Steps Input tok Output tok Actual $ Baseline $
--------------------------------------------------------------------
haiku 3 24,000 6,000 $0.0027 $0.0900
sonnet 5 40,000 10,000 $0.0600 $0.1500
opus 1 8,000 2,000 $0.0540 $0.0540
--------------------------------------------------------------------
TOTAL 9 72,000 18,000 $0.1167 $0.2940

Projected: $0.1167 vs all-opus $0.2940 — saves $0.1773 (60.3%)
```
## Commands

The numbers are a per-step token heuristic (an estimate, not measured). The authoritative post-run totals — capturing prompt-cache writes/reads and actual token counts — come from the §10 cost report at the end of the run. Configure via `config.json`:
| Command | What it does |
| --- | --- |
| `/nx-plan` | Break the current task into ordered steps with contracts and scope, routing each to the cheapest capable model tier. |
| `/nx-build` | Execute a plan: dispatch steps to Haiku/Sonnet/Opus, run acceptance checks, retry and escalate on failure. |
| `/nx-audit` | Scan the repo for context risks — unignored large/binary files, missing ignore rules — and optionally apply fixes. |
| `/nx-status` | Install the nexum session-usage status line into your Claude Code settings. |
| `/nx-save` | Write a session handoff so you can resume cleanly in a fresh session before a context limit bites. |
| `/nx-load` | Resume from the most recent handoff written by `/nx-save` or the auto-handoff hook. |

```json
{ "plan_preview_enabled": true }
```
## Documentation

### Session resume nudge
The full documentation lives at **[dropdevrahul.github.io/nexum](https://dropdevrahul.github.io/nexum/)**:

`scripts/resume_nudge.py` runs as a `SessionStart` hook. When a recent handoff for the current branch exists in the nexum data directory, it surfaces a one-line hint in the session context:
- [Install](https://dropdevrahul.github.io/nexum/install/) · [Commands](https://dropdevrahul.github.io/nexum/commands/) · [Configuration](https://dropdevrahul.github.io/nexum/configuration/)
- [How it works](https://dropdevrahul.github.io/nexum/how-it-works/) — the context levers, what works today vs. what's gated on upstream Claude Code fixes
- [Status line](https://dropdevrahul.github.io/nexum/status-line/) · [Contributing](https://dropdevrahul.github.io/nexum/contributing/)

```
[nexum] Resume available: a handoff for branch 'my-branch' was written 2026-06-18T10:00:00+00:00 — run /nx-load to continue. (Not loaded automatically.)
```
The same pages are in the [`docs/`](docs/) directory if you'd rather read them in the repo.

The nudge is skipped for continued (`resume`) or compacted sessions, and it checks that the handoff was written within `resume_nudge_max_age_hours` (default 24). Nothing is loaded automatically — the user must run `/nx-load` explicitly. Configure via `config.json`:
## License

```json
{
"resume_nudge_enabled": true,
"resume_nudge_max_age_hours": 24
}
```
Released under the [MIT License](LICENSE).
28 changes: 28 additions & 0 deletions docs/assets/banner.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
69 changes: 69 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Commands

nexum registers six slash commands inside Claude Code. Each is backed by a command definition in the `commands/` directory of the plugin.

## /nx-plan

Produce a step-by-step implementation plan for the current task, routing each step to the cheapest model that can execute it reliably.

Run `/nx-plan` with a description of your task. The planner (running on Opus) decomposes the work into self-contained steps, assigns each a route (`mechanical` → Haiku, `standard` → Sonnet, `needs-strong` → Opus), and writes the plan to `<data_dir>/plan/<session_id>.md`. Each step carries an explicit contract, file list, scope guard, and runnable acceptance test so a weaker model can execute it without additional context.

When the plan is written, the planner prints the path and a one-line summary of each step. Review the plan before running `/nx-build`.

## /nx-build

Execute a nexum plan file by dispatching steps to the cheapest capable model tier, verifying acceptance, and escalating on failure.

`/nx-build` reads the plan file for the current session, prints a projected cost preview (see below), then executes steps in tier order (mechanical → standard → needs-strong), batching where possible to reuse the warm model prefix. Each step is verified by running its acceptance command; a failing step is retried on the same tier and then escalated. Results are persisted to a step ledger so a restarted session resumes from where it left off rather than redoing completed steps.

### Cost preview

Before dispatching any steps, `/nx-build` prints a projected cost breakdown when `plan_preview_enabled` is true (the default):

```
[nexum] Plan cost preview (estimate)
Steps: 9 | Per-step heuristic: 8,000 in / 2,000 out tokens
Note: token counts are a per-step heuristic, not measured usage.

Tier Steps Input tok Output tok Actual $ Baseline $
--------------------------------------------------------------------
haiku 3 24,000 6,000 $0.0027 $0.0900
sonnet 5 40,000 10,000 $0.0600 $0.1500
opus 1 8,000 2,000 $0.0540 $0.0540
--------------------------------------------------------------------
TOTAL 9 72,000 18,000 $0.1167 $0.2940

Projected: $0.1167 vs all-opus $0.2940 — saves $0.1773 (60.3%)
```

The numbers are a per-step heuristic. Authoritative post-run totals — capturing prompt-cache writes/reads and actual token counts — come from the cost report printed after all steps complete.

Configure via `config.json`:

```json
{ "plan_preview_enabled": true }
```

## /nx-audit

Audit the current repo's Claude Code ignore configuration and flag noise files or directories that could blow context.

`/nx-audit` runs `scripts/audit.py` against the current working directory and summarizes findings: missing ignore files, unignored noise directories (`node_modules`, `.git`, `dist`, etc.), gaps between `.gitignore` and the Claude Code ignore file, and large or binary files that could consume context. After presenting findings it offers to apply recommended patterns with `--write` (idempotent — never duplicates patterns already present).

## /nx-status

Install the nexum session-usage status line into your Claude Code settings.

`/nx-status` presents the `statusLine` settings block and offers to merge it into your user-level (`~/.claude/settings.json`) or project-level (`.claude/settings.json`) settings. See [Status line](status-line.md) for details on what the status line displays and how to configure it.

## /nx-save

Write a session handoff so you can continue in a fresh session once a context or plan limit is near.

`/nx-save` gathers concrete facts about the current session — git branch and status, the stored task, decisions made, what has been verified — and writes a rich handoff to `<data_dir>/handoff/<session_id>.md` and `<data_dir>/handoff/latest.md`. A fresh session can then read `latest.md` directly, or run `/nx-load` to have nexum load and summarize it.

## /nx-load

Resume from the most recent session handoff written by `/nx-save` or the auto-handoff hook.

`/nx-load` reads `<data_dir>/handoff/latest.md`, checks its freshness and branch against the current git state, and summarizes the goal and next steps. It does not load a handoff automatically — the user must invoke it explicitly. If the actual git state contradicts the handoff notes, the discrepancy is surfaced rather than acted on silently.
Loading
Loading