gencode-ai 0.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 (274) hide show
  1. package/.env.example +11 -0
  2. package/CLAUDE.md +70 -0
  3. package/LICENSE +21 -0
  4. package/README.md +117 -0
  5. package/dist/agent/agent.d.ts +84 -0
  6. package/dist/agent/agent.d.ts.map +1 -0
  7. package/dist/agent/agent.js +233 -0
  8. package/dist/agent/agent.js.map +1 -0
  9. package/dist/agent/index.d.ts +6 -0
  10. package/dist/agent/index.d.ts.map +1 -0
  11. package/dist/agent/index.js +6 -0
  12. package/dist/agent/index.js.map +1 -0
  13. package/dist/agent/types.d.ts +47 -0
  14. package/dist/agent/types.d.ts.map +1 -0
  15. package/dist/agent/types.js +5 -0
  16. package/dist/agent/types.js.map +1 -0
  17. package/dist/cli/components/App.d.ts +14 -0
  18. package/dist/cli/components/App.d.ts.map +1 -0
  19. package/dist/cli/components/App.js +395 -0
  20. package/dist/cli/components/App.js.map +1 -0
  21. package/dist/cli/components/CommandSuggestions.d.ts +13 -0
  22. package/dist/cli/components/CommandSuggestions.d.ts.map +1 -0
  23. package/dist/cli/components/CommandSuggestions.js +32 -0
  24. package/dist/cli/components/CommandSuggestions.js.map +1 -0
  25. package/dist/cli/components/Header.d.ts +9 -0
  26. package/dist/cli/components/Header.d.ts.map +1 -0
  27. package/dist/cli/components/Header.js +13 -0
  28. package/dist/cli/components/Header.js.map +1 -0
  29. package/dist/cli/components/Input.d.ts +13 -0
  30. package/dist/cli/components/Input.d.ts.map +1 -0
  31. package/dist/cli/components/Input.js +27 -0
  32. package/dist/cli/components/Input.js.map +1 -0
  33. package/dist/cli/components/Logo.d.ts +2 -0
  34. package/dist/cli/components/Logo.d.ts.map +1 -0
  35. package/dist/cli/components/Logo.js +8 -0
  36. package/dist/cli/components/Logo.js.map +1 -0
  37. package/dist/cli/components/Messages.d.ts +37 -0
  38. package/dist/cli/components/Messages.d.ts.map +1 -0
  39. package/dist/cli/components/Messages.js +106 -0
  40. package/dist/cli/components/Messages.js.map +1 -0
  41. package/dist/cli/components/ModelSelector.d.ts +13 -0
  42. package/dist/cli/components/ModelSelector.d.ts.map +1 -0
  43. package/dist/cli/components/ModelSelector.js +72 -0
  44. package/dist/cli/components/ModelSelector.js.map +1 -0
  45. package/dist/cli/components/Spinner.d.ts +12 -0
  46. package/dist/cli/components/Spinner.d.ts.map +1 -0
  47. package/dist/cli/components/Spinner.js +45 -0
  48. package/dist/cli/components/Spinner.js.map +1 -0
  49. package/dist/cli/components/index.d.ts +12 -0
  50. package/dist/cli/components/index.d.ts.map +1 -0
  51. package/dist/cli/components/index.js +12 -0
  52. package/dist/cli/components/index.js.map +1 -0
  53. package/dist/cli/components/theme.d.ts +31 -0
  54. package/dist/cli/components/theme.d.ts.map +1 -0
  55. package/dist/cli/components/theme.js +36 -0
  56. package/dist/cli/components/theme.js.map +1 -0
  57. package/dist/cli/index-legacy.d.ts +7 -0
  58. package/dist/cli/index-legacy.d.ts.map +1 -0
  59. package/dist/cli/index-legacy.js +431 -0
  60. package/dist/cli/index-legacy.js.map +1 -0
  61. package/dist/cli/index.d.ts +7 -0
  62. package/dist/cli/index.d.ts.map +1 -0
  63. package/dist/cli/index.js +116 -0
  64. package/dist/cli/index.js.map +1 -0
  65. package/dist/cli/ink-cli.d.ts +7 -0
  66. package/dist/cli/ink-cli.d.ts.map +1 -0
  67. package/dist/cli/ink-cli.js +105 -0
  68. package/dist/cli/ink-cli.js.map +1 -0
  69. package/dist/cli/session-picker.d.ts +16 -0
  70. package/dist/cli/session-picker.d.ts.map +1 -0
  71. package/dist/cli/session-picker.js +280 -0
  72. package/dist/cli/session-picker.js.map +1 -0
  73. package/dist/cli/ui.d.ts +61 -0
  74. package/dist/cli/ui.d.ts.map +1 -0
  75. package/dist/cli/ui.js +364 -0
  76. package/dist/cli/ui.js.map +1 -0
  77. package/dist/config/index.d.ts +7 -0
  78. package/dist/config/index.d.ts.map +1 -0
  79. package/dist/config/index.js +6 -0
  80. package/dist/config/index.js.map +1 -0
  81. package/dist/config/manager.d.ts +31 -0
  82. package/dist/config/manager.d.ts.map +1 -0
  83. package/dist/config/manager.js +65 -0
  84. package/dist/config/manager.js.map +1 -0
  85. package/dist/config/types.d.ts +22 -0
  86. package/dist/config/types.d.ts.map +1 -0
  87. package/dist/config/types.js +6 -0
  88. package/dist/config/types.js.map +1 -0
  89. package/dist/index.d.ts +12 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +21 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/memory/index.d.ts +10 -0
  94. package/dist/memory/index.d.ts.map +1 -0
  95. package/dist/memory/index.js +9 -0
  96. package/dist/memory/index.js.map +1 -0
  97. package/dist/memory/init.d.ts +20 -0
  98. package/dist/memory/init.d.ts.map +1 -0
  99. package/dist/memory/init.js +332 -0
  100. package/dist/memory/init.js.map +1 -0
  101. package/dist/memory/manager.d.ts +85 -0
  102. package/dist/memory/manager.d.ts.map +1 -0
  103. package/dist/memory/manager.js +234 -0
  104. package/dist/memory/manager.js.map +1 -0
  105. package/dist/memory/types.d.ts +74 -0
  106. package/dist/memory/types.d.ts.map +1 -0
  107. package/dist/memory/types.js +6 -0
  108. package/dist/memory/types.js.map +1 -0
  109. package/dist/permissions/index.d.ts +7 -0
  110. package/dist/permissions/index.d.ts.map +1 -0
  111. package/dist/permissions/index.js +6 -0
  112. package/dist/permissions/index.js.map +1 -0
  113. package/dist/permissions/manager.d.ts +32 -0
  114. package/dist/permissions/manager.d.ts.map +1 -0
  115. package/dist/permissions/manager.js +79 -0
  116. package/dist/permissions/manager.js.map +1 -0
  117. package/dist/permissions/types.d.ts +14 -0
  118. package/dist/permissions/types.d.ts.map +1 -0
  119. package/dist/permissions/types.js +17 -0
  120. package/dist/permissions/types.js.map +1 -0
  121. package/dist/providers/anthropic.d.ts +20 -0
  122. package/dist/providers/anthropic.d.ts.map +1 -0
  123. package/dist/providers/anthropic.js +185 -0
  124. package/dist/providers/anthropic.js.map +1 -0
  125. package/dist/providers/gemini.d.ts +21 -0
  126. package/dist/providers/gemini.d.ts.map +1 -0
  127. package/dist/providers/gemini.js +241 -0
  128. package/dist/providers/gemini.js.map +1 -0
  129. package/dist/providers/index.d.ts +34 -0
  130. package/dist/providers/index.d.ts.map +1 -0
  131. package/dist/providers/index.js +72 -0
  132. package/dist/providers/index.js.map +1 -0
  133. package/dist/providers/openai.d.ts +19 -0
  134. package/dist/providers/openai.d.ts.map +1 -0
  135. package/dist/providers/openai.js +221 -0
  136. package/dist/providers/openai.js.map +1 -0
  137. package/dist/providers/types.d.ts +125 -0
  138. package/dist/providers/types.d.ts.map +1 -0
  139. package/dist/providers/types.js +6 -0
  140. package/dist/providers/types.js.map +1 -0
  141. package/dist/session/index.d.ts +6 -0
  142. package/dist/session/index.d.ts.map +1 -0
  143. package/dist/session/index.js +6 -0
  144. package/dist/session/index.js.map +1 -0
  145. package/dist/session/manager.d.ts +101 -0
  146. package/dist/session/manager.d.ts.map +1 -0
  147. package/dist/session/manager.js +295 -0
  148. package/dist/session/manager.js.map +1 -0
  149. package/dist/session/types.d.ts +39 -0
  150. package/dist/session/types.d.ts.map +1 -0
  151. package/dist/session/types.js +10 -0
  152. package/dist/session/types.js.map +1 -0
  153. package/dist/tools/builtin/bash.d.ts +7 -0
  154. package/dist/tools/builtin/bash.d.ts.map +1 -0
  155. package/dist/tools/builtin/bash.js +80 -0
  156. package/dist/tools/builtin/bash.js.map +1 -0
  157. package/dist/tools/builtin/edit.d.ts +7 -0
  158. package/dist/tools/builtin/edit.d.ts.map +1 -0
  159. package/dist/tools/builtin/edit.js +32 -0
  160. package/dist/tools/builtin/edit.js.map +1 -0
  161. package/dist/tools/builtin/glob.d.ts +7 -0
  162. package/dist/tools/builtin/glob.d.ts.map +1 -0
  163. package/dist/tools/builtin/glob.js +36 -0
  164. package/dist/tools/builtin/glob.js.map +1 -0
  165. package/dist/tools/builtin/grep.d.ts +7 -0
  166. package/dist/tools/builtin/grep.d.ts.map +1 -0
  167. package/dist/tools/builtin/grep.js +59 -0
  168. package/dist/tools/builtin/grep.js.map +1 -0
  169. package/dist/tools/builtin/read.d.ts +7 -0
  170. package/dist/tools/builtin/read.d.ts.map +1 -0
  171. package/dist/tools/builtin/read.js +29 -0
  172. package/dist/tools/builtin/read.js.map +1 -0
  173. package/dist/tools/builtin/write.d.ts +7 -0
  174. package/dist/tools/builtin/write.d.ts.map +1 -0
  175. package/dist/tools/builtin/write.js +24 -0
  176. package/dist/tools/builtin/write.js.map +1 -0
  177. package/dist/tools/index.d.ts +38 -0
  178. package/dist/tools/index.d.ts.map +1 -0
  179. package/dist/tools/index.js +32 -0
  180. package/dist/tools/index.js.map +1 -0
  181. package/dist/tools/registry.d.ts +22 -0
  182. package/dist/tools/registry.d.ts.map +1 -0
  183. package/dist/tools/registry.js +71 -0
  184. package/dist/tools/registry.js.map +1 -0
  185. package/dist/tools/types.d.ts +62 -0
  186. package/dist/tools/types.d.ts.map +1 -0
  187. package/dist/tools/types.js +126 -0
  188. package/dist/tools/types.js.map +1 -0
  189. package/docs/README.md +16 -0
  190. package/docs/proposals/0001-web-fetch-tool.md +293 -0
  191. package/docs/proposals/0002-web-search-tool.md +306 -0
  192. package/docs/proposals/0003-task-subagents.md +333 -0
  193. package/docs/proposals/0004-plan-mode.md +338 -0
  194. package/docs/proposals/0005-todo-system.md +299 -0
  195. package/docs/proposals/0006-memory-system.md +539 -0
  196. package/docs/proposals/0007-context-management.md +429 -0
  197. package/docs/proposals/0008-checkpointing.md +327 -0
  198. package/docs/proposals/0009-hooks-system.md +343 -0
  199. package/docs/proposals/0010-mcp-integration.md +382 -0
  200. package/docs/proposals/0011-custom-commands.md +374 -0
  201. package/docs/proposals/0012-ask-user-question.md +317 -0
  202. package/docs/proposals/0013-multi-edit-tool.md +345 -0
  203. package/docs/proposals/0014-lsp-tool.md +478 -0
  204. package/docs/proposals/0015-ls-tool.md +407 -0
  205. package/docs/proposals/0016-kill-shell-tool.md +455 -0
  206. package/docs/proposals/0017-background-tasks.md +489 -0
  207. package/docs/proposals/0018-parallel-tool-execution.md +415 -0
  208. package/docs/proposals/0019-session-enhancements.md +462 -0
  209. package/docs/proposals/0020-session-summarization.md +447 -0
  210. package/docs/proposals/0021-skills-system.md +409 -0
  211. package/docs/proposals/0022-plugin-system.md +467 -0
  212. package/docs/proposals/0023-permission-enhancements.md +470 -0
  213. package/docs/proposals/0024-keyboard-shortcuts.md +443 -0
  214. package/docs/proposals/0025-cost-tracking.md +447 -0
  215. package/docs/proposals/0026-git-integration.md +475 -0
  216. package/docs/proposals/0027-enhanced-read-tool.md +514 -0
  217. package/docs/proposals/0028-enhanced-bash-tool.md +511 -0
  218. package/docs/proposals/0029-notebook-edit-tool.md +413 -0
  219. package/docs/proposals/0030-plugin-marketplace.md +360 -0
  220. package/docs/proposals/0031-command-suggestions.md +295 -0
  221. package/docs/proposals/0032-ide-integrations.md +328 -0
  222. package/docs/proposals/0033-enterprise-deployment.md +221 -0
  223. package/docs/proposals/0034-sandboxing.md +273 -0
  224. package/docs/proposals/0035-auto-updater.md +311 -0
  225. package/docs/proposals/0036-enhanced-glob-tool.md +267 -0
  226. package/docs/proposals/0037-enhanced-grep-tool.md +360 -0
  227. package/docs/proposals/0038-interactive-cli-ui.md +373 -0
  228. package/docs/proposals/0039-streaming-enhancements.md +359 -0
  229. package/docs/proposals/0040-multi-provider-enhancements.md +369 -0
  230. package/docs/proposals/README.md +84 -0
  231. package/docs/proposals/TEMPLATE.md +57 -0
  232. package/docs/proposals/research/claude-code-research.md +307 -0
  233. package/examples/agent-demo.ts +115 -0
  234. package/examples/basic.ts +166 -0
  235. package/package.json +50 -0
  236. package/src/agent/agent.ts +276 -0
  237. package/src/agent/index.ts +6 -0
  238. package/src/agent/types.ts +62 -0
  239. package/src/cli/components/App.tsx +565 -0
  240. package/src/cli/components/CommandSuggestions.tsx +58 -0
  241. package/src/cli/components/Header.tsx +36 -0
  242. package/src/cli/components/Input.tsx +60 -0
  243. package/src/cli/components/Logo.tsx +16 -0
  244. package/src/cli/components/Messages.tsx +210 -0
  245. package/src/cli/components/ModelSelector.tsx +135 -0
  246. package/src/cli/components/Spinner.tsx +72 -0
  247. package/src/cli/components/index.ts +21 -0
  248. package/src/cli/components/theme.ts +36 -0
  249. package/src/cli/index.tsx +136 -0
  250. package/src/config/index.ts +7 -0
  251. package/src/config/manager.ts +77 -0
  252. package/src/config/types.ts +25 -0
  253. package/src/index.ts +86 -0
  254. package/src/permissions/index.ts +7 -0
  255. package/src/permissions/manager.ts +97 -0
  256. package/src/permissions/types.ts +29 -0
  257. package/src/providers/anthropic.ts +224 -0
  258. package/src/providers/gemini.ts +295 -0
  259. package/src/providers/index.ts +97 -0
  260. package/src/providers/openai.ts +261 -0
  261. package/src/providers/types.ts +181 -0
  262. package/src/session/index.ts +6 -0
  263. package/src/session/manager.ts +354 -0
  264. package/src/session/types.ts +49 -0
  265. package/src/tools/builtin/bash.ts +92 -0
  266. package/src/tools/builtin/edit.ts +37 -0
  267. package/src/tools/builtin/glob.ts +42 -0
  268. package/src/tools/builtin/grep.ts +67 -0
  269. package/src/tools/builtin/read.ts +34 -0
  270. package/src/tools/builtin/write.ts +27 -0
  271. package/src/tools/index.ts +36 -0
  272. package/src/tools/registry.ts +83 -0
  273. package/src/tools/types.ts +172 -0
  274. package/tsconfig.json +21 -0
