feat: token efficiency system — 40-60% output reduction#40
Conversation
- Add competitor comparison table (vs Superpowers, ECC, gstack, GSD) - Add What's New in v3.2 section with all new features - Add Tips from the Community section with attributed quotes - Add Related Projects section - Update all counts: 24 skills, 8 agents, 21 commands, 24 hook events - Expand all tables with new skills, agents, commands, and hooks - Update structure section with correct counts
- Fix ECC link: anthropics/courses (404) → affaan-m/everything-claude-code - Fix best-practice link: anthropics/courses (404) → shanraisshan/claude-code-best-practice - Fix competitor counts: ECC 143→140+, 71→60+; gstack 33→18+, 0→5+ - Add source links to competitor names in comparison table header
…s, one-pass discipline New skill, rule, and 3 hook scripts to reduce token waste by 40-60%: - rules/token-efficiency.mdc: anti-sycophancy, ASCII-only, read-before-write, one-pass coding, no re-reads, structured output preference - skills/token-efficiency/SKILL.md: comprehensive guide with task profiles (coding/agent/analysis), tool-call budget tiers, measuring impact - scripts/read-before-write.js: PreToolUse hook warns on Write/Edit without prior Read of the target file - scripts/reread-tracker.js: PreToolUse hook detects unnecessary re-reads of unchanged files - scripts/tool-call-budget.js: PreToolUse hook tracks call count against budget thresholds (20/30/50/80) with 80% warnings Updated existing files: - hooks/hooks.json: 3 new PreToolUse hooks (read-before-write, reread-tracker, tool-call-budget) - rules/core-rules.md: added token efficiency rules to Communication and Context - rules/communication-style.mdc: added anti-sycophancy and output reduction rules - rules/context-discipline.mdc: added one-pass discipline and tool-call budgets - skills/cost-tracker/SKILL.md: added tool-call budget table and 4 new strategies - skills/context-optimizer/SKILL.md: added Token Efficiency section with output reduction, behavioral efficiency, and task profiles Inspired by drona23/claude-token-efficient (MIT).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
📝 WalkthroughWalkthroughUpdated repo to v3.2: documentation and README refreshed (feature counts, new sections, new commands), added three session-tracking CLI scripts for read-before-write, re-read detection, and tool-call budgeting, extended hooks to invoke those scripts, and tightened rule/skill docs for token-efficiency and communication style. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant Hook as PreToolUse Hook
participant RBW as read-before-write.js
participant RRT as reread-tracker.js
participant TCB as tool-call-budget.js
participant Store as Session State (tmpdir)
Client->>Hook: Tool=Read(file_path)
Hook->>RRT: stdin: file_path
RRT->>Store: read mtime, counter
RRT-->>Hook: status (may exit non-zero if repeated)
Hook->>RBW: stdin: file_path
RBW->>Store: record read timestamp
Hook->>TCB: record tool call
TCB->>Store: increment session counter
TCB-->>Hook: warn/limit messages
Client->>Hook: Tool=Write(file_path)
Hook->>RBW: stdin: file_path
RBW->>Store: verify prior read
RBW-->>Hook: warn if not read
Hook->>TCB: record tool call
TCB->>Store: increment & check thresholds
TCB-->>Hook: warn/limit messages
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
skills/cost-tracker/SKILL.md (1)
51-59: Consider a single source of truth for budget tiers.This table duplicates the budget matrix in
skills/token-efficiency/SKILL.md; centralizing or cross-linking would prevent future drift between docs.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@skills/cost-tracker/SKILL.md` around lines 51 - 59, The budget matrix in the skills/cost-tracker/SKILL.md (the table with headers "Task Type | Tool-Call Budget | Wrap-Up At") duplicates the matrix in skills/token-efficiency/SKILL.md; create a single source of truth by removing the duplicated table from skills/cost-tracker/SKILL.md and replacing it with a clear cross-link to the canonical matrix (or move the canonical table into a new shared doc like skills/budget-tiers/SKILL.md), update any references to point to the chosen canonical location, and add a short comment in both SKILL.md files indicating where the authoritative budget tiers live so future edits only change one file.scripts/read-before-write.js (1)
40-54: Read tracking file updates are vulnerable to lost writes under concurrency.This read-modify-write cycle is not atomic; concurrent tool events can overwrite each other and drop tracked reads.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/read-before-write.js` around lines 40 - 54, The read-modify-write on readFiles/readTrackFile can lose concurrent updates; instead, when handling the 'Read' tool in the block that reads and writes readTrackFile, acquire an atomic update by re-reading the file immediately before write, merging the new entry by taking the max timestamp for the same filePath with any existing value, and then performing an atomic replace (write to a temp file and fs.rename to replace readTrackFile) so writes are atomic; optionally retry the read-merge-rename loop on conflict/errors to ensure concurrent updates are merged rather than overwritten.scripts/tool-call-budget.js (1)
49-51: Remove redundant hardcoded check for 65 calls.This check is inconsistent with the general threshold logic above:
- The loop already warns at 64 (80 * 0.8) for approaching the 80-call limit
- Then this fires separately at exactly 65 with a different message
This creates confusing back-to-back warnings at 64 and 65. If 65 is the intended wrap-up point for large features, integrate it into the thresholds array instead.
Proposed fix
- if (count === 65) { - console.error('[TokenEfficiency] 65 tool calls — approaching large-feature limit. Wrap up current task.'); - }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/tool-call-budget.js` around lines 49 - 51, Remove the hardcoded if (count === 65) console.error branch and instead add the 65-call wrap-up threshold into the existing thresholds array/logic used for warnings (the same mechanism that produced the 64 warning). Update the thresholds data (or threshold entries) to include an entry for 65 with the desired message ("[TokenEfficiency] 65 tool calls — approaching large-feature limit. Wrap up current task."), and ensure the loop that checks count against thresholds uses that entry so you no longer emit back-to-back 64/65 messages; reference the count variable and the thresholds array/threshold checking code where warnings are produced.scripts/reread-tracker.js (1)
24-28: Reading from/dev/stdinis not portable to Windows.This approach works on Linux and macOS but will fail on Windows. If Windows support is needed, consider using an event-based stdin read pattern like
scripts/worktree-create.js(context snippet 2).🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@scripts/reread-tracker.js` around lines 24 - 28, The code uses fs.readFileSync('/dev/stdin', 'utf8') which is not portable to Windows; replace the synchronous /dev/stdin read with an event-based read from process.stdin: remove the try/catch block around fs.readFileSync('/dev/stdin', 'utf8'), instead collect chunks on process.stdin 'data' events into the existing input variable and handle completion on the 'end' event (and call process.exit(0) if input is empty); ensure you keep the same surrounding logic that uses input so behavior remains unchanged (look for the input variable and the try/catch/process.exit(0) lines to update).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@scripts/read-before-write.js`:
- Around line 50-53: The code stores raw toolInput.file_path as the key in
readFiles causing duplicates for relative vs absolute paths; normalize paths
before using them by converting toolInput.file_path to a canonical form (e.g.,
use Node's path.resolve/path.normalize) and use that normalizedPath when
assigning readFiles[normalizedPath] and when later comparing or checking reads
(references: toolInput.file_path, readFiles, readTrackFile); apply the same
normalization logic to the other block mentioned (lines 59-69) so all lookups
and writes use the canonical path consistently.
- Around line 17-22: Sanitize the sessionId before using it in readTrackFile to
prevent path traversal: in the logic that builds sessionId (symbol: sessionId)
strip or replace any path separators and suspicious characters (e.g., slashes,
backslashes, "..") or restrict to a safe character class (alphanumeric,
dashes/underscores), and if the sanitized value is empty, fall back to a safe
default or a short hash; then construct readTrackFile with the sanitized
sessionId (symbols: readTrackFile, getTempDir, ensureDir) so filenames cannot
escape the tempDir.
- Line 25: The code reads stdin using fs.readFileSync('/dev/stdin', 'utf8'),
which is Unix-only and breaks on Windows; update the call to use the file
descriptor number instead: replace the '/dev/stdin' argument with 0 in the
fs.readFileSync call (the statement referencing input and fs.readFileSync) so it
becomes portable across Node.js-supported platforms.
In `@scripts/reread-tracker.js`:
- Around line 64-70: The current reread detection in reread-tracker.js (the
block using tracked[`${filePath}:count`], readCount, and filePath) only logs
errors and exits with code 0; update it to enforce the "Hard rules" by
terminating the process with a non-zero exit when readCount >= 2 (e.g., after
emitting the console.error call, call process.exit(1) or throw an Error) so
violations stop the tool, and ensure the error message mentions the rule and the
file name for clarity; alternatively, if you prefer warnings, update SKILL.md to
mark Read-Before-Write as guidance instead of "Hard rules"—but pick one approach
and implement it consistently.
In `@scripts/tool-call-budget.js`:
- Around line 30-47: The thresholds currently compute warnAt =
Math.floor(t.limit * 0.8) causing warn values (16,24,40,64) to differ from the
documented Wrap-Up At values (15,25,40,65); update the implementation to use
explicit warn values to match the docs by changing the thresholds array entries
(the thresholds constant) to include a warn property (e.g., { limit: 20, warn:
15, label: 'quick-fix budget (20 calls)' }) and replace the computed warnAt with
t.warn when comparing against count inside the loop (the logic around warnAt,
thresholds, and the count comparisons should reference t.warn instead of
Math.floor(...)).
---
Nitpick comments:
In `@scripts/read-before-write.js`:
- Around line 40-54: The read-modify-write on readFiles/readTrackFile can lose
concurrent updates; instead, when handling the 'Read' tool in the block that
reads and writes readTrackFile, acquire an atomic update by re-reading the file
immediately before write, merging the new entry by taking the max timestamp for
the same filePath with any existing value, and then performing an atomic replace
(write to a temp file and fs.rename to replace readTrackFile) so writes are
atomic; optionally retry the read-merge-rename loop on conflict/errors to ensure
concurrent updates are merged rather than overwritten.
In `@scripts/reread-tracker.js`:
- Around line 24-28: The code uses fs.readFileSync('/dev/stdin', 'utf8') which
is not portable to Windows; replace the synchronous /dev/stdin read with an
event-based read from process.stdin: remove the try/catch block around
fs.readFileSync('/dev/stdin', 'utf8'), instead collect chunks on process.stdin
'data' events into the existing input variable and handle completion on the
'end' event (and call process.exit(0) if input is empty); ensure you keep the
same surrounding logic that uses input so behavior remains unchanged (look for
the input variable and the try/catch/process.exit(0) lines to update).
In `@scripts/tool-call-budget.js`:
- Around line 49-51: Remove the hardcoded if (count === 65) console.error branch
and instead add the 65-call wrap-up threshold into the existing thresholds
array/logic used for warnings (the same mechanism that produced the 64 warning).
Update the thresholds data (or threshold entries) to include an entry for 65
with the desired message ("[TokenEfficiency] 65 tool calls — approaching
large-feature limit. Wrap up current task."), and ensure the loop that checks
count against thresholds uses that entry so you no longer emit back-to-back
64/65 messages; reference the count variable and the thresholds array/threshold
checking code where warnings are produced.
In `@skills/cost-tracker/SKILL.md`:
- Around line 51-59: The budget matrix in the skills/cost-tracker/SKILL.md (the
table with headers "Task Type | Tool-Call Budget | Wrap-Up At") duplicates the
matrix in skills/token-efficiency/SKILL.md; create a single source of truth by
removing the duplicated table from skills/cost-tracker/SKILL.md and replacing it
with a clear cross-link to the canonical matrix (or move the canonical table
into a new shared doc like skills/budget-tiers/SKILL.md), update any references
to point to the chosen canonical location, and add a short comment in both
SKILL.md files indicating where the authoritative budget tiers live so future
edits only change one file.
🪄 Autofix (Beta)
✅ Autofix completed
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 70788312-2e7a-4280-aeb5-beb119dda5f3
📒 Files selected for processing (13)
README.mdhooks/hooks.jsonpackage.jsonrules/communication-style.mdcrules/context-discipline.mdcrules/core-rules.mdrules/token-efficiency.mdcscripts/read-before-write.jsscripts/reread-tracker.jsscripts/tool-call-budget.jsskills/context-optimizer/SKILL.mdskills/cost-tracker/SKILL.mdskills/token-efficiency/SKILL.md
|
Hi, I noticed PR #40 is still open and wanted to ask whether there’s any plan to merge it, or if it’s currently blocked for some reason. |
|
Note Autofix is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it. Fixes Applied SuccessfullyFixed 4 file(s) based on 5 unresolved review comments. Files modified:
Commit: The changes have been pushed to the Time taken: |
Fixed 4 file(s) based on 5 unresolved review comments. Co-authored-by: CodeRabbit <noreply@coderabbit.ai>
Summary
What's New
New Files (5)
rules/token-efficiency.mdcskills/token-efficiency/SKILL.mdscripts/read-before-write.jsscripts/reread-tracker.jsscripts/tool-call-budget.jsUpdated Files (7)
hooks/hooks.jsonrules/core-rules.mdrules/communication-style.mdcrules/context-discipline.mdcskills/cost-tracker/SKILL.mdskills/context-optimizer/SKILL.mdpackage.jsonToken Efficiency Techniques
Output Reduction (40-60% savings):
Behavioral Efficiency:
Task Profiles:
Test plan
Summary by CodeRabbit
New Features
Documentation