rafcode 2.3.0 → 2.4.1-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 (129) hide show
  1. package/.claude/settings.local.json +3 -1
  2. package/CLAUDE.md +21 -4
  3. package/RAF/ahvrih-rate-forge/decisions.md +70 -0
  4. package/RAF/ahvrih-rate-forge/input.md +44 -0
  5. package/RAF/ahvrih-rate-forge/outcomes/01-remove-claude-command-config.md +58 -0
  6. package/RAF/ahvrih-rate-forge/outcomes/02-fix-mixed-attempt-cost.md +46 -0
  7. package/RAF/ahvrih-rate-forge/outcomes/03-rate-limit-estimation.md +82 -0
  8. package/RAF/ahvrih-rate-forge/outcomes/04-show-version-in-do-logs.md +45 -0
  9. package/RAF/ahvrih-rate-forge/outcomes/05-sync-main-before-worktree.md +96 -0
  10. package/RAF/ahvrih-rate-forge/outcomes/06-sync-readme-with-codebase.md +45 -0
  11. package/RAF/ahvrih-rate-forge/outcomes/07-no-session-persistence.md +26 -0
  12. package/RAF/ahvrih-rate-forge/outcomes/08-plan-execution-metadata.md +130 -0
  13. package/RAF/ahvrih-rate-forge/plans/01-remove-claude-command-config.md +36 -0
  14. package/RAF/ahvrih-rate-forge/plans/02-fix-mixed-attempt-cost.md +33 -0
  15. package/RAF/ahvrih-rate-forge/plans/03-rate-limit-estimation.md +82 -0
  16. package/RAF/ahvrih-rate-forge/plans/04-show-version-in-do-logs.md +32 -0
  17. package/RAF/ahvrih-rate-forge/plans/05-sync-main-before-worktree.md +40 -0
  18. package/RAF/ahvrih-rate-forge/plans/06-sync-readme-with-codebase.md +61 -0
  19. package/RAF/ahvrih-rate-forge/plans/07-no-session-persistence.md +28 -0
  20. package/RAF/ahvrih-rate-forge/plans/08-plan-execution-metadata.md +123 -0
  21. package/RAF/ahwidh-quick-fix-gremlin/decisions.md +37 -0
  22. package/RAF/ahwidh-quick-fix-gremlin/input.md +35 -0
  23. package/RAF/ahwidh-quick-fix-gremlin/outcomes/01-fix-name-generation-prompt.md +33 -0
  24. package/RAF/ahwidh-quick-fix-gremlin/outcomes/02-fix-amend-commit-scope.md +43 -0
  25. package/RAF/ahwidh-quick-fix-gremlin/outcomes/03-fix-diverged-main-branch-sync.md +32 -0
  26. package/RAF/ahwidh-quick-fix-gremlin/outcomes/04-wire-rate-limit-to-do-command.md +61 -0
  27. package/RAF/ahwidh-quick-fix-gremlin/outcomes/05-add-config-get-set-flags.md +125 -0
  28. package/RAF/ahwidh-quick-fix-gremlin/outcomes/06-sync-worktree-branch-before-execution.md +96 -0
  29. package/RAF/ahwidh-quick-fix-gremlin/outcomes/07-update-frontmatter-format.md +107 -0
  30. package/RAF/ahwidh-quick-fix-gremlin/outcomes/08-remove-plan-token-report.md +76 -0
  31. package/RAF/ahwidh-quick-fix-gremlin/plans/01-fix-name-generation-prompt.md +52 -0
  32. package/RAF/ahwidh-quick-fix-gremlin/plans/02-fix-amend-commit-scope.md +48 -0
  33. package/RAF/ahwidh-quick-fix-gremlin/plans/03-fix-diverged-main-branch-sync.md +49 -0
  34. package/RAF/ahwidh-quick-fix-gremlin/plans/04-wire-rate-limit-to-do-command.md +78 -0
  35. package/RAF/ahwidh-quick-fix-gremlin/plans/05-add-config-get-set-flags.md +101 -0
  36. package/RAF/ahwidh-quick-fix-gremlin/plans/06-sync-worktree-branch-before-execution.md +92 -0
  37. package/RAF/ahwidh-quick-fix-gremlin/plans/07-update-frontmatter-format.md +105 -0
  38. package/RAF/ahwidh-quick-fix-gremlin/plans/08-remove-plan-token-report.md +50 -0
  39. package/README.md +27 -7
  40. package/dist/commands/config.d.ts.map +1 -1
  41. package/dist/commands/config.js +209 -6
  42. package/dist/commands/config.js.map +1 -1
  43. package/dist/commands/do.d.ts.map +1 -1
  44. package/dist/commands/do.js +140 -21
  45. package/dist/commands/do.js.map +1 -1
  46. package/dist/commands/plan.d.ts.map +1 -1
  47. package/dist/commands/plan.js +27 -5
  48. package/dist/commands/plan.js.map +1 -1
  49. package/dist/core/claude-runner.d.ts +0 -6
  50. package/dist/core/claude-runner.d.ts.map +1 -1
  51. package/dist/core/claude-runner.js +4 -9
  52. package/dist/core/claude-runner.js.map +1 -1
  53. package/dist/core/failure-analyzer.d.ts.map +1 -1
  54. package/dist/core/failure-analyzer.js +3 -3
  55. package/dist/core/failure-analyzer.js.map +1 -1
  56. package/dist/core/pull-request.js +3 -3
  57. package/dist/core/pull-request.js.map +1 -1
  58. package/dist/core/state-derivation.d.ts +5 -0
  59. package/dist/core/state-derivation.d.ts.map +1 -1
  60. package/dist/core/state-derivation.js +14 -4
  61. package/dist/core/state-derivation.js.map +1 -1
  62. package/dist/core/worktree.d.ts +44 -0
  63. package/dist/core/worktree.d.ts.map +1 -1
  64. package/dist/core/worktree.js +247 -0
  65. package/dist/core/worktree.js.map +1 -1
  66. package/dist/prompts/amend.d.ts.map +1 -1
  67. package/dist/prompts/amend.js +28 -11
  68. package/dist/prompts/amend.js.map +1 -1
  69. package/dist/prompts/planning.d.ts.map +1 -1
  70. package/dist/prompts/planning.js +28 -11
  71. package/dist/prompts/planning.js.map +1 -1
  72. package/dist/types/config.d.ts +30 -13
  73. package/dist/types/config.d.ts.map +1 -1
  74. package/dist/types/config.js +14 -10
  75. package/dist/types/config.js.map +1 -1
  76. package/dist/utils/config.d.ts +47 -4
  77. package/dist/utils/config.d.ts.map +1 -1
  78. package/dist/utils/config.js +176 -30
  79. package/dist/utils/config.js.map +1 -1
  80. package/dist/utils/frontmatter.d.ts +53 -0
  81. package/dist/utils/frontmatter.d.ts.map +1 -0
  82. package/dist/utils/frontmatter.js +115 -0
  83. package/dist/utils/frontmatter.js.map +1 -0
  84. package/dist/utils/name-generator.d.ts.map +1 -1
  85. package/dist/utils/name-generator.js +9 -19
  86. package/dist/utils/name-generator.js.map +1 -1
  87. package/dist/utils/session-parser.d.ts +44 -0
  88. package/dist/utils/session-parser.d.ts.map +1 -0
  89. package/dist/utils/session-parser.js +122 -0
  90. package/dist/utils/session-parser.js.map +1 -0
  91. package/dist/utils/terminal-symbols.d.ts +22 -3
  92. package/dist/utils/terminal-symbols.d.ts.map +1 -1
  93. package/dist/utils/terminal-symbols.js +52 -18
  94. package/dist/utils/terminal-symbols.js.map +1 -1
  95. package/dist/utils/token-tracker.d.ts +20 -0
  96. package/dist/utils/token-tracker.d.ts.map +1 -1
  97. package/dist/utils/token-tracker.js +57 -2
  98. package/dist/utils/token-tracker.js.map +1 -1
  99. package/package.json +1 -1
  100. package/src/commands/config.ts +242 -7
  101. package/src/commands/do.ts +177 -23
  102. package/src/commands/plan.ts +27 -4
  103. package/src/core/claude-runner.ts +4 -16
  104. package/src/core/failure-analyzer.ts +3 -3
  105. package/src/core/pull-request.ts +3 -3
  106. package/src/core/state-derivation.ts +20 -4
  107. package/src/core/worktree.ts +266 -0
  108. package/src/prompts/amend.ts +28 -11
  109. package/src/prompts/config-docs.md +91 -29
  110. package/src/prompts/planning.ts +28 -11
  111. package/src/types/config.ts +46 -21
  112. package/src/utils/config.ts +200 -33
  113. package/src/utils/frontmatter.ts +140 -0
  114. package/src/utils/name-generator.ts +9 -19
  115. package/src/utils/terminal-symbols.ts +68 -16
  116. package/src/utils/token-tracker.ts +65 -2
  117. package/tests/unit/claude-runner-interactive.test.ts +8 -6
  118. package/tests/unit/claude-runner.test.ts +5 -66
  119. package/tests/unit/commit-planning-artifacts-worktree.test.ts +6 -14
  120. package/tests/unit/commit-planning-artifacts.test.ts +4 -12
  121. package/tests/unit/config-command.test.ts +176 -6
  122. package/tests/unit/config.test.ts +268 -45
  123. package/tests/unit/frontmatter.test.ts +276 -0
  124. package/tests/unit/name-generator.test.ts +1 -1
  125. package/tests/unit/post-execution-picker.test.ts +6 -0
  126. package/tests/unit/terminal-symbols.test.ts +142 -0
  127. package/tests/unit/token-tracker.test.ts +304 -1
  128. package/tests/unit/validation.test.ts +6 -4
  129. package/tests/unit/worktree.test.ts +309 -0