@@ -0,0 +1,447 @@
1
+ # Proposal: Cost Tracking
2
+
3
+ - **Proposal ID**: 0025
4
+ - **Author**: mycode team
5
+ - **Status**: Draft
6
+ - **Created**: 2025-01-15
7
+ - **Updated**: 2025-01-15
8
+
9
+ ## Summary
10
+
11
+ Implement comprehensive cost tracking for API usage, showing real-time token counts, estimated costs, and cumulative spending. This provides users with visibility and control over their LLM API expenses.
12
+
13
+ ## Motivation
14
+
15
+ Currently, mycode provides no cost visibility:
16
+
17
+ 1. **Surprise bills**: Users don't know costs until invoice
18
+ 2. **No optimization**: Can't identify expensive operations
19
+ 3. **No budgets**: Can't set spending limits
20
+ 4. **Hidden usage**: Token counts not visible
21
+ 5. **No comparison**: Can't compare provider costs
22
+
23
+ Cost tracking enables informed usage decisions.
24
+
25
+ ## Claude Code Reference
26
+
27
+ Claude Code displays cost information in the interface:
28
+
29
+ ### Observed Features
30
+ - Token count display (input/output)
31
+ - Estimated cost per message
32
+ - Session totals
33
+ - Model-specific pricing
34
+
35
+ ### Cost Visibility
36
+ ```
37
+ Tokens: 1,234 in / 567 out (~$0.02)
38
+ Session total: 45,678 tokens (~$0.58)
39
+ ```
40
+
41
+ ## Detailed Design
42
+
43
+ ### API Design
44
+
45
+ ```typescript
46
+ // src/costs/types.ts
47
+ interface TokenUsage {
48
+ inputTokens: number;
49
+ outputTokens: number;
50
+ totalTokens: number;
51
+ }
52
+
53
+ interface CostEstimate {
54
+ inputCost: number;
55
+ outputCost: number;
56
+ totalCost: number;
57
+ currency: string; // 'USD'
58
+ }
59
+
60
+ interface MessageCost {
61
+ messageId: string;
62
+ timestamp: Date;
63
+ model: string;
64
+ provider: string;
65
+ tokens: TokenUsage;
66
+ cost: CostEstimate;
67
+ }
68
+
69
+ interface SessionCost {
70
+ sessionId: string;
71
+ messages: MessageCost[];
72
+ totals: {
73
+ tokens: TokenUsage;
74
+ cost: CostEstimate;
75
+ };
76
+ }
77
+
78
+ interface CostConfig {
79
+ displayMode: 'always' | 'summary' | 'never';
80
+ currency: string;
81
+ budgets?: {
82
+ perMessage?: number;
83
+ perSession?: number;
84
+ daily?: number;
85
+ monthly?: number;
86
+ };
87
+ alerts?: {
88
+ threshold: number;
89
+ action: 'warn' | 'confirm' | 'block';
90
+ };
91
+ }
92
+
93
+ // Provider pricing (per 1M tokens)
94
+ interface ProviderPricing {
95
+ provider: string;
96
+ model: string;
97
+ inputPer1M: number;
98
+ outputPer1M: number;
99
+ effectiveDate: string;
100
+ }
101
+ ```
102
+
103
+ ### Cost Tracker
104
+
105
+ ```typescript
106
+ // src/costs/tracker.ts
107
+ class CostTracker {
108
+ private config: CostConfig;
109
+ private pricing: Map<string, ProviderPricing> = new Map();
110
+ private sessionCosts: Map<string, SessionCost> = new Map();
111
+ private dailyTotal: number = 0;
112
+ private monthlyTotal: number = 0;
113
+
114
+ constructor(config?: Partial<CostConfig>) {
115
+ this.config = {
116
+ displayMode: 'always',
117
+ currency: 'USD',
118
+ ...config
119
+ };
120
+ this.loadPricing();
121
+ this.loadHistory();
122
+ }
123
+
124
+ private loadPricing(): void {
125
+ // Current pricing as of 2025
126
+ const defaultPricing: ProviderPricing[] = [
127
+ // Anthropic
128
+ { provider: 'anthropic', model: 'claude-opus-4-5', inputPer1M: 15, outputPer1M: 75, effectiveDate: '2025-01-01' },
129
+ { provider: 'anthropic', model: 'claude-sonnet-4', inputPer1M: 3, outputPer1M: 15, effectiveDate: '2025-01-01' },
130
+ { provider: 'anthropic', model: 'claude-haiku-3-5', inputPer1M: 0.25, outputPer1M: 1.25, effectiveDate: '2025-01-01' },
131
+
132
+ // OpenAI
133
+ { provider: 'openai', model: 'gpt-4o', inputPer1M: 2.5, outputPer1M: 10, effectiveDate: '2025-01-01' },
134
+ { provider: 'openai', model: 'gpt-4-turbo', inputPer1M: 10, outputPer1M: 30, effectiveDate: '2025-01-01' },
135
+ { provider: 'openai', model: 'o1', inputPer1M: 15, outputPer1M: 60, effectiveDate: '2025-01-01' },
136
+
137
+ // Google
138
+ { provider: 'gemini', model: 'gemini-2.0-flash', inputPer1M: 0.075, outputPer1M: 0.30, effectiveDate: '2025-01-01' },
139
+ { provider: 'gemini', model: 'gemini-1.5-pro', inputPer1M: 1.25, outputPer1M: 5, effectiveDate: '2025-01-01' },
140
+ ];
141
+
142
+ for (const pricing of defaultPricing) {
143
+ this.pricing.set(`${pricing.provider}:${pricing.model}`, pricing);
144
+ }
145
+ }
146
+
147
+ recordUsage(
148
+ sessionId: string,
149
+ model: string,
150
+ provider: string,
151
+ tokens: TokenUsage
152
+ ): MessageCost {
153
+ const cost = this.calculateCost(provider, model, tokens);
154
+
155
+ const messageCost: MessageCost = {
156
+ messageId: generateId(),
157
+ timestamp: new Date(),
158
+ model,
159
+ provider,
160
+ tokens,
161
+ cost
162
+ };
163
+
164
+ // Update session costs
165
+ const session = this.sessionCosts.get(sessionId) || {
166
+ sessionId,
167
+ messages: [],
168
+ totals: { tokens: { inputTokens: 0, outputTokens: 0, totalTokens: 0 }, cost: { inputCost: 0, outputCost: 0, totalCost: 0, currency: 'USD' } }
169
+ };
170
+
171
+ session.messages.push(messageCost);
172
+ session.totals.tokens.inputTokens += tokens.inputTokens;
173
+ session.totals.tokens.outputTokens += tokens.outputTokens;
174
+ session.totals.tokens.totalTokens += tokens.totalTokens;
175
+ session.totals.cost.inputCost += cost.inputCost;
176
+ session.totals.cost.outputCost += cost.outputCost;
177
+ session.totals.cost.totalCost += cost.totalCost;
178
+
179
+ this.sessionCosts.set(sessionId, session);
180
+
181
+ // Update daily/monthly
182
+ this.dailyTotal += cost.totalCost;
183
+ this.monthlyTotal += cost.totalCost;
184
+
185
+ // Check budgets
186
+ this.checkBudgets(messageCost);
187
+
188
+ return messageCost;
189
+ }
190
+
191
+ private calculateCost(
192
+ provider: string,
193
+ model: string,
194
+ tokens: TokenUsage
195
+ ): CostEstimate {
196
+ const pricing = this.pricing.get(`${provider}:${model}`);
197
+
198
+ if (!pricing) {
199
+ // Default/unknown pricing
200
+ return {
201
+ inputCost: 0,
202
+ outputCost: 0,
203
+ totalCost: 0,
204
+ currency: 'USD'
205
+ };
206
+ }
207
+
208
+ const inputCost = (tokens.inputTokens / 1_000_000) * pricing.inputPer1M;
209
+ const outputCost = (tokens.outputTokens / 1_000_000) * pricing.outputPer1M;
210
+
211
+ return {
212
+ inputCost,
213
+ outputCost,
214
+ totalCost: inputCost + outputCost,
215
+ currency: 'USD'
216
+ };
217
+ }
218
+
219
+ private checkBudgets(cost: MessageCost): void {
220
+ const budgets = this.config.budgets;
221
+ if (!budgets) return;
222
+
223
+ const alerts = this.config.alerts;
224
+
225
+ if (budgets.perMessage && cost.cost.totalCost > budgets.perMessage) {
226
+ this.handleBudgetAlert('perMessage', cost.cost.totalCost, budgets.perMessage);
227
+ }
228
+
229
+ if (budgets.daily && this.dailyTotal > budgets.daily) {
230
+ this.handleBudgetAlert('daily', this.dailyTotal, budgets.daily);
231
+ }
232
+
233
+ if (budgets.monthly && this.monthlyTotal > budgets.monthly) {
234
+ this.handleBudgetAlert('monthly', this.monthlyTotal, budgets.monthly);
235
+ }
236
+ }
237
+
238
+ getSessionCost(sessionId: string): SessionCost | undefined {
239
+ return this.sessionCosts.get(sessionId);
240
+ }
241
+
242
+ formatCost(cost: CostEstimate): string {
243
+ if (cost.totalCost < 0.01) {
244
+ return `<$0.01`;
245
+ }
246
+ return `$${cost.totalCost.toFixed(2)}`;
247
+ }
248
+
249
+ formatTokens(tokens: TokenUsage): string {
250
+ return `${this.formatNumber(tokens.inputTokens)} in / ${this.formatNumber(tokens.outputTokens)} out`;
251
+ }
252
+
253
+ private formatNumber(n: number): string {
254
+ if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
255
+ if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
256
+ return n.toString();
257
+ }
258
+
259
+ getReport(period: 'session' | 'day' | 'month'): CostReport {
260
+ // Generate detailed cost report
261
+ return {
262
+ period,
263
+ totalCost: period === 'session' ? this.getCurrentSessionCost() : this.getPeriodCost(period),
264
+ breakdown: this.getBreakdown(period),
265
+ topOperations: this.getTopOperations(period)
266
+ };
267
+ }
268
+ }
269
+
270
+ export const costTracker = new CostTracker();
271
+ ```
272
+
273
+ ### Provider Integration
274
+
275
+ ```typescript
276
+ // Update to src/providers/types.ts
277
+ interface CompletionResponse {
278
+ content: ContentBlock[];
279
+ stopReason: string;
280
+ usage?: {
281
+ inputTokens: number;
282
+ outputTokens: number;
283
+ };
284
+ }
285
+
286
+ // Update agent to track costs
287
+ class Agent {
288
+ async *run(messages: Message[]): AsyncGenerator<AgentEvent> {
289
+ // ... existing code ...
290
+
291
+ const response = await this.provider.complete({ messages, tools });
292
+
293
+ // Track cost if usage available
294
+ if (response.usage) {
295
+ const cost = costTracker.recordUsage(
296
+ this.sessionId,
297
+ this.model,
298
+ this.provider.name,
299
+ {
300
+ inputTokens: response.usage.inputTokens,
301
+ outputTokens: response.usage.outputTokens,
302
+ totalTokens: response.usage.inputTokens + response.usage.outputTokens
303
+ }
304
+ );
305
+
306
+ yield { type: 'cost', cost };
307
+ }
308
+ }
309
+ }
310
+ ```
311
+
312
+ ### File Changes
313
+
314
+ | File | Action | Description |
315
+ |------|--------|-------------|
316
+ | `src/costs/types.ts` | Create | Type definitions |
317
+ | `src/costs/tracker.ts` | Create | Cost tracking logic |
318
+ | `src/costs/pricing.ts` | Create | Provider pricing data |
319
+ | `src/costs/reports.ts` | Create | Cost reporting |
320
+ | `src/costs/index.ts` | Create | Module exports |
321
+ | `src/agent/agent.ts` | Modify | Track costs |
322
+ | `src/providers/types.ts` | Modify | Add usage to response |
323
+ | `src/cli/ui.ts` | Modify | Display costs |
324
+
325
+ ## User Experience
326
+
327
+ ### Real-time Display
328
+ ```
329
+ ┌─ mycode ──────────────────────────────────────────────────┐
330
+ │ Agent: Here's the implementation for the auth module... │
331
+ │ │
332
+ │ [Edit: src/auth.ts] │
333
+ │ [Write: src/auth.test.ts] │
334
+ │ │
335
+ ├──────────────────────────────────────────────────────────┤
336
+ │ Tokens: 2.3K in / 1.8K out (~$0.04) Session: $0.23 │
337
+ └──────────────────────────────────────────────────────────┘
338
+ ```
339
+
340
+ ### Cost Report
341
+ ```
342
+ User: /costs
343
+
344
+ Cost Report - Current Session:
345
+ ┌────────────────────────────────────────────────────────────┐
346
+ │ Provider Model Messages Tokens Cost │
347
+ ├────────────────────────────────────────────────────────────┤
348
+ │ anthropic claude-sonnet-4 12 45.2K $0.23 │
349
+ │ anthropic claude-haiku 3 8.1K $0.01 │
350
+ ├────────────────────────────────────────────────────────────┤
351
+ │ Total 15 53.3K $0.24 │
352
+ └────────────────────────────────────────────────────────────┘
353
+
354
+ Daily: $1.45 / $10.00 budget (14.5%)
355
+ Monthly: $23.67 / $100.00 budget (23.7%)
356
+ ```
357
+
358
+ ### Budget Warning
359
+ ```
360
+ ⚠️ Budget Alert
361
+ Daily spending ($9.50) approaching limit ($10.00).
362
+ Continue? [y/N]
363
+ ```
364
+
365
+ ### Compare Providers
366
+ ```
367
+ User: /costs compare
368
+
369
+ Cost Comparison for Current Session (53.3K tokens):
370
+ ┌────────────────────────────────────────────────────────────┐
371
+ │ Provider Model Input Output Total│
372
+ ├────────────────────────────────────────────────────────────┤
373
+ │ gemini gemini-2.0-flash $0.00 $0.01 $0.01 │
374
+ │ anthropic claude-haiku $0.01 $0.05 $0.06 │
375
+ │ openai gpt-4o $0.10 $0.40 $0.50 │
376
+ │ anthropic claude-sonnet $0.13 $0.68 $0.81 │
377
+ │ anthropic claude-opus $0.67 $3.38 $4.05 │
378
+ └────────────────────────────────────────────────────────────┘
379
+
380
+ Current selection: claude-sonnet ($0.24 actual)
381
+ ```
382
+
383
+ ## Alternatives Considered
384
+
385
+ ### Alternative 1: Provider Dashboard Only
386
+ Rely on provider's usage dashboards.
387
+
388
+ **Pros**: Accurate, authoritative
389
+ **Cons**: Not real-time, not in-context
390
+ **Decision**: Rejected - Need inline visibility
391
+
392
+ ### Alternative 2: Token Count Only
393
+ Show tokens without cost estimates.
394
+
395
+ **Pros**: Simpler, always accurate
396
+ **Cons**: Users must calculate costs
397
+ **Decision**: Rejected - Cost is more actionable
398
+
399
+ ### Alternative 3: Post-hoc Reports Only
400
+ Only show costs after session ends.
401
+
402
+ **Pros**: Simpler implementation
403
+ **Cons**: No real-time awareness
404
+ **Decision**: Rejected - Real-time is essential
405
+
406
+ ## Security Considerations
407
+
408
+ 1. **No API Keys in Reports**: Don't expose credentials
409
+ 2. **Local Storage**: Cost data stored locally
410
+ 3. **Pricing Updates**: Verify pricing source
411
+ 4. **Budget Enforcement**: Optional hard limits
412
+ 5. **Export Encryption**: Protect exported reports
413
+
414
+ ## Testing Strategy
415
+
416
+ 1. **Unit Tests**:
417
+ - Cost calculation accuracy
418
+ - Token counting
419
+ - Budget checking
420
+ - Report generation
421
+
422
+ 2. **Integration Tests**:
423
+ - Provider usage extraction
424
+ - Real-time updates
425
+ - Multiple sessions
426
+
427
+ 3. **Manual Testing**:
428
+ - Various providers
429
+ - Display modes
430
+ - Budget scenarios
431
+
432
+ ## Migration Path
433
+
434
+ 1. **Phase 1**: Basic token/cost display
435
+ 2. **Phase 2**: Session totals
436
+ 3. **Phase 3**: Budget system
437
+ 4. **Phase 4**: Detailed reports
438
+ 5. **Phase 5**: Cost optimization suggestions
439
+
440
+ No breaking changes.
441
+
442
+ ## References
443
+
444
+ - [Anthropic Pricing](https://www.anthropic.com/pricing)
445
+ - [OpenAI Pricing](https://openai.com/pricing)
446
+ - [Google AI Pricing](https://ai.google.dev/pricing)
447
+ - [Token Counting Libraries](https://github.com/openai/tiktoken)