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
@@ -68,9 +68,12 @@ After interviewing the user about all tasks, create plan files in the plans fold
68
68
  - ${projectPath}/plans/02-task-name.md
69
69
  - etc.
70
70
 
71
- Each plan file should follow this structure:
71
+ Each plan file MUST have Obsidian-style frontmatter at the top, before the \`# Task:\` heading. The frontmatter uses standard YAML format with opening and closing \`---\` delimiters:
72
72
 
73
73
  \`\`\`markdown
74
+ ---
75
+ effort: medium
76
+ ---
74
77
  # Task: [Task Name]
75
78
 
76
79
  ## Objective
@@ -105,6 +108,24 @@ Each plan file should follow this structure:
105
108
  [Any additional context, warnings, or considerations]
106
109
  \`\`\`
107
110
 
111
+ ### Frontmatter Requirements
112
+
113
+ The \`effort\` field is REQUIRED in every plan file. It indicates task complexity and determines which Claude model will execute the task:
114
+ - \`effort: low\` — Trivial/mechanical changes, simple one-file edits, config changes
115
+ - \`effort: medium\` — Well-scoped feature work, bug fixes with clear plans, multi-file changes following existing patterns
116
+ - \`effort: high\` — Architectural changes, complex logic, tasks requiring deep codebase understanding
117
+
118
+ Optionally, you can add an explicit \`model\` field to override the effort-based model selection:
119
+ \`\`\`markdown
120
+ ---
121
+ effort: medium
122
+ model: opus
123
+ ---
124
+ # Task: ...
125
+ \`\`\`
126
+
127
+ This is rarely needed — prefer using the \`effort\` label so the user's config controls the actual model used.
128
+
108
129
  ### Step 4: Infer Task Dependencies
109
130
 
110
131
  For each task, analyze which other tasks must complete successfully before it can begin. Add a \`## Dependencies\` section to plan files that have prerequisites.
@@ -154,19 +175,15 @@ Planning complete! To exit this session and run your tasks:
154
175
  6. Only add Dependencies section when a task genuinely requires another to complete first
155
176
  7. Dependencies must only reference lower-numbered tasks to prevent circular dependencies
156
177
  8. Be specific - vague plans lead to poor execution
178
+ 9. ALWAYS include the \`effort\` frontmatter field in every plan file — assess each task's complexity
157
179
 
158
180
  ## Plan Output Style
159
181
 
160
- **CRITICAL**: Plans should be HIGH-LEVEL and CONCEPTUAL:
161
- - Describe WHAT needs to be done, not HOW to code it
162
- - Focus on architecture, data flow, and component interactions
163
- - NO code snippets or implementation details in plans
164
- - File paths ARE acceptable when referencing:
165
- - Existing project files to modify
166
- - Previous plan/outcome files for context
167
- - Project structure and directories
168
- - Let the executing agent decide implementation specifics
169
- - Plans guide the work; they don't prescribe exact code`;
182
+ Plans can include whatever level of detail you deem helpful for the executing agent. Use your judgment:
183
+ - Include implementation details when they clarify the approach
184
+ - Code snippets are acceptable when they help illustrate a specific pattern
185
+ - File paths are helpful when referencing existing project files, patterns, or directories
186
+ - Focus on clarity the goal is for the executing agent to understand what needs to be done`;
170
187
  const userMessage = `Here is my project description:
171
188
 
172
189
  ${params.inputContent}
