@build-astron-co/nimbus 0.2.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 (313) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +628 -0
  3. package/bin/nimbus +38 -0
  4. package/package.json +80 -0
  5. package/src/__tests__/app.test.ts +76 -0
  6. package/src/__tests__/audit.test.ts +877 -0
  7. package/src/__tests__/circuit-breaker.test.ts +116 -0
  8. package/src/__tests__/cli-run.test.ts +115 -0
  9. package/src/__tests__/context-manager.test.ts +502 -0
  10. package/src/__tests__/context.test.ts +242 -0
  11. package/src/__tests__/enterprise.test.ts +401 -0
  12. package/src/__tests__/generator.test.ts +433 -0
  13. package/src/__tests__/hooks.test.ts +582 -0
  14. package/src/__tests__/init.test.ts +436 -0
  15. package/src/__tests__/intent-parser.test.ts +229 -0
  16. package/src/__tests__/llm-router.test.ts +209 -0
  17. package/src/__tests__/lsp.test.ts +293 -0
  18. package/src/__tests__/modes.test.ts +336 -0
  19. package/src/__tests__/permissions.test.ts +338 -0
  20. package/src/__tests__/serve.test.ts +275 -0
  21. package/src/__tests__/sessions.test.ts +227 -0
  22. package/src/__tests__/sharing.test.ts +288 -0
  23. package/src/__tests__/snapshots.test.ts +581 -0
  24. package/src/__tests__/state-db.test.ts +334 -0
  25. package/src/__tests__/stream-with-tools.test.ts +732 -0
  26. package/src/__tests__/subagents.test.ts +176 -0
  27. package/src/__tests__/system-prompt.test.ts +169 -0
  28. package/src/__tests__/tool-converter.test.ts +256 -0
  29. package/src/__tests__/tool-schemas.test.ts +397 -0
  30. package/src/__tests__/tools.test.ts +143 -0
  31. package/src/__tests__/version.test.ts +49 -0
  32. package/src/agent/compaction-agent.ts +227 -0
  33. package/src/agent/context-manager.ts +435 -0
  34. package/src/agent/context.ts +427 -0
  35. package/src/agent/deploy-preview.ts +426 -0
  36. package/src/agent/index.ts +68 -0
  37. package/src/agent/loop.ts +717 -0
  38. package/src/agent/modes.ts +429 -0
  39. package/src/agent/permissions.ts +466 -0
  40. package/src/agent/subagents/base.ts +116 -0
  41. package/src/agent/subagents/cost.ts +51 -0
  42. package/src/agent/subagents/explore.ts +42 -0
  43. package/src/agent/subagents/general.ts +54 -0
  44. package/src/agent/subagents/index.ts +102 -0
  45. package/src/agent/subagents/infra.ts +59 -0
  46. package/src/agent/subagents/security.ts +69 -0
  47. package/src/agent/system-prompt.ts +436 -0
  48. package/src/app.ts +122 -0
  49. package/src/audit/activity-log.ts +290 -0
  50. package/src/audit/compliance-checker.ts +540 -0
  51. package/src/audit/cost-tracker.ts +318 -0
  52. package/src/audit/index.ts +23 -0
  53. package/src/audit/security-scanner.ts +596 -0
  54. package/src/auth/guard.ts +75 -0
  55. package/src/auth/index.ts +56 -0
  56. package/src/auth/oauth.ts +455 -0
  57. package/src/auth/providers.ts +470 -0
  58. package/src/auth/sso.ts +113 -0
  59. package/src/auth/store.ts +505 -0
  60. package/src/auth/types.ts +187 -0
  61. package/src/build.ts +141 -0
  62. package/src/cli/index.ts +16 -0
  63. package/src/cli/init.ts +854 -0
  64. package/src/cli/openapi-spec.ts +356 -0
  65. package/src/cli/run.ts +237 -0
  66. package/src/cli/serve-auth.ts +80 -0
  67. package/src/cli/serve.ts +462 -0
  68. package/src/cli/web.ts +67 -0
  69. package/src/cli.ts +1417 -0
  70. package/src/clients/core-engine-client.ts +227 -0
  71. package/src/clients/enterprise-client.ts +334 -0
  72. package/src/clients/generator-client.ts +351 -0
  73. package/src/clients/git-client.ts +627 -0
  74. package/src/clients/github-client.ts +410 -0
  75. package/src/clients/helm-client.ts +504 -0
  76. package/src/clients/index.ts +80 -0
  77. package/src/clients/k8s-client.ts +497 -0
  78. package/src/clients/llm-client.ts +161 -0
  79. package/src/clients/rest-client.ts +130 -0
  80. package/src/clients/service-discovery.ts +33 -0
  81. package/src/clients/terraform-client.ts +482 -0
  82. package/src/clients/tools-client.ts +1843 -0
  83. package/src/clients/ws-client.ts +115 -0
  84. package/src/commands/analyze/index.ts +352 -0
  85. package/src/commands/apply/helm.ts +473 -0
  86. package/src/commands/apply/index.ts +213 -0
  87. package/src/commands/apply/k8s.ts +454 -0
  88. package/src/commands/apply/terraform.ts +582 -0
  89. package/src/commands/ask.ts +167 -0
  90. package/src/commands/audit/index.ts +238 -0
  91. package/src/commands/auth-cloud.ts +294 -0
  92. package/src/commands/auth-list.ts +134 -0
  93. package/src/commands/auth-profile.ts +121 -0
  94. package/src/commands/auth-status.ts +141 -0
  95. package/src/commands/aws/ec2.ts +501 -0
  96. package/src/commands/aws/iam.ts +397 -0
  97. package/src/commands/aws/index.ts +133 -0
  98. package/src/commands/aws/lambda.ts +396 -0
  99. package/src/commands/aws/rds.ts +439 -0
  100. package/src/commands/aws/s3.ts +439 -0
  101. package/src/commands/aws/vpc.ts +393 -0
  102. package/src/commands/aws-discover.ts +649 -0
  103. package/src/commands/aws-terraform.ts +805 -0
  104. package/src/commands/azure/aks.ts +376 -0
  105. package/src/commands/azure/functions.ts +253 -0
  106. package/src/commands/azure/index.ts +116 -0
  107. package/src/commands/azure/storage.ts +478 -0
  108. package/src/commands/azure/vm.ts +355 -0
  109. package/src/commands/billing/index.ts +256 -0
  110. package/src/commands/chat.ts +314 -0
  111. package/src/commands/config.ts +346 -0
  112. package/src/commands/cost/cloud-cost-estimator.ts +266 -0
  113. package/src/commands/cost/estimator.ts +79 -0
  114. package/src/commands/cost/index.ts +594 -0
  115. package/src/commands/cost/parsers/terraform.ts +273 -0
  116. package/src/commands/cost/parsers/types.ts +25 -0
  117. package/src/commands/cost/pricing/aws.ts +544 -0
  118. package/src/commands/cost/pricing/azure.ts +499 -0
  119. package/src/commands/cost/pricing/gcp.ts +396 -0
  120. package/src/commands/cost/pricing/index.ts +40 -0
  121. package/src/commands/demo.ts +250 -0
  122. package/src/commands/doctor.ts +794 -0
  123. package/src/commands/drift/index.ts +439 -0
  124. package/src/commands/explain.ts +277 -0
  125. package/src/commands/feedback.ts +389 -0
  126. package/src/commands/fix.ts +324 -0
  127. package/src/commands/fs/index.ts +402 -0
  128. package/src/commands/gcp/compute.ts +325 -0
  129. package/src/commands/gcp/functions.ts +271 -0
  130. package/src/commands/gcp/gke.ts +438 -0
  131. package/src/commands/gcp/iam.ts +344 -0
  132. package/src/commands/gcp/index.ts +129 -0
  133. package/src/commands/gcp/storage.ts +284 -0
  134. package/src/commands/generate-helm.ts +1249 -0
  135. package/src/commands/generate-k8s.ts +1560 -0
  136. package/src/commands/generate-terraform.ts +1460 -0
  137. package/src/commands/gh/index.ts +863 -0
  138. package/src/commands/git/index.ts +1343 -0
  139. package/src/commands/helm/index.ts +1126 -0
  140. package/src/commands/help.ts +539 -0
  141. package/src/commands/history.ts +142 -0
  142. package/src/commands/import.ts +868 -0
  143. package/src/commands/index.ts +367 -0
  144. package/src/commands/init.ts +1046 -0
  145. package/src/commands/k8s/index.ts +1137 -0
  146. package/src/commands/login.ts +631 -0
  147. package/src/commands/logout.ts +83 -0
  148. package/src/commands/onboarding.ts +228 -0
  149. package/src/commands/plan/display.ts +279 -0
  150. package/src/commands/plan/index.ts +599 -0
  151. package/src/commands/preview.ts +452 -0
  152. package/src/commands/questionnaire.ts +1270 -0
  153. package/src/commands/resume.ts +55 -0
  154. package/src/commands/team/index.ts +346 -0
  155. package/src/commands/template.ts +232 -0
  156. package/src/commands/tf/index.ts +1034 -0
  157. package/src/commands/upgrade.ts +550 -0
  158. package/src/commands/usage/index.ts +134 -0
  159. package/src/commands/version.ts +170 -0
  160. package/src/compat/index.ts +2 -0
  161. package/src/compat/runtime.ts +12 -0
  162. package/src/compat/sqlite.ts +107 -0
  163. package/src/config/index.ts +17 -0
  164. package/src/config/manager.ts +530 -0
  165. package/src/config/safety-policy.ts +358 -0
  166. package/src/config/schema.ts +125 -0
  167. package/src/config/types.ts +527 -0
  168. package/src/context/context-db.ts +199 -0
  169. package/src/demo/index.ts +349 -0
  170. package/src/demo/scenarios/full-journey.ts +229 -0
  171. package/src/demo/scenarios/getting-started.ts +127 -0
  172. package/src/demo/scenarios/helm-release.ts +341 -0
  173. package/src/demo/scenarios/k8s-deployment.ts +194 -0
  174. package/src/demo/scenarios/terraform-vpc.ts +170 -0
  175. package/src/demo/types.ts +92 -0
  176. package/src/engine/cost-estimator.ts +438 -0
  177. package/src/engine/diagram-generator.ts +256 -0
  178. package/src/engine/drift-detector.ts +902 -0
  179. package/src/engine/executor.ts +1035 -0
  180. package/src/engine/index.ts +76 -0
  181. package/src/engine/orchestrator.ts +636 -0
  182. package/src/engine/planner.ts +720 -0
  183. package/src/engine/safety.ts +743 -0
  184. package/src/engine/verifier.ts +770 -0
  185. package/src/enterprise/audit.ts +348 -0
  186. package/src/enterprise/auth.ts +270 -0
  187. package/src/enterprise/billing.ts +822 -0
  188. package/src/enterprise/index.ts +17 -0
  189. package/src/enterprise/teams.ts +443 -0
  190. package/src/generator/best-practices.ts +1608 -0
  191. package/src/generator/helm.ts +630 -0
  192. package/src/generator/index.ts +37 -0
  193. package/src/generator/intent-parser.ts +514 -0
  194. package/src/generator/kubernetes.ts +976 -0
  195. package/src/generator/terraform.ts +1867 -0
  196. package/src/history/index.ts +8 -0
  197. package/src/history/manager.ts +322 -0
  198. package/src/history/types.ts +34 -0
  199. package/src/hooks/config.ts +432 -0
  200. package/src/hooks/engine.ts +391 -0
  201. package/src/hooks/index.ts +4 -0
  202. package/src/llm/auth-bridge.ts +198 -0
  203. package/src/llm/circuit-breaker.ts +140 -0
  204. package/src/llm/config-loader.ts +201 -0
  205. package/src/llm/cost-calculator.ts +171 -0
  206. package/src/llm/index.ts +8 -0
  207. package/src/llm/model-aliases.ts +115 -0
  208. package/src/llm/provider-registry.ts +63 -0
  209. package/src/llm/providers/anthropic.ts +433 -0
  210. package/src/llm/providers/bedrock.ts +477 -0
  211. package/src/llm/providers/google.ts +405 -0
  212. package/src/llm/providers/ollama.ts +767 -0
  213. package/src/llm/providers/openai-compatible.ts +340 -0
  214. package/src/llm/providers/openai.ts +328 -0
  215. package/src/llm/providers/openrouter.ts +338 -0
  216. package/src/llm/router.ts +1035 -0
  217. package/src/llm/types.ts +232 -0
  218. package/src/lsp/client.ts +298 -0
  219. package/src/lsp/languages.ts +116 -0
  220. package/src/lsp/manager.ts +278 -0
  221. package/src/mcp/client.ts +402 -0
  222. package/src/mcp/index.ts +5 -0
  223. package/src/mcp/manager.ts +133 -0
  224. package/src/nimbus.ts +214 -0
  225. package/src/plugins/index.ts +27 -0
  226. package/src/plugins/loader.ts +334 -0
  227. package/src/plugins/manager.ts +376 -0
  228. package/src/plugins/types.ts +284 -0
  229. package/src/scanners/cicd-scanner.ts +258 -0
  230. package/src/scanners/cloud-scanner.ts +466 -0
  231. package/src/scanners/framework-scanner.ts +469 -0
  232. package/src/scanners/iac-scanner.ts +388 -0
  233. package/src/scanners/index.ts +539 -0
  234. package/src/scanners/language-scanner.ts +276 -0
  235. package/src/scanners/package-manager-scanner.ts +277 -0
  236. package/src/scanners/types.ts +172 -0
  237. package/src/sessions/manager.ts +365 -0
  238. package/src/sessions/types.ts +44 -0
  239. package/src/sharing/sync.ts +296 -0
  240. package/src/sharing/viewer.ts +97 -0
  241. package/src/snapshots/index.ts +2 -0
  242. package/src/snapshots/manager.ts +530 -0
  243. package/src/state/artifacts.ts +147 -0
  244. package/src/state/audit.ts +137 -0
  245. package/src/state/billing.ts +240 -0
  246. package/src/state/checkpoints.ts +117 -0
  247. package/src/state/config.ts +67 -0
  248. package/src/state/conversations.ts +14 -0
  249. package/src/state/credentials.ts +154 -0
  250. package/src/state/db.ts +58 -0
  251. package/src/state/index.ts +26 -0
  252. package/src/state/messages.ts +115 -0
  253. package/src/state/projects.ts +123 -0
  254. package/src/state/schema.ts +236 -0
  255. package/src/state/sessions.ts +147 -0
  256. package/src/state/teams.ts +200 -0
  257. package/src/telemetry.ts +108 -0
  258. package/src/tools/aws-ops.ts +952 -0
  259. package/src/tools/azure-ops.ts +579 -0
  260. package/src/tools/file-ops.ts +593 -0
  261. package/src/tools/gcp-ops.ts +625 -0
  262. package/src/tools/git-ops.ts +773 -0
  263. package/src/tools/github-ops.ts +799 -0
  264. package/src/tools/helm-ops.ts +943 -0
  265. package/src/tools/index.ts +17 -0
  266. package/src/tools/k8s-ops.ts +819 -0
  267. package/src/tools/schemas/converter.ts +184 -0
  268. package/src/tools/schemas/devops.ts +612 -0
  269. package/src/tools/schemas/index.ts +73 -0
  270. package/src/tools/schemas/standard.ts +1144 -0
  271. package/src/tools/schemas/types.ts +705 -0
  272. package/src/tools/terraform-ops.ts +862 -0
  273. package/src/types/ambient.d.ts +193 -0
  274. package/src/types/config.ts +83 -0
  275. package/src/types/drift.ts +116 -0
  276. package/src/types/enterprise.ts +335 -0
  277. package/src/types/index.ts +20 -0
  278. package/src/types/plan.ts +44 -0
  279. package/src/types/request.ts +65 -0
  280. package/src/types/response.ts +54 -0
  281. package/src/types/service.ts +51 -0
  282. package/src/ui/App.tsx +997 -0
  283. package/src/ui/DeployPreview.tsx +169 -0
  284. package/src/ui/Header.tsx +68 -0
  285. package/src/ui/InputBox.tsx +350 -0
  286. package/src/ui/MessageList.tsx +585 -0
  287. package/src/ui/PermissionPrompt.tsx +151 -0
  288. package/src/ui/StatusBar.tsx +158 -0
  289. package/src/ui/ToolCallDisplay.tsx +409 -0
  290. package/src/ui/chat-ui.ts +853 -0
  291. package/src/ui/index.ts +33 -0
  292. package/src/ui/ink/index.ts +711 -0
  293. package/src/ui/streaming.ts +176 -0
  294. package/src/ui/types.ts +57 -0
  295. package/src/utils/analytics.ts +72 -0
  296. package/src/utils/cost-warning.ts +27 -0
  297. package/src/utils/env.ts +46 -0
  298. package/src/utils/errors.ts +69 -0
  299. package/src/utils/event-bus.ts +38 -0
  300. package/src/utils/index.ts +24 -0
  301. package/src/utils/logger.ts +171 -0
  302. package/src/utils/rate-limiter.ts +121 -0
  303. package/src/utils/service-auth.ts +49 -0
  304. package/src/utils/validation.ts +53 -0
  305. package/src/version.ts +4 -0
  306. package/src/watcher/index.ts +163 -0
  307. package/src/wizard/approval.ts +383 -0
  308. package/src/wizard/index.ts +25 -0
  309. package/src/wizard/prompts.ts +338 -0
  310. package/src/wizard/types.ts +171 -0
  311. package/src/wizard/ui.ts +556 -0
  312. package/src/wizard/wizard.ts +304 -0
  313. package/tsconfig.json +24 -0
