feat: token efficiency system — 40-60% output reduction#40
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).
📝 WalkthroughWalkthroughThis PR introduces v3.2 with token-efficiency and anti-sycophancy guardrails, adds three new hook scripts for read-before-write validation and tool-call budgeting, and updates comprehensive documentation across rules and skills. Version bumped from 3.1.0 to 3.2.0 with expanded feature counts. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant PreToolUse as PreToolUse Hook
participant RBW as read-before-write.js
participant RRT as reread-tracker.js
participant TCB as tool-call-budget.js
participant SessionStore as Session State<br/>(tmpdir)
Client->>PreToolUse: Tool: Read(file_path)
PreToolUse->>RRT: stdin: file_path
RRT->>SessionStore: Check mtime vs last read
RRT-->>RRT: Increment counter if unchanged
RRT->>SessionStore: Update tracking JSON
PreToolUse->>RBW: stdin: file_path
RBW->>SessionStore: Record file as read
PreToolUse->>TCB: stdin: tool_call event
TCB->>SessionStore: Increment session counter
TCB-->>TCB: Warn at 80% threshold if needed
Client->>PreToolUse: Tool: Write(file_path)
PreToolUse->>RBW: stdin: file_path
RBW->>SessionStore: Verify file was read
RBW-->>RBW: Warn if not previously read
PreToolUse->>TCB: stdin: tool_call event
TCB->>SessionStore: Increment & check limits
TCB-->>TCB: Emit warning at boundaries
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)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ 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
| const sessionId = process.env.CLAUDE_SESSION_ID || String(process.ppid) || 'default'; | ||
| const tempDir = getTempDir(); | ||
| ensureDir(tempDir); | ||
|
|
||
| const readTrackFile = path.join(tempDir, `reads-${sessionId}.json`); | ||
|
|
There was a problem hiding this comment.
Sanitize sessionId before composing the tracker filename.
Using raw CLAUDE_SESSION_ID in the filename allows path traversal patterns and can write outside the intended temp folder.
Proposed fix
- const sessionId = process.env.CLAUDE_SESSION_ID || String(process.ppid) || 'default';
+ const rawSessionId = process.env.CLAUDE_SESSION_ID || String(process.ppid) || 'default';
+ const sessionId = rawSessionId.replace(/[^a-zA-Z0-9._-]/g, '_');📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const sessionId = process.env.CLAUDE_SESSION_ID || String(process.ppid) || 'default'; | |
| const tempDir = getTempDir(); | |
| ensureDir(tempDir); | |
| const readTrackFile = path.join(tempDir, `reads-${sessionId}.json`); | |
| const rawSessionId = process.env.CLAUDE_SESSION_ID || String(process.ppid) || 'default'; | |
| const sessionId = rawSessionId.replace(/[^a-zA-Z0-9._-]/g, '_'); | |
| const tempDir = getTempDir(); | |
| ensureDir(tempDir); | |
| const readTrackFile = path.join(tempDir, `reads-${sessionId}.json`); |
🤖 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 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.
|
|
||
| let input = ''; | ||
| try { | ||
| input = fs.readFileSync('/dev/stdin', 'utf8'); |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In Node.js, is fs.readFileSync('/dev/stdin', 'utf8')portable on Windows, and isfs.readFileSync(0, 'utf8') the recommended cross-platform alternative for CLI stdin?
💡 Result:
No, fs.readFileSync('/dev/stdin', 'utf8') is not portable on Windows because Windows lacks /dev/stdin; it results in ENOENT error. Yes, fs.readFileSync(0, 'utf8') works cross-platform as 0 is the POSIX stdin file descriptor (STDIN_FILENO) and functions on Windows too, reading entire stdin synchronously into a string. However, it is not the officially recommended approach for CLI stdin reading—Node.js docs emphasize streams via process.stdin or readline module for proper handling, especially since readFileSync assumes a seekable regular file (may fail to read complete stdin from pipes). For sync CLI tools wanting full stdin, this hack is commonly used despite caveats.
Citations:
- 1: https://stackoverflow.com/questions/8452957/synchronously-reading-stdin-in-windows/8452997
- 2: https://stackoverflow.com/questions/8452957/synchronously-reading-stdin-in-windows/27931290
- 3: https://nodejs.org/api/fs.html
- 4: fs.readFile[Sync]("/dev/stdin") does not always read the entire file. nodejs/node-v0.x-archive#7412
- 5: https://stackoverflow.com/questions/3430939/node-js-readsync-from-stdin
- 6: https://stackoverflow.com/questions/30441025/read-all-text-from-stdin-to-a-string
- 7: https://stackoverflow.com/questions/58520983/difference-of-fs-readfilesync-on-dev-stdin-or-process-stdin-fd
🏁 Script executed:
cat -n scripts/read-before-write.jsRepository: rohitg00/pro-workflow
Length of output: 2336
🏁 Script executed:
# Check for Windows references in project docs and CI
find . -type f \( -name "README*" -o -name "*.md" \) | head -5 | xargs grep -l -i "windows\|platform" 2>/dev/null || echo "No Windows references found in docs"
# Check for CI configuration
ls -la .github/workflows/ 2>/dev/null || echo "No GitHub workflows found"
# Check package.json for any platform hints
cat package.json 2>/dev/null | grep -A 2 -B 2 "windows\|platform" || echo "No platform hints in package.json"Repository: rohitg00/pro-workflow
Length of output: 428
🏁 Script executed:
cat -n .github/workflows/ci.ymlRepository: rohitg00/pro-workflow
Length of output: 2754
Use fd 0 instead of /dev/stdin for cross-platform stdin reads.
/dev/stdin is Unix-specific and fails with ENOENT on Windows. Use fs.readFileSync(0, 'utf8') to read stdin portably across Node.js-supported platforms.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/read-before-write.js` at 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.
| const filePath = toolInput.file_path || ''; | ||
| if (filePath) { | ||
| readFiles[filePath] = Date.now(); | ||
| fs.writeFileSync(readTrackFile, JSON.stringify(readFiles)); |
There was a problem hiding this comment.
Normalize file paths before tracking/comparison.
Current keying uses raw tool_input.file_path, so relative/absolute variants of the same file can produce false "not read" warnings.
Proposed fix
+function normalizeFilePath(filePath) {
+ return path.resolve(filePath);
+}
+
if (tool === 'Read') {
- const filePath = toolInput.file_path || '';
+ const filePath = toolInput.file_path ? normalizeFilePath(toolInput.file_path) : '';
if (filePath) {
readFiles[filePath] = Date.now();
fs.writeFileSync(readTrackFile, JSON.stringify(readFiles));
@@
if (tool === 'Write' || tool === 'Edit') {
- const filePath = toolInput.file_path || '';
+ const filePath = toolInput.file_path ? normalizeFilePath(toolInput.file_path) : '';Also applies to: 59-69
🤖 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 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.
| if (!modified) { | ||
| const readCount = (tracked[`${filePath}:count`] || 1) + 1; | ||
| tracked[`${filePath}:count`] = readCount; | ||
| if (readCount >= 2) { | ||
| console.error(`[TokenEfficiency] Re-reading ${path.basename(filePath)} (${readCount}x) — file unchanged since last read. Consider using cached knowledge.`); | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if other hook scripts in this repo enforce rules by exiting non-zero
# or if warn-only is the established pattern
rg -n 'process\.exit\([^0]' scripts/ || echo "No non-zero exits found - warn-only appears to be the pattern"Repository: rohitg00/pro-workflow
Length of output: 126
🏁 Script executed:
find . -name "SKILL.md" -o -name "skill.md" | head -20Repository: rohitg00/pro-workflow
Length of output: 695
🏁 Script executed:
# Also search for any documentation mentioning "Hard rules" or "Read-Before-Write"
rg -i "hard rule|read-before-write" --max-count=50Repository: rohitg00/pro-workflow
Length of output: 1005
🏁 Script executed:
cat skills/token-efficiency/SKILL.mdRepository: rohitg00/pro-workflow
Length of output: 4140
🏁 Script executed:
cat -n scripts/reread-tracker.jsRepository: rohitg00/pro-workflow
Length of output: 2410
Reconcile enforcement mechanism with "Hard rules" documentation.
The SKILL.md documentation explicitly labels Read-Before-Write rules as "Hard rules" under enforcement, yet reread-tracker.js only emits warnings via console.error and exits with code 0. The tool proceeds regardless of violations.
Decide: either update SKILL.md to reflect that these are guidelines/warnings rather than enforced rules, or implement actual enforcement by exiting with a non-zero code when violations are detected.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/reread-tracker.js` around lines 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.
| const thresholds = [ | ||
| { limit: 20, label: 'quick-fix budget (20 calls)' }, | ||
| { limit: 30, label: 'bug-fix budget (30 calls)' }, | ||
| { limit: 50, label: 'feature budget (50 calls)' }, | ||
| { limit: 80, label: 'large-feature budget (80 calls)' } | ||
| ]; | ||
|
|
||
| for (const t of thresholds) { | ||
| const warnAt = Math.floor(t.limit * 0.8); | ||
| if (count === warnAt) { | ||
| console.error(`[TokenEfficiency] ${count} tool calls — approaching ${t.label}. Consider wrapping up or compacting.`); | ||
| break; | ||
| } | ||
| if (count === t.limit) { | ||
| console.error(`[TokenEfficiency] ${count} tool calls — hit ${t.label}. Commit progress and assess remaining work.`); | ||
| break; | ||
| } | ||
| } |
There was a problem hiding this comment.
Documentation mismatch: "Wrap-Up At" thresholds differ from implementation.
The script calculates warnAt = Math.floor(limit * 0.8), yielding:
- 20 → 16, 30 → 24, 50 → 40, 80 → 64
However, skills/token-efficiency/SKILL.md documents "Wrap-Up At" as:
- 20 → 15, 30 → 25, 50 → 40, 80 → 65
The 15/25/65 values don't match the 80% formula. Either update the documentation to match the implementation (16/24/40/64) or adjust the thresholds array to use explicit warn values.
Proposed fix: Use explicit wrap-up values matching documentation
const thresholds = [
- { limit: 20, label: 'quick-fix budget (20 calls)' },
- { limit: 30, label: 'bug-fix budget (30 calls)' },
- { limit: 50, label: 'feature budget (50 calls)' },
- { limit: 80, label: 'large-feature budget (80 calls)' }
+ { limit: 20, warnAt: 15, label: 'quick-fix budget (20 calls)' },
+ { limit: 30, warnAt: 25, label: 'bug-fix budget (30 calls)' },
+ { limit: 50, warnAt: 40, label: 'feature budget (50 calls)' },
+ { limit: 80, warnAt: 65, label: 'large-feature budget (80 calls)' }
];
for (const t of thresholds) {
- const warnAt = Math.floor(t.limit * 0.8);
- if (count === warnAt) {
+ if (count === t.warnAt) {🤖 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 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(...)).
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
Release Notes - v3.2.0
New Features
/permission-tuner,/cost-tracker,/mcp-auditDocumentation