@@ -1 +1 @@
1
- {"version":3,"file":"planning.js","sourceRoot":"","sources":["../../src/prompts/planning.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA4B;IAC5D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvD,MAAM,YAAY,GAAG;;;;;;;;;;kBAUL,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BzB,WAAW;;;;;;;;;;;;;;;;;;IAkBX,WAAW;IACX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA4EkB,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;wDAyBW,CAAC;IAEvD,MAAM,WAAW,GAAG;;EAEpB,MAAM,CAAC,YAAY;;sDAEiC,CAAC;IAErD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"planning.js","sourceRoot":"","sources":["../../src/prompts/planning.ts"],"names":[],"mappings":"AAWA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA4B;IAC5D,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAC7C,MAAM,YAAY,GAAG,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;IAEvD,MAAM,YAAY,GAAG;;;;;;;;;;kBAUL,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BzB,WAAW;;;;;;;;;;;;;;;;;;IAkBX,WAAW;IACX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iCAiGkB,YAAY;;;;;;;;;;;;;;;;;;;;;6FAqBgD,CAAC;IAE5F,MAAM,WAAW,GAAG;;EAEpB,MAAM,CAAC,YAAY;;sDAEiC,CAAC;IAErD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC"}
@@ -7,9 +7,9 @@ export type ClaudeModelAlias = 'sonnet' | 'haiku' | 'opus';
7
7
  export type ClaudeModelName = ClaudeModelAlias | (string & {
8
8
  __brand?: 'FullModelId';
9
9
  });
10
- export type EffortLevel = 'low' | 'medium' | 'high';
10
+ /** Task complexity label for per-task effort frontmatter. Maps to models via effortMapping. */
11
+ export type TaskEffortLevel = 'low' | 'medium' | 'high';
11
12
  export type ModelScenario = 'plan' | 'execute' | 'nameGeneration' | 'failureAnalysis' | 'prGeneration' | 'config';
12
- export type EffortScenario = ModelScenario;
13
13
  export type CommitFormatType = 'task' | 'plan' | 'amend';
14
14
  export interface ModelsConfig {
15
15
  plan: ClaudeModelName;
@@ -19,13 +19,14 @@ export interface ModelsConfig {
19
19
  prGeneration: ClaudeModelName;
20
20
  config: ClaudeModelName;
21
21
  }
22
- export interface EffortConfig {
23
- plan: EffortLevel;
24
- execute: EffortLevel;
25
- nameGeneration: EffortLevel;
26
- failureAnalysis: EffortLevel;
27
- prGeneration: EffortLevel;
28
- config: EffortLevel;
22
+ /**
23
+ * Maps task complexity labels to model names.
24
+ * Used to resolve per-task effort frontmatter to a model.
25
+ */
26
+ export interface EffortMappingConfig {
27
+ low: ClaudeModelName;
28
+ medium: ClaudeModelName;
29
+ high: ClaudeModelName;
29
30
  }
30
31
  export interface CommitFormatConfig {
31
32
  task: string;
@@ -48,16 +49,32 @@ export interface PricingConfig {
48
49
  sonnet: ModelPricing;
49
50
  haiku: ModelPricing;
50
51
  }
52
+ /** Display options for token usage summaries. */
53
+ export interface DisplayConfig {
54
+ /** Show estimated 5h rate limit window percentage. Default: true */
55
+ showRateLimitEstimate: boolean;
56
+ /** Show cache token counts in summaries. Default: true */
57
+ showCacheTokens: boolean;
58
+ }
59
+ /** Rate limit window configuration. */
60
+ export interface RateLimitWindowConfig {
61
+ /** Sonnet-equivalent token cap for the 5h window. Default: 88000 */
62
+ sonnetTokenCap: number;
63
+ }
51
64
  export interface RafConfig {
52
65
  models: ModelsConfig;
53
- effort: EffortConfig;
66
+ /** Maps task complexity labels (low/medium/high) to models. Used for per-task effort frontmatter. */
67
+ effortMapping: EffortMappingConfig;
54
68
  timeout: number;
55
69
  maxRetries: number;
56
70
  autoCommit: boolean;
57
71
  worktree: boolean;
72
+ /** Sync main branch with remote before worktree/PR operations. Default: true */
73
+ syncMainBranch: boolean;
58
74
  commitFormat: CommitFormatConfig;
59
- claudeCommand: string;
60
75
  pricing: PricingConfig;
76
+ display: DisplayConfig;
77
+ rateLimitWindow: RateLimitWindowConfig;
61
78
  }
62
79
  export declare const DEFAULT_CONFIG: RafConfig;
63
80
  /** Deep partial type for user config files — all fields optional at every level */
@@ -73,13 +90,13 @@ export declare const VALID_MODEL_ALIASES: readonly ClaudeModelAlias[];
73
90
  export declare const FULL_MODEL_ID_PATTERN: RegExp;
74
91
  /** @deprecated Use VALID_MODEL_ALIASES instead */
75
92
  export declare const VALID_MODELS: readonly ClaudeModelAlias[];
76
- export declare const VALID_EFFORTS: readonly EffortLevel[];
93
+ /** Valid task effort levels for plan frontmatter. */
94
+ export declare const VALID_TASK_EFFORTS: readonly TaskEffortLevel[];
77
95
  /** @deprecated Use DEFAULT_CONFIG instead */
78
96
  export declare const DEFAULT_RAF_CONFIG: {
79
97
  defaultTimeout: number;
80
98
  defaultMaxRetries: number;
81
99
  autoCommit: boolean;
82
- claudeCommand: string;
83
100
  };
84
101
  export interface PlanCommandOptions {
85
102
  projectName?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
@@ -7,25 +7,22 @@ export const DEFAULT_CONFIG = {
7
7
  prGeneration: 'sonnet',
8
8
  config: 'sonnet',
9
9
  },
10
- effort: {
11
- plan: 'high',
12
- execute: 'medium',
13
- nameGeneration: 'low',
14
- failureAnalysis: 'low',
15
- prGeneration: 'medium',
16
- config: 'medium',
10
+ effortMapping: {
11
+ low: 'haiku',
12
+ medium: 'sonnet',
13
+ high: 'opus',
17
14
  },
18
15
  timeout: 60,
19
16
  maxRetries: 3,
20
17
  autoCommit: true,
21
18
  worktree: false,
19
+ syncMainBranch: true,
22
20
  commitFormat: {
23
21
  task: '{prefix}[{projectId}:{taskId}] {description}',
24
22
  plan: '{prefix}[{projectId}] Plan: {projectName}',
25
23
  amend: '{prefix}[{projectId}] Amend: {projectName}',
26
24
  prefix: 'RAF',
27
25
  },
28
- claudeCommand: 'claude',
29
26
  pricing: {
30
27
  opus: {
31
28
  inputPerMTok: 15,
@@ -46,6 +43,13 @@ export const DEFAULT_CONFIG = {
46
43
  cacheCreatePerMTok: 1.25,
47
44
  },
48
45
  },
46
+ display: {
47
+ showRateLimitEstimate: true,
48
+ showCacheTokens: true,
49
+ },
50
+ rateLimitWindow: {
51
+ sonnetTokenCap: 88000,
52
+ },
49
53
  };
50
54
  export const VALID_MODEL_ALIASES = ['sonnet', 'haiku', 'opus'];
51
55
  /**
@@ -55,13 +59,13 @@ export const VALID_MODEL_ALIASES = ['sonnet', 'haiku', 'opus'];
55
59
  export const FULL_MODEL_ID_PATTERN = /^claude-[a-z]+-\d+(-\d+)*$/;
56
60
  /** @deprecated Use VALID_MODEL_ALIASES instead */
57
61
  export const VALID_MODELS = VALID_MODEL_ALIASES;
58
- export const VALID_EFFORTS = ['low', 'medium', 'high'];
62
+ /** Valid task effort levels for plan frontmatter. */
63
+ export const VALID_TASK_EFFORTS = ['low', 'medium', 'high'];
59
64
  // Keep backward-compat exports used by other modules
60
65
  /** @deprecated Use DEFAULT_CONFIG instead */
61
66
  export const DEFAULT_RAF_CONFIG = {
62
67
  defaultTimeout: DEFAULT_CONFIG.timeout,
63
68
  defaultMaxRetries: DEFAULT_CONFIG.maxRetries,
64
69
  autoCommit: DEFAULT_CONFIG.autoCommit,
65
- claudeCommand: DEFAULT_CONFIG.claudeCommand,
66
70
  };
67
71
  //# sourceMappingURL=config.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAqEA,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,MAAM;QACf,cAAc,EAAE,QAAQ;QACxB,eAAe,EAAE,OAAO;QACxB,YAAY,EAAE,QAAQ;QACtB,MAAM,EAAE,QAAQ;KACjB;IACD,MAAM,EAAE;QACN,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,QAAQ;QACjB,cAAc,EAAE,KAAK;QACrB,eAAe,EAAE,KAAK;QACtB,YAAY,EAAE,QAAQ;QACtB,MAAM,EAAE,QAAQ;KACjB;IACD,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,KAAK;IACf,YAAY,EAAE;QACZ,IAAI,EAAE,8CAA8C;QACpD,IAAI,EAAE,2CAA2C;QACjD,KAAK,EAAE,4CAA4C;QACnD,MAAM,EAAE,KAAK;KACd;IACD,aAAa,EAAE,QAAQ;IACvB,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,YAAY,EAAE,EAAE;YAChB,aAAa,EAAE,EAAE;YACjB,gBAAgB,EAAE,GAAG;YACrB,kBAAkB,EAAE,KAAK;SAC1B;QACD,MAAM,EAAE;YACN,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,EAAE;YACjB,gBAAgB,EAAE,GAAG;YACrB,kBAAkB,EAAE,IAAI;SACzB;QACD,KAAK,EAAE;YACL,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,gBAAgB,EAAE,GAAG;YACrB,kBAAkB,EAAE,IAAI;SACzB;KACF;CACF,CAAC;AASF,MAAM,CAAC,MAAM,mBAAmB,GAAgC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAE5F;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAElE,kDAAkD;AAClD,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAChD,MAAM,CAAC,MAAM,aAAa,GAA2B,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAE/E,qDAAqD;AACrD,6CAA6C;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,cAAc,EAAE,cAAc,CAAC,OAAO;IACtC,iBAAiB,EAAE,cAAc,CAAC,UAAU;IAC5C,UAAU,EAAE,cAAc,CAAC,UAAU;IACrC,aAAa,EAAE,cAAc,CAAC,aAAa;CAC5C,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAyFA,MAAM,CAAC,MAAM,cAAc,GAAc;IACvC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM;QACZ,OAAO,EAAE,MAAM;QACf,cAAc,EAAE,QAAQ;QACxB,eAAe,EAAE,OAAO;QACxB,YAAY,EAAE,QAAQ;QACtB,MAAM,EAAE,QAAQ;KACjB;IACD,aAAa,EAAE;QACb,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,MAAM;KACb;IACD,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,KAAK;IACf,cAAc,EAAE,IAAI;IACpB,YAAY,EAAE;QACZ,IAAI,EAAE,8CAA8C;QACpD,IAAI,EAAE,2CAA2C;QACjD,KAAK,EAAE,4CAA4C;QACnD,MAAM,EAAE,KAAK;KACd;IACD,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,YAAY,EAAE,EAAE;YAChB,aAAa,EAAE,EAAE;YACjB,gBAAgB,EAAE,GAAG;YACrB,kBAAkB,EAAE,KAAK;SAC1B;QACD,MAAM,EAAE;YACN,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,EAAE;YACjB,gBAAgB,EAAE,GAAG;YACrB,kBAAkB,EAAE,IAAI;SACzB;QACD,KAAK,EAAE;YACL,YAAY,EAAE,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,gBAAgB,EAAE,GAAG;YACrB,kBAAkB,EAAE,IAAI;SACzB;KACF;IACD,OAAO,EAAE;QACP,qBAAqB,EAAE,IAAI;QAC3B,eAAe,EAAE,IAAI;KACtB;IACD,eAAe,EAAE;QACf,cAAc,EAAE,KAAK;KACtB;CACF,CAAC;AASF,MAAM,CAAC,MAAM,mBAAmB,GAAgC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAE5F;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,4BAA4B,CAAC;AAElE,kDAAkD;AAClD,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAEhD,qDAAqD;AACrD,MAAM,CAAC,MAAM,kBAAkB,GAA+B,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;AAExF,qDAAqD;AACrD,6CAA6C;AAC7C,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,cAAc,EAAE,cAAc,CAAC,OAAO;IACtC,iBAAiB,EAAE,cAAc,CAAC,UAAU;IAC5C,UAAU,EAAE,cAAc,CAAC,UAAU;CACtC,CAAC"}
@@ -1,4 +1,4 @@
1
- import { RafConfig, UserConfig, ClaudeModelName, EffortLevel, ModelScenario, EffortScenario, CommitFormatType, PricingCategory, ModelPricing, PricingConfig } from '../types/config.js';
1
+ import { RafConfig, UserConfig, ClaudeModelName, TaskEffortLevel, ModelScenario, CommitFormatType, PricingCategory, ModelPricing, PricingConfig, DisplayConfig, RateLimitWindowConfig, EffortMappingConfig } from '../types/config.js';
2
2
  export declare function getConfigPath(): string;
3
3
  /**
4
4
  * Get the path to Claude CLI settings file.
@@ -24,7 +24,6 @@ export declare function loadConfig(_rafDir: string): {
24
24
  defaultTimeout: number;
25
25
  defaultMaxRetries: number;
26
26
  autoCommit: boolean;
27
- claudeCommand: string;
28
27
  };
29
28
  export declare function saveConfig(configPath: string, config: UserConfig): void;
30
29
  /**
@@ -34,20 +33,44 @@ export declare function saveConfig(configPath: string, config: UserConfig): void
34
33
  export declare function getResolvedConfig(): RafConfig;
35
34
  export declare function resetConfigCache(): void;
36
35
  export declare function getModel(scenario: ModelScenario): ClaudeModelName;
37
- export declare function getEffort(scenario: EffortScenario): EffortLevel;
36
+ /**
37
+ * Get the full effort mapping config.
38
+ */
39
+ export declare function getEffortMapping(): EffortMappingConfig;
40
+ /**
41
+ * Resolve a task effort level to a model name using the effort mapping config.
42
+ */
43
+ export declare function resolveEffortToModel(effort: TaskEffortLevel): ClaudeModelName;
44
+ /**
45
+ * Get the numeric tier of a model for comparison.
46
+ * Extracts family from full model IDs (e.g., 'claude-opus-4-6' -> 3).
47
+ * Unknown models default to highest tier (3) so they're never accidentally capped.
48
+ */
49
+ export declare function getModelTier(modelName: string): number;
50
+ /**
51
+ * Apply ceiling to a model based on the configured models.execute ceiling.
52
+ * Returns the lower-tier model between the input and the ceiling.
53
+ */
54
+ export declare function applyModelCeiling(resolvedModel: string, ceiling?: string): string;
38
55
  export declare function getCommitFormat(type: CommitFormatType): string;
39
56
  export declare function getCommitPrefix(): string;
40
57
  export declare function getTimeout(): number;
41
58
  export declare function getMaxRetries(): number;
42
59
  export declare function getAutoCommit(): boolean;
43
60
  export declare function getWorktreeDefault(): boolean;
44
- export declare function getClaudeCommand(): string;
61
+ export declare function getSyncMainBranch(): boolean;
45
62
  /**
46
63
  * Extract the short model alias (opus, sonnet, haiku) from a model ID.
47
64
  * Works with both full model IDs (e.g., "claude-sonnet-4-5-20250929") and already-short names ("sonnet").
48
65
  * Returns the original string if no known alias can be extracted.
49
66
  */
50
67
  export declare function getModelShortName(modelId: string): string;
68
+ /**
69
+ * Resolve a model name to its full model ID.
70
+ * If already a full model ID, returns as-is.
71
+ * If a short alias (opus, sonnet, haiku), returns the corresponding full ID.
72
+ */
73
+ export declare function resolveFullModelId(modelName: string): string;
51
74
  /**
52
75
  * Map a full model ID (e.g., `claude-opus-4-6`) or short alias to a pricing category.
53
76
  * Returns null if the model cannot be mapped.
@@ -61,6 +84,26 @@ export declare function getPricing(category: PricingCategory): ModelPricing;
61
84
  * Get the full pricing config.
62
85
  */
63
86
  export declare function getPricingConfig(): PricingConfig;
87
+ /**
88
+ * Get the full display config.
89
+ */
90
+ export declare function getDisplayConfig(): DisplayConfig;
91
+ /**
92
+ * Get the full rate limit window config.
93
+ */
94
+ export declare function getRateLimitWindowConfig(): RateLimitWindowConfig;
95
+ /**
96
+ * Get whether to show rate limit estimate in token summaries.
97
+ */
98
+ export declare function getShowRateLimitEstimate(): boolean;
99
+ /**
100
+ * Get whether to show cache tokens in summaries.
101
+ */
102
+ export declare function getShowCacheTokens(): boolean;
103
+ /**
104
+ * Get the Sonnet-equivalent token cap for the 5h rate limit window.
105
+ */
106
+ export declare function getSonnetTokenCap(): number;
64
107
  /**
65
108
  * Render a commit message template by replacing {placeholder} tokens with values.
66
109
  * Unknown placeholders are left as-is.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,SAAS,EAGT,UAAU,EAIV,eAAe,EACf,WAAW,EACX,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,aAAa,EACd,MAAM,oBAAoB,CAAC;AAK5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAsBD,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAUD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU,CA6G1D;AAkCD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAW5D;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,cAAc,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAE7I;AAED,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAMvE;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,SAAS,CAK7C;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,aAAa,GAAG,eAAe,CAEjE;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,cAAc,GAAG,WAAW,CAE/D;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG,MAAM,CAE9D;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAED,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAezD;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAcnF;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,YAAY,CAElE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,aAAa,CAEhD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAI/F;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYnE;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAOxF"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
3
  import * as os from 'node:os';
4
- import { DEFAULT_CONFIG, DEFAULT_RAF_CONFIG, VALID_MODEL_ALIASES, FULL_MODEL_ID_PATTERN, VALID_EFFORTS, } from '../types/config.js';
4
+ import { DEFAULT_CONFIG, DEFAULT_RAF_CONFIG, VALID_MODEL_ALIASES, FULL_MODEL_ID_PATTERN, } from '../types/config.js';
5
5
  const CONFIG_DIR = path.join(os.homedir(), '.raf');
6
6
  const CONFIG_FILENAME = 'raf.config.json';
7
7
  export function getConfigPath() {
@@ -15,18 +15,18 @@ export function getClaudeSettingsPath() {
15
15
  }
16
16
  // ---- Validation ----
17
17
  const VALID_TOP_LEVEL_KEYS = new Set([
18
- 'models', 'effort', 'timeout', 'maxRetries', 'autoCommit',
19
- 'worktree', 'commitFormat', 'claudeCommand', 'pricing',
18
+ 'models', 'effortMapping', 'timeout', 'maxRetries', 'autoCommit',
19
+ 'worktree', 'syncMainBranch', 'commitFormat', 'pricing', 'display', 'rateLimitWindow',
20
20
  ]);
21
21
  const VALID_PRICING_CATEGORIES = new Set(['opus', 'sonnet', 'haiku']);
22
22
  const VALID_PRICING_FIELDS = new Set(['inputPerMTok', 'outputPerMTok', 'cacheReadPerMTok', 'cacheCreatePerMTok']);
23
23
  const VALID_MODEL_KEYS = new Set([
24
24
  'plan', 'execute', 'nameGeneration', 'failureAnalysis', 'prGeneration', 'config',
25
25
  ]);
26
- const VALID_EFFORT_KEYS = new Set([
27
- 'plan', 'execute', 'nameGeneration', 'failureAnalysis', 'prGeneration', 'config',
28
- ]);
26
+ const VALID_EFFORT_MAPPING_KEYS = new Set(['low', 'medium', 'high']);
29
27
  const VALID_COMMIT_FORMAT_KEYS = new Set(['task', 'plan', 'amend', 'prefix']);
28
+ const VALID_DISPLAY_KEYS = new Set(['showRateLimitEstimate', 'showCacheTokens']);
29
+ const VALID_RATE_LIMIT_WINDOW_KEYS = new Set(['sonnetTokenCap']);
30
30
  export class ConfigValidationError extends Error {
31
31
  constructor(message) {
32
32
  super(message);
@@ -65,16 +65,16 @@ export function validateConfig(config) {
65
65
  }
66
66
  }
67
67
  }
68
- // effort
69
- if (obj.effort !== undefined) {
70
- if (typeof obj.effort !== 'object' || obj.effort === null || Array.isArray(obj.effort)) {
71
- throw new ConfigValidationError('effort must be an object');
68
+ // effortMapping
69
+ if (obj.effortMapping !== undefined) {
70
+ if (typeof obj.effortMapping !== 'object' || obj.effortMapping === null || Array.isArray(obj.effortMapping)) {
71
+ throw new ConfigValidationError('effortMapping must be an object');
72
72
  }
73
- const effort = obj.effort;
74
- checkUnknownKeys(effort, VALID_EFFORT_KEYS, 'effort');
75
- for (const [key, val] of Object.entries(effort)) {
76
- if (typeof val !== 'string' || !VALID_EFFORTS.includes(val)) {
77
- throw new ConfigValidationError(`effort.${key} must be one of: ${VALID_EFFORTS.join(', ')}`);
73
+ const effortMapping = obj.effortMapping;
74
+ checkUnknownKeys(effortMapping, VALID_EFFORT_MAPPING_KEYS, 'effortMapping');
75
+ for (const [key, val] of Object.entries(effortMapping)) {
76
+ if (typeof val !== 'string' || !isValidModelName(val)) {
77
+ throw new ConfigValidationError(`effortMapping.${key} must be a short alias (${VALID_MODEL_ALIASES.join(', ')}) or a full model ID (e.g., claude-sonnet-4-5-20250929)`);
78
78
  }
79
79
  }
80
80
  }
@@ -102,6 +102,12 @@ export function validateConfig(config) {
102
102
  throw new ConfigValidationError('worktree must be a boolean');
103
103
  }
104
104
  }
105
+ // syncMainBranch
106
+ if (obj.syncMainBranch !== undefined) {
107
+ if (typeof obj.syncMainBranch !== 'boolean') {
108
+ throw new ConfigValidationError('syncMainBranch must be a boolean');
109
+ }
110
+ }
105
111
  // commitFormat
106
112
  if (obj.commitFormat !== undefined) {
107
113
  if (typeof obj.commitFormat !== 'object' || obj.commitFormat === null || Array.isArray(obj.commitFormat)) {
@@ -115,12 +121,6 @@ export function validateConfig(config) {
115
121
  }
116
122
  }
117
123
  }
118
- // claudeCommand
119
- if (obj.claudeCommand !== undefined) {
120
- if (typeof obj.claudeCommand !== 'string' || obj.claudeCommand.trim() === '') {
121
- throw new ConfigValidationError('claudeCommand must be a non-empty string');
122
- }
123
- }
124
124
  // pricing
125
125
  if (obj.pricing !== undefined) {
126
126
  if (typeof obj.pricing !== 'object' || obj.pricing === null || Array.isArray(obj.pricing)) {
@@ -141,6 +141,32 @@ export function validateConfig(config) {
141
141
  }
142
142
  }
143
143
  }
144
+ // display
145
+ if (obj.display !== undefined) {
146
+ if (typeof obj.display !== 'object' || obj.display === null || Array.isArray(obj.display)) {
147
+ throw new ConfigValidationError('display must be an object');
148
+ }
149
+ const display = obj.display;
150
+ checkUnknownKeys(display, VALID_DISPLAY_KEYS, 'display');
151
+ for (const [key, val] of Object.entries(display)) {
152
+ if (typeof val !== 'boolean') {
153
+ throw new ConfigValidationError(`display.${key} must be a boolean`);
154
+ }
155
+ }
156
+ }
157
+ // rateLimitWindow
158
+ if (obj.rateLimitWindow !== undefined) {
159
+ if (typeof obj.rateLimitWindow !== 'object' || obj.rateLimitWindow === null || Array.isArray(obj.rateLimitWindow)) {
160
+ throw new ConfigValidationError('rateLimitWindow must be an object');
161
+ }
162
+ const rlw = obj.rateLimitWindow;
163
+ checkUnknownKeys(rlw, VALID_RATE_LIMIT_WINDOW_KEYS, 'rateLimitWindow');
164
+ if (rlw.sonnetTokenCap !== undefined) {
165
+ if (typeof rlw.sonnetTokenCap !== 'number' || rlw.sonnetTokenCap <= 0 || !Number.isFinite(rlw.sonnetTokenCap)) {
166
+ throw new ConfigValidationError('rateLimitWindow.sonnetTokenCap must be a positive number');
167
+ }
168
+ }
169
+ }
144
170
  return config;
145
171
  }
146
172
  // ---- Deep merge ----
@@ -149,8 +175,8 @@ function deepMerge(defaults, overrides) {
149
175
  if (overrides.models) {
150
176
  result.models = { ...defaults.models, ...overrides.models };
151
177
  }
152
- if (overrides.effort) {
153
- result.effort = { ...defaults.effort, ...overrides.effort };
178
+ if (overrides.effortMapping) {
179
+ result.effortMapping = { ...defaults.effortMapping, ...overrides.effortMapping };
154
180
  }
155
181
  if (overrides.commitFormat) {
156
182
  result.commitFormat = { ...defaults.commitFormat, ...overrides.commitFormat };
@@ -162,6 +188,12 @@ function deepMerge(defaults, overrides) {
162
188
  haiku: { ...defaults.pricing.haiku, ...overrides.pricing.haiku },
163
189
  };
164
190
  }
191
+ if (overrides.display) {
192
+ result.display = { ...defaults.display, ...overrides.display };
193
+ }
194
+ if (overrides.rateLimitWindow) {
195
+ result.rateLimitWindow = { ...defaults.rateLimitWindow, ...overrides.rateLimitWindow };
196
+ }
165
197
  if (overrides.timeout !== undefined)
166
198
  result.timeout = overrides.timeout;
167
199
  if (overrides.maxRetries !== undefined)
@@ -170,8 +202,8 @@ function deepMerge(defaults, overrides) {
170
202
  result.autoCommit = overrides.autoCommit;
171
203
  if (overrides.worktree !== undefined)
172
204
  result.worktree = overrides.worktree;
173
- if (overrides.claudeCommand !== undefined)
174
- result.claudeCommand = overrides.claudeCommand;
205
+ if (overrides.syncMainBranch !== undefined)
206
+ result.syncMainBranch = overrides.syncMainBranch;
175
207
  return result;
176
208
  }
177
209
  // ---- Config loading ----
@@ -182,7 +214,14 @@ function deepMerge(defaults, overrides) {
182
214
  export function resolveConfig(configPath) {
183
215
  const filePath = configPath ?? getConfigPath();
184
216
  if (!fs.existsSync(filePath)) {
185
- return { ...DEFAULT_CONFIG, models: { ...DEFAULT_CONFIG.models }, effort: { ...DEFAULT_CONFIG.effort }, commitFormat: { ...DEFAULT_CONFIG.commitFormat } };
217
+ return {
218
+ ...DEFAULT_CONFIG,
219
+ models: { ...DEFAULT_CONFIG.models },
220
+ effortMapping: { ...DEFAULT_CONFIG.effortMapping },
221
+ commitFormat: { ...DEFAULT_CONFIG.commitFormat },
222
+ display: { ...DEFAULT_CONFIG.display },
223
+ rateLimitWindow: { ...DEFAULT_CONFIG.rateLimitWindow },
224
+ };
186
225
  }
187
226
  const content = fs.readFileSync(filePath, 'utf-8');
188
227
  const parsed = JSON.parse(content);
@@ -220,8 +259,63 @@ export function resetConfigCache() {
220
259
  export function getModel(scenario) {
221
260
  return getResolvedConfig().models[scenario];
222
261
  }
223
- export function getEffort(scenario) {
224
- return getResolvedConfig().effort[scenario];
262
+ /**
263
+ * Get the full effort mapping config.
264
+ */
265
+ export function getEffortMapping() {
266
+ return getResolvedConfig().effortMapping;
267
+ }
268
+ /**
269
+ * Resolve a task effort level to a model name using the effort mapping config.
270
+ */
271
+ export function resolveEffortToModel(effort) {
272
+ return getResolvedConfig().effortMapping[effort];
273
+ }
274
+ /**
275
+ * Model tier ordering for ceiling comparison.
276
+ * Higher tier = more capable/expensive model.
277
+ * haiku (1) < sonnet (2) < opus (3)
278
+ */
279
+ const MODEL_TIER_ORDER = {
280
+ haiku: 1,
281
+ sonnet: 2,
282
+ opus: 3,
283
+ };
284
+ /**
285
+ * Get the numeric tier of a model for comparison.
286
+ * Extracts family from full model IDs (e.g., 'claude-opus-4-6' -> 3).
287
+ * Unknown models default to highest tier (3) so they're never accidentally capped.
288
+ */
289
+ export function getModelTier(modelName) {
290
+ // Check short aliases first
291
+ const tier = MODEL_TIER_ORDER[modelName];
292
+ if (tier !== undefined) {
293
+ return tier;
294
+ }
295
+ // Extract family from full model ID
296
+ const match = modelName.match(/^claude-([a-z]+)-/);
297
+ if (match && match[1]) {
298
+ const familyTier = MODEL_TIER_ORDER[match[1]];
299
+ if (familyTier !== undefined) {
300
+ return familyTier;
301
+ }
302
+ }
303
+ // Unknown model - default to highest tier (no cap)
304
+ return 3;
305
+ }
306
+ /**
307
+ * Apply ceiling to a model based on the configured models.execute ceiling.
308
+ * Returns the lower-tier model between the input and the ceiling.
309
+ */
310
+ export function applyModelCeiling(resolvedModel, ceiling) {
311
+ const ceilingModel = ceiling ?? getModel('execute');
312
+ const resolvedTier = getModelTier(resolvedModel);
313
+ const ceilingTier = getModelTier(ceilingModel);
314
+ // If resolved model is above ceiling, use ceiling instead
315
+ if (resolvedTier > ceilingTier) {
316
+ return ceilingModel;
317
+ }
318
+ return resolvedModel;
225
319
  }
226
320
  export function getCommitFormat(type) {
227
321
  return getResolvedConfig().commitFormat[type];
@@ -241,8 +335,8 @@ export function getAutoCommit() {
241
335
  export function getWorktreeDefault() {
242
336
  return getResolvedConfig().worktree;
243
337
  }
244
- export function getClaudeCommand() {
245
- return getResolvedConfig().claudeCommand;
338
+ export function getSyncMainBranch() {
339
+ return getResolvedConfig().syncMainBranch;
246
340
  }
247
341
  /**
248
342
  * Extract the short model alias (opus, sonnet, haiku) from a model ID.
@@ -265,6 +359,28 @@ export function getModelShortName(modelId) {
265
359
  // Unknown format, return as-is
266
360
  return modelId;
267
361
  }
362
+ /**
363
+ * Mapping of short model aliases to their current full model IDs.
364
+ * These should match the latest Claude model versions.
365
+ */
366
+ const MODEL_ALIAS_TO_FULL_ID = {
367
+ opus: 'claude-opus-4-6',
368
+ sonnet: 'claude-sonnet-4-5-20250929',
369
+ haiku: 'claude-haiku-4-5-20251001',
370
+ };
371
+ /**
372
+ * Resolve a model name to its full model ID.
373
+ * If already a full model ID, returns as-is.
374
+ * If a short alias (opus, sonnet, haiku), returns the corresponding full ID.
375
+ */
376
+ export function resolveFullModelId(modelName) {
377
+ const fullId = MODEL_ALIAS_TO_FULL_ID[modelName];
378
+ if (fullId) {
379
+ return fullId;
380
+ }
381
+ // Already a full ID or unknown, return as-is
382
+ return modelName;
383
+ }
268
384
  /**
269
385
  * Map a full model ID (e.g., `claude-opus-4-6`) or short alias to a pricing category.
270
386
  * Returns null if the model cannot be mapped.
@@ -296,6 +412,36 @@ export function getPricing(category) {
296
412
  export function getPricingConfig() {
297
413
  return getResolvedConfig().pricing;
298
414
  }
415
+ /**
416
+ * Get the full display config.
417
+ */
418
+ export function getDisplayConfig() {
419
+ return getResolvedConfig().display;
420
+ }
421
+ /**
422
+ * Get the full rate limit window config.
423
+ */
424
+ export function getRateLimitWindowConfig() {
425
+ return getResolvedConfig().rateLimitWindow;
426
+ }
427
+ /**
428
+ * Get whether to show rate limit estimate in token summaries.
429
+ */
430
+ export function getShowRateLimitEstimate() {
431
+ return getResolvedConfig().display.showRateLimitEstimate;
432
+ }
433
+ /**
434
+ * Get whether to show cache tokens in summaries.
435
+ */
436
+ export function getShowCacheTokens() {
437
+ return getResolvedConfig().display.showCacheTokens;
438
+ }
439
+ /**
440
+ * Get the Sonnet-equivalent token cap for the 5h rate limit window.
441
+ */
442
+ export function getSonnetTokenCap() {
443
+ return getResolvedConfig().rateLimitWindow.sonnetTokenCap;
444
+ }
299
445
  /**
300
446
  * Render a commit message template by replacing {placeholder} tokens with values.
301
447
  * Unknown placeholders are left as-is.