@@ -0,0 +1,318 @@
1
+ /**
2
+ * Cost Tracker - Track LLM and infrastructure costs across sessions.
3
+ *
4
+ * Records cost entries for LLM API calls (with token counts and model info)
5
+ * and infrastructure changes (from terraform plan). Computes daily cost
6
+ * aggregates, monthly projections, and per-session breakdowns.
7
+ */
8
+
9
+ // ---------------------------------------------------------------------------
10
+ // Types
11
+ // ---------------------------------------------------------------------------
12
+
13
+ /** A single cost entry representing an LLM call or infrastructure change */
14
+ export interface CostEntry {
15
+ /** Unique identifier */
16
+ id: string;
17
+ /** Session in which the cost was incurred */
18
+ sessionId: string;
19
+ /** When the cost was recorded */
20
+ timestamp: Date;
21
+ /** Whether this is an LLM or infrastructure cost */
22
+ category: 'llm' | 'infra';
23
+ /** Human-readable description of what generated the cost */
24
+ description: string;
25
+ /** Cost in USD */
26
+ amount: number;
27
+ /** Number of input/prompt tokens (LLM only) */
28
+ inputTokens?: number;
29
+ /** Number of output/completion tokens (LLM only) */
30
+ outputTokens?: number;
31
+ /** Model identifier (LLM only) */
32
+ model?: string;
33
+ }
34
+
35
+ /** Aggregated cost summary with breakdowns and projections */
36
+ export interface CostSummary {
37
+ /** Total cost across all entries in USD */
38
+ totalCost: number;
39
+ /** Total LLM cost in USD */
40
+ llmCost: number;
41
+ /** Total infrastructure cost in USD */
42
+ infraCost: number;
43
+ /** Entries grouped by session ID */
44
+ entriesBySession: Map<string, CostEntry[]>;
45
+ /** Per-day cost totals sorted chronologically */
46
+ dailyCosts: { date: string; amount: number }[];
47
+ /** Projected monthly cost based on the daily average in USD */
48
+ monthlyProjection: number;
49
+ }
50
+
51
+ // ---------------------------------------------------------------------------
52
+ // Helpers
53
+ // ---------------------------------------------------------------------------
54
+
55
+ /**
56
+ * Format a Date as a YYYY-MM-DD string for daily aggregation.
57
+ */
58
+ function toDateKey(date: Date): string {
59
+ const y = date.getFullYear();
60
+ const m = String(date.getMonth() + 1).padStart(2, '0');
61
+ const d = String(date.getDate()).padStart(2, '0');
62
+ return `${y}-${m}-${d}`;
63
+ }
64
+
65
+ /**
66
+ * Format a USD amount with appropriate precision.
67
+ */
68
+ function formatUSD(amount: number): string {
69
+ if (amount < 0.01 && amount > 0) {
70
+ return `$${amount.toFixed(6)}`;
71
+ }
72
+ return `$${amount.toFixed(4)}`;
73
+ }
74
+
75
+ // ---------------------------------------------------------------------------
76
+ // CostTracker
77
+ // ---------------------------------------------------------------------------
78
+
79
+ /**
80
+ * Tracks LLM and infrastructure costs across Nimbus sessions.
81
+ *
82
+ * Maintains an in-memory ledger of cost entries and provides methods to
83
+ * compute summaries, daily breakdowns, and monthly projections.
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const tracker = new CostTracker();
88
+ *
89
+ * tracker.recordLLMCost({
90
+ * sessionId: 'abc-123',
91
+ * model: 'claude-sonnet-4-20250514',
92
+ * inputTokens: 1500,
93
+ * outputTokens: 800,
94
+ * costUSD: 0.0165,
95
+ * });
96
+ *
97
+ * const summary = tracker.getSummary();
98
+ * console.log(tracker.formatSummary(summary));
99
+ * ```
100
+ */
101
+ export class CostTracker {
102
+ private entries: CostEntry[] = [];
103
+
104
+ /**
105
+ * Record a cost entry for an LLM API call.
106
+ *
107
+ * @param params - LLM call details including model, token counts, and cost
108
+ * @returns The created cost entry
109
+ */
110
+ recordLLMCost(params: {
111
+ sessionId: string;
112
+ model: string;
113
+ inputTokens: number;
114
+ outputTokens: number;
115
+ costUSD: number;
116
+ }): CostEntry {
117
+ const entry: CostEntry = {
118
+ id: crypto.randomUUID(),
119
+ sessionId: params.sessionId,
120
+ timestamp: new Date(),
121
+ category: 'llm',
122
+ description: `LLM call to ${params.model} (${params.inputTokens} in / ${params.outputTokens} out tokens)`,
123
+ amount: params.costUSD,
124
+ inputTokens: params.inputTokens,
125
+ outputTokens: params.outputTokens,
126
+ model: params.model,
127
+ };
128
+
129
+ this.entries.push(entry);
130
+ return entry;
131
+ }
132
+
133
+ /**
134
+ * Record an infrastructure cost change, typically derived from a terraform plan.
135
+ *
136
+ * @param params - Infrastructure cost details
137
+ * @returns The created cost entry
138
+ */
139
+ recordInfraCost(params: {
140
+ sessionId: string;
141
+ description: string;
142
+ monthlyCost: number;
143
+ }): CostEntry {
144
+ const entry: CostEntry = {
145
+ id: crypto.randomUUID(),
146
+ sessionId: params.sessionId,
147
+ timestamp: new Date(),
148
+ category: 'infra',
149
+ description: params.description,
150
+ amount: params.monthlyCost,
151
+ };
152
+
153
+ this.entries.push(entry);
154
+ return entry;
155
+ }
156
+
157
+ /**
158
+ * Compute a cost summary over all entries or a subset filtered by time/session.
159
+ *
160
+ * The monthly projection is calculated by taking the average daily cost
161
+ * and multiplying by 30. If only a single day of data exists, that day's
162
+ * total is used as the daily average.
163
+ *
164
+ * @param options - Optional time range or session filter
165
+ * @returns Aggregated cost summary
166
+ */
167
+ getSummary(options?: { since?: Date; sessionId?: string }): CostSummary {
168
+ let filtered = this.entries;
169
+
170
+ if (options?.since) {
171
+ const since = options.since.getTime();
172
+ filtered = filtered.filter(e => e.timestamp.getTime() >= since);
173
+ }
174
+
175
+ if (options?.sessionId) {
176
+ filtered = filtered.filter(e => e.sessionId === options.sessionId);
177
+ }
178
+
179
+ // Totals
180
+ let totalCost = 0;
181
+ let llmCost = 0;
182
+ let infraCost = 0;
183
+
184
+ // Group by session
185
+ const entriesBySession = new Map<string, CostEntry[]>();
186
+
187
+ // Group by date
188
+ const dailyMap = new Map<string, number>();
189
+
190
+ for (const entry of filtered) {
191
+ totalCost += entry.amount;
192
+ if (entry.category === 'llm') {
193
+ llmCost += entry.amount;
194
+ } else {
195
+ infraCost += entry.amount;
196
+ }
197
+
198
+ // Session grouping
199
+ const sessionEntries = entriesBySession.get(entry.sessionId);
200
+ if (sessionEntries) {
201
+ sessionEntries.push(entry);
202
+ } else {
203
+ entriesBySession.set(entry.sessionId, [entry]);
204
+ }
205
+
206
+ // Daily grouping
207
+ const dateKey = toDateKey(entry.timestamp);
208
+ dailyMap.set(dateKey, (dailyMap.get(dateKey) ?? 0) + entry.amount);
209
+ }
210
+
211
+ // Sort daily costs chronologically
212
+ const dailyCosts = Array.from(dailyMap.entries())
213
+ .sort(([a], [b]) => a.localeCompare(b))
214
+ .map(([date, amount]) => ({ date, amount }));
215
+
216
+ // Monthly projection: average daily cost * 30
217
+ let monthlyProjection = 0;
218
+ if (dailyCosts.length > 0) {
219
+ const totalDailyCost = dailyCosts.reduce((sum, d) => sum + d.amount, 0);
220
+ const avgDaily = totalDailyCost / dailyCosts.length;
221
+ monthlyProjection = avgDaily * 30;
222
+ }
223
+
224
+ return {
225
+ totalCost,
226
+ llmCost,
227
+ infraCost,
228
+ entriesBySession,
229
+ dailyCosts,
230
+ monthlyProjection,
231
+ };
232
+ }
233
+
234
+ /**
235
+ * Retrieve raw cost entries, optionally filtered by session.
236
+ *
237
+ * @param sessionId - If provided, only return entries for this session
238
+ * @returns Array of cost entries sorted by timestamp (newest first)
239
+ */
240
+ getEntries(sessionId?: string): CostEntry[] {
241
+ let result = [...this.entries];
242
+ if (sessionId) {
243
+ result = result.filter(e => e.sessionId === sessionId);
244
+ }
245
+ return result.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
246
+ }
247
+
248
+ /**
249
+ * Format a cost summary as a human-readable text report.
250
+ *
251
+ * Includes totals, per-session breakdowns, daily costs, and the
252
+ * projected monthly spend.
253
+ *
254
+ * @param summary - The summary to format
255
+ * @returns Multi-line formatted report
256
+ */
257
+ formatSummary(summary: CostSummary): string {
258
+ const lines: string[] = [
259
+ 'Cost Summary',
260
+ '='.repeat(50),
261
+ '',
262
+ ` Total Cost: ${formatUSD(summary.totalCost)}`,
263
+ ` LLM Cost: ${formatUSD(summary.llmCost)}`,
264
+ ` Infra Cost: ${formatUSD(summary.infraCost)}`,
265
+ ` Monthly Estimate: ${formatUSD(summary.monthlyProjection)}`,
266
+ '',
267
+ ];
268
+
269
+ // Per-session breakdown
270
+ if (summary.entriesBySession.size > 0) {
271
+ lines.push('Per-Session Breakdown:');
272
+ lines.push('-'.repeat(50));
273
+
274
+ for (const [sessionId, entries] of summary.entriesBySession) {
275
+ const sessionTotal = entries.reduce((s, e) => s + e.amount, 0);
276
+ const llm = entries.filter(e => e.category === 'llm');
277
+ const infra = entries.filter(e => e.category === 'infra');
278
+
279
+ const totalInputTokens = llm.reduce((s, e) => s + (e.inputTokens ?? 0), 0);
280
+ const totalOutputTokens = llm.reduce((s, e) => s + (e.outputTokens ?? 0), 0);
281
+
282
+ lines.push(` Session: ${sessionId}`);
283
+ lines.push(` Total: ${formatUSD(sessionTotal)} (${entries.length} entries)`);
284
+
285
+ if (llm.length > 0) {
286
+ const llmTotal = llm.reduce((s, e) => s + e.amount, 0);
287
+ lines.push(
288
+ ` LLM: ${formatUSD(llmTotal)} (${llm.length} calls, ${totalInputTokens} in / ${totalOutputTokens} out tokens)`
289
+ );
290
+ }
291
+
292
+ if (infra.length > 0) {
293
+ const infraTotal = infra.reduce((s, e) => s + e.amount, 0);
294
+ lines.push(` Infra: ${formatUSD(infraTotal)} (${infra.length} changes)`);
295
+ }
296
+
297
+ lines.push('');
298
+ }
299
+ }
300
+
301
+ // Daily costs
302
+ if (summary.dailyCosts.length > 0) {
303
+ lines.push('Daily Costs:');
304
+ lines.push('-'.repeat(50));
305
+
306
+ for (const day of summary.dailyCosts) {
307
+ lines.push(` ${day.date}: ${formatUSD(day.amount)}`);
308
+ }
309
+
310
+ lines.push('');
311
+ }
312
+
313
+ lines.push('='.repeat(50));
314
+ lines.push(`Projected monthly cost: ${formatUSD(summary.monthlyProjection)}`);
315
+
316
+ return lines.join('\n');
317
+ }
318
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Audit Notebook - barrel exports.
3
+ *
4
+ * Re-exports the security scanner, compliance checker, cost tracker, and
5
+ * activity log modules for convenient single-import access.
6
+ */
7
+
8
+ export { scanSecurity, formatFindings } from './security-scanner';
9
+ export type { SecurityFinding, ScanResult, ScanOptions, Severity } from './security-scanner';
10
+
11
+ export { checkCompliance, generateScorecard } from './compliance-checker';
12
+ export type {
13
+ ComplianceControl,
14
+ ComplianceReport,
15
+ ComplianceOptions,
16
+ Framework,
17
+ } from './compliance-checker';
18
+
19
+ export { CostTracker } from './cost-tracker';
20
+ export type { CostEntry, CostSummary } from './cost-tracker';
21
+
22
+ export { ActivityLog } from './activity-log';
23
+ export type { ActivityEntry, ActivityFilter } from './activity-log';