@@ -113,63 +113,94 @@ export function formatCost(cost) {
113
113
  return `$${cost.toFixed(4)}`;
114
114
  return `$${cost.toFixed(2)}`;
115
115
  }
116
+ /**
117
+ * Formats a rate limit percentage for display.
118
+ * Uses tilde (~) prefix to indicate estimate.
119
+ */
120
+ export function formatRateLimitPercentage(percentage) {
121
+ if (percentage === 0)
122
+ return '~0% of 5h window';
123
+ if (percentage < 0.1)
124
+ return `~${percentage.toFixed(2)}% of 5h window`;
125
+ if (percentage < 1)
126
+ return `~${percentage.toFixed(1)}% of 5h window`;
127
+ return `~${Math.round(percentage)}% of 5h window`;
128
+ }
116
129
  /**
117
130
  * Formats a single line of token usage (for a single attempt or total).
118
131
  * Used internally by formatTaskTokenSummary.
119
132
  */
120
- function formatTokenLine(usage, costValue, prefix = '', indent = ' ') {
133
+ function formatTokenLine(usage, costValue, prefix = '', indent = ' ', options = {}) {
134
+ const { showCacheTokens = true, showRateLimitEstimate = true, rateLimitPercentage } = options;
121
135
  const parts = [];
122
136
  const tokenPart = `${formatNumber(usage.inputTokens)} in / ${formatNumber(usage.outputTokens)} out`;
123
137
  parts.push(prefix ? `${prefix}: ${tokenPart}` : `Tokens: ${tokenPart}`);
124
- const cacheTotal = usage.cacheReadInputTokens + usage.cacheCreationInputTokens;
125
- if (cacheTotal > 0) {
126
- if (usage.cacheReadInputTokens > 0 && usage.cacheCreationInputTokens > 0) {
127
- parts.push(`Cache: ${formatNumber(usage.cacheReadInputTokens)} read / ${formatNumber(usage.cacheCreationInputTokens)} created`);
128
- }
129
- else if (usage.cacheReadInputTokens > 0) {
130
- parts.push(`Cache: ${formatNumber(usage.cacheReadInputTokens)} read`);
131
- }
132
- else {
133
- parts.push(`Cache: ${formatNumber(usage.cacheCreationInputTokens)} created`);
138
+ if (showCacheTokens) {
139
+ const cacheTotal = usage.cacheReadInputTokens + usage.cacheCreationInputTokens;
140
+ if (cacheTotal > 0) {
141
+ if (usage.cacheReadInputTokens > 0 && usage.cacheCreationInputTokens > 0) {
142
+ parts.push(`Cache: ${formatNumber(usage.cacheReadInputTokens)} read / ${formatNumber(usage.cacheCreationInputTokens)} created`);
143
+ }
144
+ else if (usage.cacheReadInputTokens > 0) {
145
+ parts.push(`Cache: ${formatNumber(usage.cacheReadInputTokens)} read`);
146
+ }
147
+ else {
148
+ parts.push(`Cache: ${formatNumber(usage.cacheCreationInputTokens)} created`);
149
+ }
134
150
  }
135
151
  }
136
152
  parts.push(`Est. cost: ${formatCost(costValue)}`);
153
+ if (showRateLimitEstimate && rateLimitPercentage !== undefined) {
154
+ parts.push(formatRateLimitPercentage(rateLimitPercentage));
155
+ }
137
156
  return `${indent}${parts.join(' | ')}`;
138
157
  }
139
158
  /**
140
159
  * Formats a per-task token usage summary.
141
- * For single-attempt tasks: " Tokens: 5,234 in / 1,023 out | Cache: 18,500 read | Est. cost: $0.42"
160
+ * For single-attempt tasks: " Tokens: 5,234 in / 1,023 out | Cache: 18,500 read | Est. cost: $0.42 | ~2% of 5h window"
142
161
  * For multi-attempt tasks: shows per-attempt breakdown plus total.
143
162
  *
144
163
  * @param entry - The TaskUsageEntry containing accumulated usage, cost, and attempts array
145
164
  * @param calculateAttemptCost - Optional function to calculate cost for a single attempt's UsageData
165
+ * @param options - Display options for showing cache tokens and rate limit percentage
146
166
  */
147
- export function formatTaskTokenSummary(entry, calculateAttemptCost) {
167
+ export function formatTaskTokenSummary(entry, calculateAttemptCost, options = {}) {
148
168
  // Single-attempt: render exactly as before (no per-attempt breakdown)
149
169
  if (entry.attempts.length <= 1) {
150
- return formatTokenLine(entry.usage, entry.cost.totalCost);
170
+ return formatTokenLine(entry.usage, entry.cost.totalCost, '', ' ', options);
151
171
  }
152
172
  // Multi-attempt: show per-attempt lines plus total
173
+ // Per-attempt lines don't show rate limit (only show on total)
174
+ const perAttemptOptions = {
175
+ ...options,
176
+ showRateLimitEstimate: false,
177
+ rateLimitPercentage: undefined,
178
+ };
153
179
  const lines = [];
154
180
  entry.attempts.forEach((attemptUsage, i) => {
155
181
  const attemptCost = calculateAttemptCost
156
182
  ? calculateAttemptCost(attemptUsage).totalCost
157
183
  : 0;
158
- lines.push(formatTokenLine(attemptUsage, attemptCost, `Attempt ${i + 1}`, ' '));
184
+ lines.push(formatTokenLine(attemptUsage, attemptCost, `Attempt ${i + 1}`, ' ', perAttemptOptions));
159
185
  });
160
- lines.push(formatTokenLine(entry.usage, entry.cost.totalCost, 'Total', ' '));
186
+ lines.push(formatTokenLine(entry.usage, entry.cost.totalCost, 'Total', ' ', options));
161
187
  return lines.join('\n');
162
188
  }
163
189
  /**
164
190
  * Formats the grand total token usage summary block.
165
191
  * Displayed after all tasks complete.
192
+ *
193
+ * @param usage - Total usage data
194
+ * @param cost - Total cost breakdown
195
+ * @param options - Display options for cache tokens and rate limit
166
196
  */
167
- export function formatTokenTotalSummary(usage, cost) {
197
+ export function formatTokenTotalSummary(usage, cost, options = {}) {
198
+ const { showCacheTokens = true, showRateLimitEstimate = true, rateLimitPercentage } = options;
168
199
  const lines = [];
169
200
  const divider = '── Token Usage Summary ──────────────────';
170
201
  lines.push(divider);
171
202
  lines.push(`Total tokens: ${formatNumber(usage.inputTokens)} in / ${formatNumber(usage.outputTokens)} out`);
172
- if (usage.cacheReadInputTokens > 0 || usage.cacheCreationInputTokens > 0) {
203
+ if (showCacheTokens && (usage.cacheReadInputTokens > 0 || usage.cacheCreationInputTokens > 0)) {
173
204
  const cacheParts = [];
174
205
  if (usage.cacheReadInputTokens > 0) {
175
206
  cacheParts.push(`${formatNumber(usage.cacheReadInputTokens)} read`);
@@ -180,6 +211,9 @@ export function formatTokenTotalSummary(usage, cost) {
180
211
  lines.push(`Cache: ${cacheParts.join(' / ')}`);
181
212
  }
182
213
  lines.push(`Estimated cost: ${formatCost(cost.totalCost)}`);
214
+ if (showRateLimitEstimate && rateLimitPercentage !== undefined) {
215
+ lines.push(formatRateLimitPercentage(rateLimitPercentage));
216
+ }
183
217
  lines.push('─────────────────────────────────────────');
184
218
  return lines.join('\n');
185
219
  }
@@ -1 +1 @@
1
- {"version":3,"file":"terminal-symbols.js","sourceRoot":"","sources":["../../src/utils/terminal-symbols.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"terminal-symbols.js","sourceRoot":"","sources":["../../src/utils/terminal-symbols.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,10 @@ export interface TaskUsageEntry {
17
17
  /** Raw per-attempt usage data (for display breakdowns). */
18
18
  attempts: UsageData[];
19
19
  }
20
+ /**
21
+ * Sum multiple CostBreakdown objects into a single total.
22
+ */
23
+ export declare function sumCostBreakdowns(costs: CostBreakdown[]): CostBreakdown;
20
24
  /**
21
25
  * Merge multiple UsageData objects into a single accumulated UsageData.
22
26
  * Sums all token fields and merges modelUsage maps.
@@ -33,6 +37,8 @@ export declare class TokenTracker {
33
37
  /**
34
38
  * Record usage data from a completed task.
35
39
  * Accepts an array of UsageData (one per attempt) and accumulates them.
40
+ * Cost is calculated per-attempt to avoid underreporting when some attempts
41
+ * have modelUsage and others only have aggregate fields.
36
42
  */
37
43
  addTask(taskId: string, attempts: UsageData[]): TaskUsageEntry;
38
44
  /**
@@ -51,5 +57,19 @@ export declare class TokenTracker {
51
57
  * Uses per-model breakdown when available, falls back to aggregate with sonnet pricing.
52
58
  */
53
59
  calculateCost(usage: UsageData): CostBreakdown;
60
+ /**
61
+ * Calculate the 5h rate limit window percentage for a given cost.
62
+ * Converts cost to Sonnet-equivalent tokens using the configured Sonnet pricing,
63
+ * then divides by the configured cap.
64
+ *
65
+ * @param totalCost - The total cost in dollars
66
+ * @param sonnetTokenCap - Optional override for the Sonnet-equivalent token cap (defaults to config value)
67
+ * @returns The percentage of the 5h window consumed (0-100+)
68
+ */
69
+ calculateRateLimitPercentage(totalCost: number, sonnetTokenCap?: number): number;
70
+ /**
71
+ * Get the cumulative 5h window percentage across all recorded tasks.
72
+ */
73
+ getCumulativeRateLimitPercentage(sonnetTokenCap?: number): number;
54
74
  }
55
75
  //# sourceMappingURL=token-tracker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-tracker.d.ts","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9D,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,EAAE,SAAS,CAAC;IACjB,4CAA4C;IAC5C,IAAI,EAAE,aAAa,CAAC;IACpB,2DAA2D;IAC3D,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,CA8BhE;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,aAAa,CAAC,EAAE,aAAa;IAIzC;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc;IAQ9D;;OAEG;IACH,UAAU,IAAI,SAAS,cAAc,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAE;IA6CtD;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa;CAkC/C"}
1
+ {"version":3,"file":"token-tracker.d.ts","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAG9D,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,KAAK,EAAE,SAAS,CAAC;IACjB,4CAA4C;IAC5C,IAAI,EAAE,aAAa,CAAC;IACpB,2DAA2D;IAC3D,QAAQ,EAAE,SAAS,EAAE,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,aAAa,CAkBvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,SAAS,CA8BhE;AAED;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAwB;IACvC,OAAO,CAAC,aAAa,CAAgB;gBAEzB,aAAa,CAAC,EAAE,aAAa;IAIzC;;;;;OAKG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc;IAW9D;;OAEG;IACH,UAAU,IAAI,SAAS,cAAc,EAAE;IAIvC;;OAEG;IACH,SAAS,IAAI;QAAE,KAAK,EAAE,SAAS,CAAC;QAAC,IAAI,EAAE,aAAa,CAAA;KAAE;IA6CtD;;;OAGG;IACH,aAAa,CAAC,KAAK,EAAE,SAAS,GAAG,aAAa;IAmC9C;;;;;;;;OAQG;IACH,4BAA4B,CAAC,SAAS,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;IAkBhF;;OAEG;IACH,gCAAgC,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,MAAM;CAIlE"}
@@ -1,4 +1,24 @@
1
- import { resolveModelPricingCategory, getPricingConfig } from './config.js';
1
+ import { resolveModelPricingCategory, getPricingConfig, getRateLimitWindowConfig } from './config.js';
2
+ /**
3
+ * Sum multiple CostBreakdown objects into a single total.
4
+ */
5
+ export function sumCostBreakdowns(costs) {
6
+ const result = {
7
+ inputCost: 0,
8
+ outputCost: 0,
9
+ cacheReadCost: 0,
10
+ cacheCreateCost: 0,
11
+ totalCost: 0,
12
+ };
13
+ for (const cost of costs) {
14
+ result.inputCost += cost.inputCost;
15
+ result.outputCost += cost.outputCost;
16
+ result.cacheReadCost += cost.cacheReadCost;
17
+ result.cacheCreateCost += cost.cacheCreateCost;
18
+ result.totalCost += cost.totalCost;
19
+ }
20
+ return result;
21
+ }
2
22
  /**
3
23
  * Merge multiple UsageData objects into a single accumulated UsageData.
4
24
  * Sums all token fields and merges modelUsage maps.
@@ -45,10 +65,15 @@ export class TokenTracker {
45
65
  /**
46
66
  * Record usage data from a completed task.
47
67
  * Accepts an array of UsageData (one per attempt) and accumulates them.
68
+ * Cost is calculated per-attempt to avoid underreporting when some attempts
69
+ * have modelUsage and others only have aggregate fields.
48
70
  */
49
71
  addTask(taskId, attempts) {
50
72
  const usage = accumulateUsage(attempts);
51
- const cost = this.calculateCost(usage);
73
+ // Calculate cost per-attempt, then sum. This ensures attempts with only
74
+ // aggregate fields use sonnet fallback pricing independently.
75
+ const perAttemptCosts = attempts.map((attempt) => this.calculateCost(attempt));
76
+ const cost = sumCostBreakdowns(perAttemptCosts);
52
77
  const entry = { taskId, usage, cost, attempts };
53
78
  this.entries.push(entry);
54
79
  return entry;
@@ -138,5 +163,35 @@ export class TokenTracker {
138
163
  result.totalCost = result.inputCost + result.outputCost + result.cacheReadCost + result.cacheCreateCost;
139
164
  return result;
140
165
  }
166
+ /**
167
+ * Calculate the 5h rate limit window percentage for a given cost.
168
+ * Converts cost to Sonnet-equivalent tokens using the configured Sonnet pricing,
169
+ * then divides by the configured cap.
170
+ *
171
+ * @param totalCost - The total cost in dollars
172
+ * @param sonnetTokenCap - Optional override for the Sonnet-equivalent token cap (defaults to config value)
173
+ * @returns The percentage of the 5h window consumed (0-100+)
174
+ */
175
+ calculateRateLimitPercentage(totalCost, sonnetTokenCap) {
176
+ if (totalCost === 0)
177
+ return 0;
178
+ // Get the configured cap or use the provided override
179
+ const cap = sonnetTokenCap ?? getRateLimitWindowConfig().sonnetTokenCap;
180
+ // Calculate the average Sonnet cost per token
181
+ // Using the average of input and output pricing (simplified approach)
182
+ const sonnetPricing = this.pricingConfig.sonnet;
183
+ const avgSonnetCostPerToken = (sonnetPricing.inputPerMTok + sonnetPricing.outputPerMTok) / 2 / 1_000_000;
184
+ // Convert cost to Sonnet-equivalent tokens
185
+ const sonnetEquivalentTokens = totalCost / avgSonnetCostPerToken;
186
+ // Calculate percentage
187
+ return (sonnetEquivalentTokens / cap) * 100;
188
+ }
189
+ /**
190
+ * Get the cumulative 5h window percentage across all recorded tasks.
191
+ */
192
+ getCumulativeRateLimitPercentage(sonnetTokenCap) {
193
+ const totals = this.getTotals();
194
+ return this.calculateRateLimitPercentage(totals.cost.totalCost, sonnetTokenCap);
195
+ }
141
196
  }
142
197
  //# sourceMappingURL=token-tracker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"token-tracker.js","sourceRoot":"","sources":["../../src/utils/token-tracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,2BAA2B,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAC;AAsBtG;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB;IACtD,MAAM,MAAM,GAAkB;QAC5B,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,CAAC;QACb,aAAa,EAAE,CAAC;QAChB,eAAe,EAAE,CAAC;QAClB,SAAS,EAAE,CAAC;KACb,CAAC;IAEF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QACnC,MAAM,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC;QACrC,MAAM,CAAC,aAAa,IAAI,IAAI,CAAC,aAAa,CAAC;QAC3C,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC;QAC/C,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;IACrC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,QAAqB;IACnD,MAAM,MAAM,GAAc;QACxB,WAAW,EAAE,CAAC;QACd,YAAY,EAAE,CAAC;QACf,oBAAoB,EAAE,CAAC;QACvB,wBAAwB,EAAE,CAAC;QAC3B,UAAU,EAAE,EAAE;KACf,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;QAC1C,MAAM,CAAC,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;QAC5C,MAAM,CAAC,oBAAoB,IAAI,OAAO,CAAC,oBAAoB,CAAC;QAC5D,MAAM,CAAC,wBAAwB,IAAI,OAAO,CAAC,wBAAwB,CAAC;QAEpE,wBAAwB;QACxB,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACvE,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACb,QAAQ,CAAC,WAAW,IAAI,UAAU,CAAC,WAAW,CAAC;gBAC/C,QAAQ,CAAC,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC;gBACjD,QAAQ,CAAC,oBAAoB,IAAI,UAAU,CAAC,oBAAoB,CAAC;gBACjE,QAAQ,CAAC,wBAAwB,IAAI,UAAU,CAAC,wBAAwB,CAAC;YAC3E,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC;YACjD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,OAAO,GAAqB,EAAE,CAAC;IAC/B,aAAa,CAAgB;IAErC,YAAY,aAA6B;QACvC,IAAI,CAAC,aAAa,GAAG,aAAa,IAAI,gBAAgB,EAAE,CAAC;IAC3D,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,MAAc,EAAE,QAAqB;QAC3C,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxC,wEAAwE;QACxE,8DAA8D;QAC9D,MAAM,eAAe,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAC/E,MAAM,IAAI,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;QAChD,MAAM,KAAK,GAAmB,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,SAAS;QACP,MAAM,UAAU,GAAc;YAC5B,WAAW,EAAE,CAAC;YACd,YAAY,EAAE,CAAC;YACf,oBAAoB,EAAE,CAAC;YACvB,wBAAwB,EAAE,CAAC;YAC3B,UAAU,EAAE,EAAE;SACf,CAAC;QACF,MAAM,SAAS,GAAkB;YAC/B,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,aAAa,EAAE,CAAC;YAChB,eAAe,EAAE,CAAC;YAClB,SAAS,EAAE,CAAC;SACb,CAAC;QAEF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,UAAU,CAAC,WAAW,IAAI,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC;YAClD,UAAU,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC;YACpD,UAAU,CAAC,oBAAoB,IAAI,KAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC;YACpE,UAAU,CAAC,wBAAwB,IAAI,KAAK,CAAC,KAAK,CAAC,wBAAwB,CAAC;YAE5E,wBAAwB;YACxB,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC3E,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAChD,IAAI,QAAQ,EAAE,CAAC;oBACb,QAAQ,CAAC,WAAW,IAAI,UAAU,CAAC,WAAW,CAAC;oBAC/C,QAAQ,CAAC,YAAY,IAAI,UAAU,CAAC,YAAY,CAAC;oBACjD,QAAQ,CAAC,oBAAoB,IAAI,UAAU,CAAC,oBAAoB,CAAC;oBACjE,QAAQ,CAAC,wBAAwB,IAAI,UAAU,CAAC,wBAAwB,CAAC;gBAC3E,CAAC;qBAAM,CAAC;oBACN,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC;gBACrD,CAAC;YACH,CAAC;YAED,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;YAC5C,SAAS,CAAC,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;YAC9C,SAAS,CAAC,aAAa,IAAI,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC;YACpD,SAAS,CAAC,eAAe,IAAI,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC;YACxD,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;QAC9C,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAChD,CAAC;IAED;;;OAGG;IACH,aAAa,CAAC,KAAgB;QAC5B,MAAM,MAAM,GAAkB;YAC5B,SAAS,EAAE,CAAC;YACZ,UAAU,EAAE,CAAC;YACb,aAAa,EAAE,CAAC;YAChB,eAAe,EAAE,CAAC;YAClB,SAAS,EAAE,CAAC;SACb,CAAC;QAEF,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAEtD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,+CAA+C;YAC/C,KAAK,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,IAAI,YAAY,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,2BAA2B,CAAC,OAAO,CAAC,CAAC;gBACtD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,QAAQ,IAAI,QAAQ,CAAC,CAAC;gBAEzD,MAAM,CAAC,SAAS,IAAI,CAAC,UAAU,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;gBAChF,MAAM,CAAC,UAAU,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;gBACnF,MAAM,CAAC,aAAa,IAAI,CAAC,UAAU,CAAC,oBAAoB,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC;gBACjG,MAAM,CAAC,eAAe,IAAI,CAAC,UAAU,CAAC,wBAAwB,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAC3G,CAAC;QACH,CAAC;aAAM,CAAC;YACN,qDAAqD;YACrD,MAAM,OAAO,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;YAC1C,MAAM,CAAC,SAAS,GAAG,CAAC,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;YAC1E,MAAM,CAAC,UAAU,GAAG,CAAC,KAAK,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;YAC7E,MAAM,CAAC,aAAa,GAAG,CAAC,KAAK,CAAC,oBAAoB,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC;YAC3F,MAAM,CAAC,eAAe,GAAG,CAAC,KAAK,CAAC,wBAAwB,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrG,CAAC;QAED,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,aAAa,GAAG,MAAM,CAAC,eAAe,CAAC;QACxG,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;;;;;OAQG;IACH,4BAA4B,CAAC,SAAiB,EAAE,cAAuB;QACrE,IAAI,SAAS,KAAK,CAAC;YAAE,OAAO,CAAC,CAAC;QAE9B,sDAAsD;QACtD,MAAM,GAAG,GAAG,cAAc,IAAI,wBAAwB,EAAE,CAAC,cAAc,CAAC;QAExE,8CAA8C;QAC9C,sEAAsE;QACtE,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC;QAChD,MAAM,qBAAqB,GAAG,CAAC,aAAa,CAAC,YAAY,GAAG,aAAa,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;QAEzG,2CAA2C;QAC3C,MAAM,sBAAsB,GAAG,SAAS,GAAG,qBAAqB,CAAC;QAEjE,uBAAuB;QACvB,OAAO,CAAC,sBAAsB,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC;IAC9C,CAAC;IAED;;OAEG;IACH,gCAAgC,CAAC,cAAuB;QACtD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC,4BAA4B,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAClF,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rafcode",
3
- "version": "2.3.0",
3
+ "version": "2.4.1-0",
4
4
  "description": "Automated Task Planning & Execution with Claude Code",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,16 +9,20 @@ import { logger } from '../utils/logger.js';
9
9
  import {
10
10
  getConfigPath,
11
11
  getModel,
12
- getEffort,
13
12
  getModelShortName,
14
13
  validateConfig,
15
14
  ConfigValidationError,
16
15
  resetConfigCache,
16
+ resolveConfig,
17
+ saveConfig,
17
18
  } from '../utils/config.js';
18
19
  import { DEFAULT_CONFIG } from '../types/config.js';
20
+ import type { UserConfig } from '../types/config.js';
19
21
 
20
22
  interface ConfigCommandOptions {
21
23
  reset?: boolean;
24
+ get?: true | string; // true when --get with no key, string when --get <key>
25
+ set?: string[]; // [key, value]
22
26
  }
23
27
 
24
28
  /**
@@ -115,17 +119,254 @@ async function confirm(message: string): Promise<boolean> {
115
119
  });
116
120
  }
117
121
 
122
+ // ---- Helper functions for nested config access ----
123
+
124
+ /**
125
+ * Get a nested value from an object using dot notation.
126
+ * Returns undefined if the path doesn't exist.
127
+ */
128
+ function getNestedValue(obj: unknown, dotPath: string): unknown {
129
+ const keys = dotPath.split('.');
130
+ let current: unknown = obj;
131
+
132
+ for (const key of keys) {
133
+ if (current === null || typeof current !== 'object') {
134
+ return undefined;
135
+ }
136
+ current = (current as Record<string, unknown>)[key];
137
+ }
138
+
139
+ return current;
140
+ }
141
+
142
+ /**
143
+ * Set a nested value in an object using dot notation.
144
+ * Creates intermediate objects as needed.
145
+ */
146
+ function setNestedValue(obj: Record<string, unknown>, dotPath: string, value: unknown): void {
147
+ const keys = dotPath.split('.');
148
+ let current: Record<string, unknown> = obj;
149
+
150
+ for (let i = 0; i < keys.length - 1; i++) {
151
+ const key = keys[i]!;
152
+ if (!(key in current) || typeof current[key] !== 'object' || current[key] === null) {
153
+ current[key] = {};
154
+ }
155
+ current = current[key] as Record<string, unknown>;
156
+ }
157
+
158
+ const lastKey = keys[keys.length - 1]!;
159
+ current[lastKey] = value;
160
+ }
161
+
162
+ /**
163
+ * Delete a nested value from an object using dot notation.
164
+ * Cleans up empty parent objects after deletion.
165
+ */
166
+ function deleteNestedValue(obj: Record<string, unknown>, dotPath: string): void {
167
+ const keys = dotPath.split('.');
168
+
169
+ // Navigate to parent and delete the key
170
+ if (keys.length === 1) {
171
+ delete obj[keys[0]!];
172
+ return;
173
+ }
174
+
175
+ // Build path to parent
176
+ let current: Record<string, unknown> = obj;
177
+ const path: Array<{ obj: Record<string, unknown>; key: string }> = [];
178
+
179
+ for (let i = 0; i < keys.length - 1; i++) {
180
+ const key = keys[i]!;
181
+ path.push({ obj: current, key });
182
+
183
+ if (typeof current[key] !== 'object' || current[key] === null) {
184
+ return; // Path doesn't exist
185
+ }
186
+ current = current[key] as Record<string, unknown>;
187
+ }
188
+
189
+ // Delete the leaf value
190
+ const lastKey = keys[keys.length - 1]!;
191
+ delete current[lastKey];
192
+
193
+ // Clean up empty parents
194
+ for (let i = path.length - 1; i >= 0; i--) {
195
+ const { obj, key } = path[i]!;
196
+ const child = obj[key] as Record<string, unknown>;
197
+ if (Object.keys(child).length === 0) {
198
+ delete obj[key];
199
+ } else {
200
+ break; // Stop if we find a non-empty parent
201
+ }
202
+ }
203
+ }
204
+
205
+ /**
206
+ * Get the default value at a dot-notation path from DEFAULT_CONFIG.
207
+ */
208
+ function getDefaultValue(dotPath: string): unknown {
209
+ return getNestedValue(DEFAULT_CONFIG, dotPath);
210
+ }
211
+
212
+ /**
213
+ * Parse a string value, attempting JSON.parse for numbers/booleans, falling back to string.
214
+ */
215
+ function parseValue(value: string): unknown {
216
+ // Try JSON.parse for numbers, booleans, null
217
+ try {
218
+ return JSON.parse(value);
219
+ } catch {
220
+ // Fall back to string
221
+ return value;
222
+ }
223
+ }
224
+
225
+ /**
226
+ * Format a value for console output.
227
+ * Strings are printed plain, objects/arrays as JSON.
228
+ */
229
+ function formatValue(value: unknown): string {
230
+ if (typeof value === 'string') {
231
+ return value;
232
+ }
233
+ if (typeof value === 'number' || typeof value === 'boolean') {
234
+ return String(value);
235
+ }
236
+ if (value === null || value === undefined) {
237
+ return String(value);
238
+ }
239
+ return JSON.stringify(value, null, 2);
240
+ }
241
+
242
+ // ---- Config get/set handlers ----
243
+
244
+ /**
245
+ * Handle --get flag: print config value(s).
246
+ */
247
+ function handleGet(key: true | string): void {
248
+ const config = resolveConfig();
249
+
250
+ if (key === true) {
251
+ // No key specified: print full config
252
+ console.log(JSON.stringify(config, null, 2));
253
+ return;
254
+ }
255
+
256
+ // Specific key requested
257
+ const value = getNestedValue(config, key);
258
+
259
+ if (value === undefined) {
260
+ logger.error(`Config key not found: ${key}`);
261
+ process.exit(1);
262
+ }
263
+
264
+ console.log(formatValue(value));
265
+ }
266
+
267
+ /**
268
+ * Handle --set flag: update config file with a new value.
269
+ */
270
+ function handleSet(args: string[]): void {
271
+ if (args.length !== 2) {
272
+ logger.error('--set requires exactly 2 arguments: key and value');
273
+ process.exit(1);
274
+ }
275
+
276
+ const [key, rawValue] = args as [string, string];
277
+ const value = parseValue(rawValue);
278
+ const configPath = getConfigPath();
279
+
280
+ // Read current user config (or start with empty)
281
+ let userConfig: UserConfig = {};
282
+ if (fs.existsSync(configPath)) {
283
+ try {
284
+ const content = fs.readFileSync(configPath, 'utf-8');
285
+ userConfig = JSON.parse(content) as UserConfig;
286
+ } catch (error) {
287
+ logger.error(`Failed to read config file: ${error}`);
288
+ process.exit(1);
289
+ }
290
+ }
291
+
292
+ // Check if value matches default
293
+ const defaultValue = getDefaultValue(key);
294
+
295
+ if (defaultValue === undefined) {
296
+ logger.error(`Config key not found in schema: ${key}`);
297
+ process.exit(1);
298
+ }
299
+
300
+ // Deep equality check for objects
301
+ const valuesMatch = JSON.stringify(value) === JSON.stringify(defaultValue);
302
+
303
+ if (valuesMatch) {
304
+ // Remove from config file (keep config minimal)
305
+ deleteNestedValue(userConfig as Record<string, unknown>, key);
306
+ logger.info(`Value matches default, removing ${key} from config`);
307
+ } else {
308
+ // Set the value
309
+ setNestedValue(userConfig as Record<string, unknown>, key, value);
310
+ logger.info(`Set ${key} = ${formatValue(value)}`);
311
+ }
312
+
313
+ // Validate the resulting config
314
+ try {
315
+ validateConfig(userConfig);
316
+ } catch (error) {
317
+ if (error instanceof ConfigValidationError) {
318
+ logger.error(`Validation error: ${error.message}`);
319
+ process.exit(1);
320
+ }
321
+ throw error;
322
+ }
323
+
324
+ // Save or delete config file
325
+ if (Object.keys(userConfig).length === 0) {
326
+ // Config is empty, delete the file
327
+ if (fs.existsSync(configPath)) {
328
+ fs.unlinkSync(configPath);
329
+ logger.info('Config is empty, removed file');
330
+ }
331
+ } else {
332
+ saveConfig(configPath, userConfig);
333
+ logger.success('Config updated successfully');
334
+ }
335
+ }
336
+
118
337
  export function createConfigCommand(): Command {
119
338
  const command = new Command('config')
120
339
  .description('View and edit RAF configuration with Claude')
121
340
  .argument('[prompt...]', 'Optional initial prompt for the config session')
122
341
  .option('--reset', 'Delete config file and restore all defaults')
342
+ .option('--get [key]', 'Show config value (all config if no key, or specific dot-notation key)')
343
+ .option('--set <items...>', 'Set a config value using dot-notation key and value')
123
344
  .action(async (promptParts: string[], options: ConfigCommandOptions) => {
345
+ // --reset takes precedence
124
346
  if (options.reset) {
125
347
  await handleReset();
126
348
  return;
127
349
  }
128
350
 
351
+ // --get and --set are mutually exclusive
352
+ if (options.get !== undefined && options.set !== undefined) {
353
+ logger.error('Cannot use --get and --set together');
354
+ process.exit(1);
355
+ }
356
+
357
+ // Handle --get
358
+ if (options.get !== undefined) {
359
+ handleGet(options.get);
360
+ return;
361
+ }
362
+
363
+ // Handle --set
364
+ if (options.set !== undefined) {
365
+ handleSet(options.set);
366
+ return;
367
+ }
368
+
369
+ // Default: run interactive session
129
370
  const initialPrompt = promptParts.length > 0 ? promptParts.join(' ') : undefined;
130
371
  await runConfigSession(initialPrompt);
131
372
  });
@@ -160,17 +401,14 @@ async function runConfigSession(initialPrompt?: string): Promise<void> {
160
401
  // Try to load config, but fall back to defaults if it's broken
161
402
  // This allows raf config to be used to fix a broken config file
162
403
  let model: string;
163
- let effort: string;
164
404
  let configError: Error | null = null;
165
405
 
166
406
  try {
167
407
  model = getModel('config');
168
- effort = getEffort('config');
169
408
  } catch (error) {
170
409
  // Config file has errors - fall back to defaults so the session can launch
171
410
  configError = error instanceof Error ? error : new Error(String(error));
172
411
  model = DEFAULT_CONFIG.models.config;
173
- effort = DEFAULT_CONFIG.effort.config;
174
412
  // Clear the cached config so subsequent calls don't use the broken cache
175
413
  resetConfigCache();
176
414
  }
@@ -182,9 +420,6 @@ async function runConfigSession(initialPrompt?: string): Promise<void> {
182
420
  logger.newline();
183
421
  }
184
422
 
185
- // Set effort level env var for the Claude session
186
- process.env['CLAUDE_CODE_EFFORT_LEVEL'] = effort;
187
-
188
423
  // Load config docs
189
424
  let configDocs: string;
190
425
  try {