contextpruner 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +98 -3
  2. package/dist/index.js +1055 -103
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -10,11 +10,20 @@ actually in your tree and reports:
10
10
  - **Dead** — rules that match nothing,
11
11
  - **Drift** — rules in one config but not another,
12
12
  - **Conflict** — rules that contradict each other, including an enforced rule
13
- that hard-blocks a file you pinned Keep or Skim.
13
+ that hard-blocks a file you pinned Keep or Skim, or a path you declared
14
+ `keep:` in `.contextpruner`.
14
15
 
15
16
  It exits non-zero when it finds issues, so it drops straight into CI or a
16
17
  pre-commit hook.
17
18
 
19
+ This CLI is the check side of a larger loop. At
20
+ [contextpruner.app](https://contextpruner.app) you can generate all nine
21
+ config files free in your browser — four of them enforced by the agent's own
22
+ harness as a best-effort block — and the $9/month automation regenerates all
23
+ nine on every push, with your account's usage dashboard showing what the last
24
+ sync cut. Lint is how you prove, locally or in CI, that the configs still
25
+ match your tree.
26
+
18
27
  ## Usage
19
28
 
20
29
  ```sh
@@ -43,8 +52,91 @@ contextpruner lint [--config <path>]... [--fix] [--json]
43
52
  safely.
44
53
  - `--json` — emit the full report as JSON.
45
54
 
55
+ If the repo root has a committed `.contextpruner` file, its
56
+ `keep: <path-or-glob>` lines (enforcement exceptions — paths that must stay
57
+ readable by agents, even untracked ones like docs inside `node_modules/`)
58
+ drop any enforced rule covering them from the expected rule set, exactly as
59
+ the generate automation does — so lint, `--fix`, and generation always agree.
60
+ A bare `prefer-tools` line (optionally `prefer-tools: true|on|yes`) is also
61
+ recognized — it turns on the runtime filter's "Prefer these tools" section
62
+ (written by `serve`, see below). Unrecognized lines are reported as a warning
63
+ and ignored.
64
+
46
65
  **Exit codes:** `0` clean · `1` issues found · `2` usage/auth error.
47
66
 
67
+ ## Filter search junk (`serve`)
68
+
69
+ ```sh
70
+ export CONTEXTPRUNER_API_KEY=cp_live_... # same key as lint
71
+ contextpruner serve
72
+ ```
73
+
74
+ `serve` (paid, same `cp_live_` key) installs shell shims for the common search
75
+ tools — `rg`, `grep`, `find`, `ls` — into `~/.contextpruner/bin`. Each shim runs
76
+ the real tool and pipes its output through ContextPruner, dropping junk paths
77
+ from broad fan-out results and printing a footer showing what it hid. When a
78
+ search actually pruned something, a savings note is also printed to stderr —
79
+ `contextpruner: this search — ~120 → ~30 tokens (~90 of junk pruned)` — so the
80
+ filtered results on stdout stay clean while you still see the tokens-per-turn
81
+ saving. The estimate is computed locally and never sent. `cat` gets
82
+ a passthrough shim (reading a named file is a pointed read, never filtered). It
83
+ verifies your key (no key or an invalid one exits `2`), writes the shims, and
84
+ prints the line to prepend to your `PATH`:
85
+
86
+ ```sh
87
+ export PATH="$HOME/.contextpruner/bin:$PATH"
88
+ ```
89
+
90
+ Once it's on the front of your `PATH`, broad `rg`/`grep`/`find`/`ls` searches
91
+ drop junk paths automatically. Set `CONTEXTPRUNER_ALL=1` to run a search
92
+ unfiltered. The shims are POSIX `sh` (macOS/Linux); Windows is not yet
93
+ supported.
94
+
95
+ After the shims, `serve` also writes (or merges into) each supported agent's
96
+ MCP config so an MCP-speaking agent — whose bundled search bypasses the `PATH`
97
+ shims — spawns ContextPruner's filtered-search server (`contextpruner __mcp`)
98
+ and gets the same junk-pruning through the `contextpruner_search` /
99
+ `contextpruner_glob` / `contextpruner_list` tools (pass `all: true` to see
100
+ everything). Claude Code's project `.mcp.json` is written unconditionally (the
101
+ proven target, and the generic project MCP config). The other three are
102
+ detection-gated — written only when that agent is in use here, so `serve` never
103
+ litters a config for an agent you don't have:
104
+
105
+ - **Cursor** — `.cursor/mcp.json` (project), when `.cursor/` exists.
106
+ - **Gemini CLI** — `.gemini/settings.json` (project), when `.gemini/` exists.
107
+ - **Windsurf** — `~/.codeium/mcp_config.json` (home; Windsurf has no
108
+ project-local MCP config), when `~/.codeium/` exists.
109
+
110
+ An undetected agent prints a one-line "not detected — re-run serve once it's set
111
+ up" hint. A fresh config file is created; an existing one is left untouched
112
+ except for splicing in the `contextpruner` server, preserving every other server
113
+ and key — and never overwritten if it can't be parsed safely (the note tells you
114
+ to add the server by hand). Restart the agent afterward, then prefer those tools
115
+ for broad searches.
116
+
117
+ Finally, `serve` marks the repo's `.contextpruner` file with a `prefer-tools`
118
+ directive (creating the file with a header if it doesn't exist, appending the
119
+ line if it does, or leaving it untouched if it's already there). **Commit it:**
120
+ the committed directive is what tells the config automation to add the "Prefer
121
+ these tools" section to your generated `AGENTS.md` / `CLAUDE.md` / etc., steering
122
+ agents toward the filtered tools. It's a committed marker — not local detection —
123
+ so the automation reads the same value locally and in CI and the section never
124
+ flip-flops.
125
+
126
+ ### Optional aggregate stats
127
+
128
+ The first time you run `serve` in an interactive terminal, it asks once whether
129
+ you'd share two aggregate numbers — how many files were assessed and how many
130
+ bytes were pruned — so we can show running totals on the website. **Only those
131
+ two integers are ever sent — never a path, never file contents.** A leading
132
+ `y`/`yes` opts in; anything else opts out, and a non-interactive or CI run is
133
+ never prompted and never sends. The answer is saved in
134
+ `~/.contextpruner/config.json`, so you're only asked once. If you opt in, each
135
+ filtered search adds to a local tally in `~/.contextpruner/stats.json`, and
136
+ `serve` flushes it best-effort — at most once a day — to `/api/stats/contribute`
137
+ with your `cp_live_` key. Opting out (or never being prompted) writes and sends
138
+ nothing.
139
+
48
140
  ## In CI
49
141
 
50
142
  Fail the build when a config drifts. Save this as
@@ -70,8 +162,11 @@ jobs:
70
162
  ## Privacy
71
163
 
72
164
  The pruning engine runs **entirely on your machine** — your file tree never
73
- leaves it. The only network call is to `/api/license/verify`, which sends just
74
- your API key to confirm an active subscription.
165
+ leaves it. `lint` makes a single network call, to `/api/license/verify`, which
166
+ sends just your API key to confirm an active subscription. The only other thing
167
+ that can ever leave your machine is the opt-in aggregate stats above: if — and
168
+ only if — you say yes at `serve`, two integers (files assessed, bytes pruned)
169
+ are POSTed to `/api/stats/contribute`. Never a path, never file contents.
75
170
 
76
171
  ## Development
77
172