@bahulam/code 2.6.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 (273) hide show
  1. package/README.md +80 -0
  2. package/package.json +49 -0
  3. package/pulse/app/activity/page.tsx +190 -0
  4. package/pulse/app/api/activity/route.ts +138 -0
  5. package/pulse/app/api/benchmark/route.ts +113 -0
  6. package/pulse/app/api/benchmarks/route.ts +195 -0
  7. package/pulse/app/api/costs/route.ts +88 -0
  8. package/pulse/app/api/export/route.ts +77 -0
  9. package/pulse/app/api/history/route.ts +11 -0
  10. package/pulse/app/api/import/route.ts +31 -0
  11. package/pulse/app/api/memory/route.ts +50 -0
  12. package/pulse/app/api/plans/route.ts +9 -0
  13. package/pulse/app/api/projects/[slug]/route.ts +96 -0
  14. package/pulse/app/api/projects/route.ts +121 -0
  15. package/pulse/app/api/sessions/[id]/replay/route.ts +20 -0
  16. package/pulse/app/api/sessions/[id]/route.ts +31 -0
  17. package/pulse/app/api/sessions/route.ts +112 -0
  18. package/pulse/app/api/settings/route.ts +14 -0
  19. package/pulse/app/api/stats/route.ts +143 -0
  20. package/pulse/app/api/todos/route.ts +9 -0
  21. package/pulse/app/api/tools/route.ts +160 -0
  22. package/pulse/app/benchmarks/page.tsx +224 -0
  23. package/pulse/app/costs/page.tsx +179 -0
  24. package/pulse/app/export/page.tsx +465 -0
  25. package/pulse/app/favicon.ico +0 -0
  26. package/pulse/app/globals.css +263 -0
  27. package/pulse/app/help/page.tsx +143 -0
  28. package/pulse/app/history/page.tsx +157 -0
  29. package/pulse/app/layout.tsx +46 -0
  30. package/pulse/app/memory/page.tsx +365 -0
  31. package/pulse/app/overview-client.tsx +393 -0
  32. package/pulse/app/page.tsx +14 -0
  33. package/pulse/app/plans/page.tsx +308 -0
  34. package/pulse/app/projects/[slug]/page.tsx +390 -0
  35. package/pulse/app/projects/page.tsx +110 -0
  36. package/pulse/app/sessions/[id]/page.tsx +243 -0
  37. package/pulse/app/sessions/page.tsx +39 -0
  38. package/pulse/app/settings/page.tsx +188 -0
  39. package/pulse/app/todos/page.tsx +211 -0
  40. package/pulse/app/tools/page.tsx +249 -0
  41. package/pulse/cli.js +164 -0
  42. package/pulse/components/activity/day-of-week-chart.tsx +35 -0
  43. package/pulse/components/activity/streak-card.tsx +36 -0
  44. package/pulse/components/costs/cache-efficiency-panel.tsx +76 -0
  45. package/pulse/components/costs/cost-by-project-chart.tsx +48 -0
  46. package/pulse/components/costs/cost-over-time-chart.tsx +95 -0
  47. package/pulse/components/costs/model-token-table.tsx +60 -0
  48. package/pulse/components/global-search.tsx +193 -0
  49. package/pulse/components/keyboard-nav-provider.tsx +23 -0
  50. package/pulse/components/layout/bottom-nav.tsx +53 -0
  51. package/pulse/components/layout/client-layout.tsx +31 -0
  52. package/pulse/components/layout/sidebar-context.tsx +50 -0
  53. package/pulse/components/layout/sidebar.tsx +183 -0
  54. package/pulse/components/layout/top-bar.tsx +121 -0
  55. package/pulse/components/overview/activity-heatmap.tsx +107 -0
  56. package/pulse/components/overview/conversation-table.tsx +148 -0
  57. package/pulse/components/overview/model-breakdown-donut.tsx +95 -0
  58. package/pulse/components/overview/peak-hours-chart.tsx +87 -0
  59. package/pulse/components/overview/project-activity-donut.tsx +96 -0
  60. package/pulse/components/overview/stat-card.tsx +102 -0
  61. package/pulse/components/overview/usage-over-time-chart.tsx +166 -0
  62. package/pulse/components/projects/project-card.tsx +175 -0
  63. package/pulse/components/sessions/replay/assistant-markdown.tsx +94 -0
  64. package/pulse/components/sessions/replay/compaction-card.tsx +25 -0
  65. package/pulse/components/sessions/replay/session-sidebar.tsx +231 -0
  66. package/pulse/components/sessions/replay/token-accumulation-chart.tsx +98 -0
  67. package/pulse/components/sessions/replay/tool-call-badge.tsx +127 -0
  68. package/pulse/components/sessions/replay/turn-cards.tsx +220 -0
  69. package/pulse/components/sessions/replay/user-tool-result.tsx +158 -0
  70. package/pulse/components/sessions/session-badges.tsx +49 -0
  71. package/pulse/components/sessions/session-table.tsx +299 -0
  72. package/pulse/components/theme-provider.tsx +44 -0
  73. package/pulse/components/tools/feature-adoption-table.tsx +58 -0
  74. package/pulse/components/tools/mcp-server-panel.tsx +45 -0
  75. package/pulse/components/tools/tool-ranking-chart.tsx +57 -0
  76. package/pulse/components/tools/version-history-table.tsx +32 -0
  77. package/pulse/components/ui/alert.tsx +66 -0
  78. package/pulse/components/ui/badge.tsx +48 -0
  79. package/pulse/components/ui/breadcrumb.tsx +109 -0
  80. package/pulse/components/ui/button.tsx +64 -0
  81. package/pulse/components/ui/calendar.tsx +220 -0
  82. package/pulse/components/ui/card.tsx +92 -0
  83. package/pulse/components/ui/command.tsx +158 -0
  84. package/pulse/components/ui/dialog.tsx +158 -0
  85. package/pulse/components/ui/input.tsx +21 -0
  86. package/pulse/components/ui/popover.tsx +89 -0
  87. package/pulse/components/ui/progress.tsx +31 -0
  88. package/pulse/components/ui/select.tsx +190 -0
  89. package/pulse/components/ui/separator.tsx +28 -0
  90. package/pulse/components/ui/sheet.tsx +143 -0
  91. package/pulse/components/ui/skeleton.tsx +13 -0
  92. package/pulse/components/ui/table.tsx +116 -0
  93. package/pulse/components/ui/tabs.tsx +91 -0
  94. package/pulse/components/ui/tooltip.tsx +57 -0
  95. package/pulse/components/use-global-keyboard-nav.ts +79 -0
  96. package/pulse/components.json +23 -0
  97. package/pulse/eslint.config.mjs +18 -0
  98. package/pulse/lib/bahulam-paths.ts +23 -0
  99. package/pulse/lib/claude-reader.ts +592 -0
  100. package/pulse/lib/decode.ts +129 -0
  101. package/pulse/lib/pricing.ts +102 -0
  102. package/pulse/lib/replay-parser.ts +165 -0
  103. package/pulse/lib/tool-categories.ts +127 -0
  104. package/pulse/lib/utils.ts +6 -0
  105. package/pulse/next-env.d.ts +6 -0
  106. package/pulse/next.config.ts +16 -0
  107. package/pulse/package.json +45 -0
  108. package/pulse/postcss.config.mjs +7 -0
  109. package/pulse/public/activity.png +0 -0
  110. package/pulse/public/cc-lens.png +0 -0
  111. package/pulse/public/command-k.png +0 -0
  112. package/pulse/public/costs.png +0 -0
  113. package/pulse/public/dashboard-dark.png +0 -0
  114. package/pulse/public/dashboard-white.png +0 -0
  115. package/pulse/public/export.png +0 -0
  116. package/pulse/public/file.svg +1 -0
  117. package/pulse/public/globe.svg +1 -0
  118. package/pulse/public/next.svg +1 -0
  119. package/pulse/public/projects.png +0 -0
  120. package/pulse/public/session-chat.png +0 -0
  121. package/pulse/public/todos.png +0 -0
  122. package/pulse/public/tools.png +0 -0
  123. package/pulse/public/vercel.svg +1 -0
  124. package/pulse/public/window.svg +1 -0
  125. package/pulse/tsconfig.json +34 -0
  126. package/pulse/types/claude.ts +294 -0
  127. package/src/agents/loader.mjs +94 -0
  128. package/src/agents/multi_workflow_loader.mjs +330 -0
  129. package/src/agents/parser.mjs +205 -0
  130. package/src/agents/scaffold.mjs +222 -0
  131. package/src/agents/teams.mjs +123 -0
  132. package/src/agents/workflow_loader.mjs +122 -0
  133. package/src/agents/workflow_scaffold.mjs +249 -0
  134. package/src/auth/oauth.mjs +220 -0
  135. package/src/auth/tarang-auth.mjs +306 -0
  136. package/src/commands/agent.mjs +220 -0
  137. package/src/commands/workflow.mjs +581 -0
  138. package/src/config/cli-args.mjs +200 -0
  139. package/src/config/env.mjs +263 -0
  140. package/src/config/hook-runner.mjs +100 -0
  141. package/src/config/memory-loader.mjs +32 -0
  142. package/src/config/settings-loader.mjs +45 -0
  143. package/src/config/settings.mjs +132 -0
  144. package/src/context/ast-parser.mjs +298 -0
  145. package/src/context/bm25.mjs +85 -0
  146. package/src/context/retriever.mjs +308 -0
  147. package/src/context/skeleton.mjs +134 -0
  148. package/src/context/symbol-indexer.mjs +375 -0
  149. package/src/core/agent-history.mjs +111 -0
  150. package/src/core/agent-loop.mjs +486 -0
  151. package/src/core/approval-log.mjs +104 -0
  152. package/src/core/approval.mjs +476 -0
  153. package/src/core/attachments.mjs +380 -0
  154. package/src/core/backend-url.mjs +55 -0
  155. package/src/core/cache-control.mjs +92 -0
  156. package/src/core/cache.mjs +105 -0
  157. package/src/core/callback-client.mjs +180 -0
  158. package/src/core/checkpoints.mjs +142 -0
  159. package/src/core/compact-history.mjs +127 -0
  160. package/src/core/context-envelope.mjs +54 -0
  161. package/src/core/context-manager.mjs +198 -0
  162. package/src/core/error-guidance.mjs +311 -0
  163. package/src/core/file-diff.mjs +217 -0
  164. package/src/core/headless.mjs +448 -0
  165. package/src/core/hooks-manager.mjs +87 -0
  166. package/src/core/jsonl-writer.mjs +449 -0
  167. package/src/core/local-agent.mjs +537 -0
  168. package/src/core/local-store.mjs +836 -0
  169. package/src/core/mode-selector.mjs +51 -0
  170. package/src/core/output-filter.mjs +177 -0
  171. package/src/core/paths.mjs +190 -0
  172. package/src/core/policy-resolver.mjs +156 -0
  173. package/src/core/pricing.mjs +336 -0
  174. package/src/core/project-artifacts.mjs +39 -0
  175. package/src/core/project-context-loader.mjs +139 -0
  176. package/src/core/providers.mjs +219 -0
  177. package/src/core/rate-limit-display.mjs +121 -0
  178. package/src/core/rate-limiter.mjs +119 -0
  179. package/src/core/resume-mode.mjs +192 -0
  180. package/src/core/risk-tier.mjs +337 -0
  181. package/src/core/safety.mjs +203 -0
  182. package/src/core/scheduler.mjs +173 -0
  183. package/src/core/session-manager.mjs +360 -0
  184. package/src/core/session.mjs +143 -0
  185. package/src/core/settings-sync.mjs +85 -0
  186. package/src/core/stagnation.mjs +57 -0
  187. package/src/core/stream-client.mjs +829 -0
  188. package/src/core/streaming.mjs +182 -0
  189. package/src/core/system-prompt.mjs +140 -0
  190. package/src/core/tasks.mjs +196 -0
  191. package/src/core/tool-executor.mjs +1950 -0
  192. package/src/core/trust.mjs +158 -0
  193. package/src/core/work-scope.mjs +248 -0
  194. package/src/hooks/engine.mjs +162 -0
  195. package/src/index.mjs +426 -0
  196. package/src/mcp/client.mjs +253 -0
  197. package/src/mcp/transport-shttp.mjs +130 -0
  198. package/src/mcp/transport-sse.mjs +131 -0
  199. package/src/mcp/transport-ws.mjs +134 -0
  200. package/src/onboarding/preflight.mjs +360 -0
  201. package/src/permissions/checker.mjs +57 -0
  202. package/src/permissions/command-classifier.mjs +652 -0
  203. package/src/permissions/injection-check.mjs +60 -0
  204. package/src/permissions/path-check.mjs +102 -0
  205. package/src/permissions/prompt.mjs +73 -0
  206. package/src/permissions/sandbox.mjs +112 -0
  207. package/src/plugins/loader.mjs +138 -0
  208. package/src/skills/installer.mjs +188 -0
  209. package/src/skills/loader.mjs +252 -0
  210. package/src/skills/runner.mjs +55 -0
  211. package/src/state/orbit.mjs +263 -0
  212. package/src/state/verbosity.mjs +99 -0
  213. package/src/telemetry/index.mjs +96 -0
  214. package/src/terminal/agents.mjs +177 -0
  215. package/src/terminal/analytics.mjs +292 -0
  216. package/src/terminal/ansi.mjs +695 -0
  217. package/src/terminal/init.mjs +145 -0
  218. package/src/terminal/main.mjs +269 -0
  219. package/src/terminal/repl-explore.mjs +35 -0
  220. package/src/terminal/repl-format.mjs +257 -0
  221. package/src/terminal/repl-render.mjs +561 -0
  222. package/src/terminal/repl-resume.mjs +625 -0
  223. package/src/terminal/repl-state.mjs +103 -0
  224. package/src/terminal/repl-utils.mjs +34 -0
  225. package/src/terminal/repl.mjs +3832 -0
  226. package/src/terminal/skills.mjs +54 -0
  227. package/src/terminal/tool-display.mjs +240 -0
  228. package/src/tools/agent.mjs +137 -0
  229. package/src/tools/ask-user.mjs +61 -0
  230. package/src/tools/bash.mjs +231 -0
  231. package/src/tools/cron-create.mjs +120 -0
  232. package/src/tools/cron-delete.mjs +49 -0
  233. package/src/tools/cron-list.mjs +37 -0
  234. package/src/tools/edit.mjs +82 -0
  235. package/src/tools/enter-worktree.mjs +69 -0
  236. package/src/tools/exit-worktree.mjs +57 -0
  237. package/src/tools/glob.mjs +117 -0
  238. package/src/tools/grep.mjs +129 -0
  239. package/src/tools/lint.mjs +71 -0
  240. package/src/tools/ls.mjs +58 -0
  241. package/src/tools/lsp.mjs +115 -0
  242. package/src/tools/multi-edit.mjs +94 -0
  243. package/src/tools/notebook-edit.mjs +96 -0
  244. package/src/tools/project-overview.mjs +641 -0
  245. package/src/tools/read-mcp-resource.mjs +57 -0
  246. package/src/tools/read.mjs +138 -0
  247. package/src/tools/registry.mjs +116 -0
  248. package/src/tools/remote-trigger.mjs +84 -0
  249. package/src/tools/send-message.mjs +64 -0
  250. package/src/tools/skill.mjs +52 -0
  251. package/src/tools/test-runner.mjs +49 -0
  252. package/src/tools/todo-write.mjs +68 -0
  253. package/src/tools/tool-search.mjs +77 -0
  254. package/src/tools/web-fetch.mjs +65 -0
  255. package/src/tools/web-search.mjs +89 -0
  256. package/src/tools/write.mjs +55 -0
  257. package/src/ui/approval.mjs +263 -0
  258. package/src/ui/banner.mjs +235 -0
  259. package/src/ui/commands.mjs +537 -0
  260. package/src/ui/formatter.mjs +409 -0
  261. package/src/ui/icons.mjs +164 -0
  262. package/src/ui/input-dock.mjs +444 -0
  263. package/src/ui/markdown.mjs +278 -0
  264. package/src/ui/mission-report.mjs +296 -0
  265. package/src/ui/palette.mjs +189 -0
  266. package/src/ui/slash-commands.mjs +245 -0
  267. package/src/ui/spinner.mjs +116 -0
  268. package/src/ui/sub-agent.mjs +152 -0
  269. package/src/ui/term.mjs +159 -0
  270. package/src/ui/text-layout.mjs +127 -0
  271. package/src/ui/tool-card.mjs +463 -0
  272. package/src/ui/tool-details.mjs +312 -0
  273. package/src/ui/transcript-block.mjs +21 -0
@@ -0,0 +1,34 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2017",
4
+ "lib": ["dom", "dom.iterable", "esnext"],
5
+ "allowJs": true,
6
+ "skipLibCheck": true,
7
+ "strict": true,
8
+ "noEmit": true,
9
+ "esModuleInterop": true,
10
+ "module": "esnext",
11
+ "moduleResolution": "bundler",
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "jsx": "react-jsx",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts",
30
+ ".next/dev/types/**/*.ts",
31
+ "**/*.mts"
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }
@@ -0,0 +1,294 @@
1
+ // ─── Stats Cache ─────────────────────────────────────────────────────────────
2
+
3
+ export interface DailyActivity {
4
+ date: string
5
+ messageCount: number
6
+ sessionCount: number
7
+ toolCallCount: number
8
+ }
9
+
10
+ export interface DailyTokens {
11
+ date: string
12
+ tokensByModel: Record<string, number>
13
+ }
14
+
15
+ export interface ModelUsage {
16
+ inputTokens: number
17
+ outputTokens: number
18
+ cacheReadInputTokens: number
19
+ cacheCreationInputTokens: number
20
+ costUSD: number
21
+ webSearchRequests: number
22
+ }
23
+
24
+ export interface LongestSession {
25
+ sessionId: string
26
+ duration: number
27
+ messageCount: number
28
+ timestamp: string
29
+ }
30
+
31
+ export interface StatsCache {
32
+ version: number
33
+ lastComputedDate: string
34
+ dailyActivity: DailyActivity[]
35
+ tokensByDate: DailyTokens[]
36
+ dailyModelTokens?: DailyTokens[]
37
+ modelUsage: Record<string, ModelUsage>
38
+ totalSessions: number
39
+ totalMessages: number
40
+ longestSession: LongestSession
41
+ firstSessionDate: string
42
+ hourCounts: Record<string, number>
43
+ totalSpeculationTimeSavedMs: number
44
+ }
45
+
46
+ // ─── Session Meta ─────────────────────────────────────────────────────────────
47
+
48
+ export interface SessionMeta {
49
+ session_id: string
50
+ project_path: string
51
+ start_time: string
52
+ duration_minutes: number
53
+ user_message_count: number
54
+ assistant_message_count: number
55
+ tool_counts: Record<string, number>
56
+ languages: Record<string, number>
57
+ git_commits: number
58
+ git_pushes: number
59
+ input_tokens: number
60
+ output_tokens: number
61
+ cache_creation_input_tokens?: number
62
+ cache_read_input_tokens?: number
63
+ first_prompt: string
64
+ user_interruptions: number
65
+ user_response_times: number[]
66
+ tool_errors: number
67
+ tool_error_categories: Record<string, number>
68
+ uses_task_agent: boolean
69
+ uses_mcp: boolean
70
+ uses_web_search: boolean
71
+ uses_web_fetch: boolean
72
+ lines_added: number
73
+ lines_removed: number
74
+ files_modified: number
75
+ message_hours: number[]
76
+ user_message_timestamps: string[]
77
+ }
78
+
79
+ // ─── Facets ──────────────────────────────────────────────────────────────────
80
+
81
+ export interface Facet {
82
+ session_id: string
83
+ underlying_goal: string
84
+ goal_categories: Record<string, number>
85
+ outcome: string
86
+ user_satisfaction_counts: Record<string, number>
87
+ claude_helpfulness: string
88
+ session_type: string
89
+ friction_counts: Record<string, number>
90
+ friction_detail: string
91
+ primary_success: string
92
+ brief_summary: string
93
+ }
94
+
95
+ // ─── Session with Facet joined ───────────────────────────────────────────────
96
+
97
+ export interface SessionWithFacet extends SessionMeta {
98
+ facet?: Facet
99
+ estimated_cost: number
100
+ slug?: string
101
+ version?: string
102
+ git_branch?: string
103
+ has_compaction?: boolean
104
+ has_thinking?: boolean
105
+ }
106
+
107
+ // ─── Replay / JSONL ──────────────────────────────────────────────────────────
108
+
109
+ export interface TurnUsage {
110
+ input_tokens: number
111
+ output_tokens: number
112
+ cache_creation_input_tokens: number
113
+ cache_read_input_tokens: number
114
+ cache_creation?: {
115
+ ephemeral_5m_input_tokens: number
116
+ ephemeral_1h_input_tokens: number
117
+ }
118
+ service_tier?: string
119
+ inference_geo?: string
120
+ }
121
+
122
+ export interface ToolCall {
123
+ id: string
124
+ name: string
125
+ input: Record<string, unknown>
126
+ result?: string
127
+ is_error?: boolean
128
+ }
129
+
130
+ export interface ReplayTurn {
131
+ uuid: string
132
+ parentUuid: string | null
133
+ type: 'user' | 'assistant'
134
+ timestamp: string
135
+ model?: string
136
+ usage?: TurnUsage
137
+ text?: string
138
+ tool_calls?: ToolCall[]
139
+ tool_results?: Array<{ tool_use_id: string; content: string; is_error: boolean }>
140
+ has_thinking?: boolean
141
+ thinking_text?: string
142
+ estimated_cost?: number
143
+ turn_duration_ms?: number
144
+ response_time_s?: number
145
+ }
146
+
147
+ export interface CompactionEvent {
148
+ uuid: string
149
+ timestamp: string
150
+ trigger: 'auto' | 'manual'
151
+ pre_tokens: number
152
+ summary?: string
153
+ turn_index: number
154
+ }
155
+
156
+ export interface SummaryEvent {
157
+ uuid: string
158
+ summary: string
159
+ leaf_uuid: string
160
+ }
161
+
162
+ export interface ReplayData {
163
+ session_id: string
164
+ slug?: string
165
+ version?: string
166
+ git_branch?: string
167
+ turns: ReplayTurn[]
168
+ compactions: CompactionEvent[]
169
+ summaries: SummaryEvent[]
170
+ total_cost: number
171
+ }
172
+
173
+ // ─── Project Summary ──────────────────────────────────────────────────────────
174
+
175
+ export interface ProjectSummary {
176
+ slug: string
177
+ project_path: string
178
+ display_name: string
179
+ session_count: number
180
+ total_messages: number
181
+ total_duration_minutes: number
182
+ total_lines_added: number
183
+ total_lines_removed: number
184
+ total_files_modified: number
185
+ git_commits: number
186
+ git_pushes: number
187
+ estimated_cost: number
188
+ input_tokens: number
189
+ output_tokens: number
190
+ languages: Record<string, number>
191
+ tool_counts: Record<string, number>
192
+ last_active: string
193
+ first_active: string
194
+ uses_mcp: boolean
195
+ uses_task_agent: boolean
196
+ branches: string[]
197
+ }
198
+
199
+ // ─── Tool Analytics ───────────────────────────────────────────────────────────
200
+
201
+ export interface ToolSummary {
202
+ name: string
203
+ category: string
204
+ total_calls: number
205
+ session_count: number
206
+ error_count: number
207
+ }
208
+
209
+ export interface McpServerSummary {
210
+ server_name: string
211
+ tools: Array<{ name: string; calls: number }>
212
+ total_calls: number
213
+ session_count: number
214
+ }
215
+
216
+ export interface VersionRecord {
217
+ version: string
218
+ session_count: number
219
+ first_seen: string
220
+ last_seen: string
221
+ }
222
+
223
+ export interface ToolsAnalytics {
224
+ tools: ToolSummary[]
225
+ mcp_servers: McpServerSummary[]
226
+ feature_adoption: Record<string, { sessions: number; pct: number }>
227
+ versions: VersionRecord[]
228
+ branches: Array<{ branch: string; turns: number }>
229
+ error_categories: Record<string, number>
230
+ total_tool_calls: number
231
+ total_errors: number
232
+ }
233
+
234
+ // ─── Cost Analytics ───────────────────────────────────────────────────────────
235
+
236
+ export interface ModelCostBreakdown {
237
+ model: string
238
+ input_tokens: number
239
+ output_tokens: number
240
+ cache_write_tokens: number
241
+ cache_read_tokens: number
242
+ estimated_cost: number
243
+ cache_savings: number
244
+ cache_hit_rate: number
245
+ }
246
+
247
+ export interface DailyCost {
248
+ date: string
249
+ costs: Record<string, number>
250
+ total: number
251
+ }
252
+
253
+ export interface ProjectCost {
254
+ slug: string
255
+ display_name: string
256
+ estimated_cost: number
257
+ input_tokens: number
258
+ output_tokens: number
259
+ }
260
+
261
+ export interface CostAnalytics {
262
+ total_cost: number
263
+ total_savings: number
264
+ models: ModelCostBreakdown[]
265
+ daily: DailyCost[]
266
+ by_project: ProjectCost[]
267
+ }
268
+
269
+ // ─── History ──────────────────────────────────────────────────────────────────
270
+
271
+ export interface HistoryEntry {
272
+ display: string
273
+ timestamp: number
274
+ project: string
275
+ sessionId?: string
276
+ }
277
+
278
+ // ─── Export ──────────────────────────────────────────────────────────────────
279
+
280
+ export interface ExportPayload {
281
+ exportedAt: string
282
+ version: string
283
+ stats: StatsCache | null
284
+ sessions: SessionMeta[]
285
+ facets: Facet[]
286
+ history: HistoryEntry[]
287
+ }
288
+
289
+ export interface ImportDiff {
290
+ total_in_export: number
291
+ already_present: number
292
+ new_sessions: number
293
+ sessions_to_add: SessionMeta[]
294
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Agent Loader — loads custom agent definitions from .bahulam/agents/
3
+ *
4
+ * Supports two formats:
5
+ * - YAML: .bahulam/agents/*.yaml / *.yml (native Kepler SubAgent config)
6
+ * - JSON: .bahulam/agents/*.json
7
+ * - Markdown with YAML frontmatter: .bahulam/agents/*.md
8
+ *
9
+ * Agent definitions specify: name, description, model, tools, hooks, prompt.
10
+ */
11
+
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import { parseAgentDefinition } from './parser.mjs';
15
+
16
+ export class AgentLoader {
17
+ constructor() {
18
+ this.agents = new Map();
19
+ this.searchPaths = [];
20
+ }
21
+
22
+ /**
23
+ * Load agents from standard directories.
24
+ * @param {string} [cwd] - project working directory
25
+ */
26
+ load(cwd = process.cwd()) {
27
+ // Prefer .bahulam/, but also scan legacy .kepler/ so agents defined
28
+ // under the old convention keep loading for existing projects.
29
+ this.searchPaths = [
30
+ path.join(cwd, '.bahulam', 'agents'),
31
+ path.join(cwd, '.kepler', 'agents'),
32
+ path.join(process.env.HOME || '', '.bahulam', 'agents'),
33
+ path.join(process.env.HOME || '', '.kepler', 'agents'),
34
+ ];
35
+
36
+ for (const dir of this.searchPaths) {
37
+ this._loadFromDir(dir);
38
+ }
39
+
40
+ return this;
41
+ }
42
+
43
+ _loadFromDir(dir) {
44
+ try {
45
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
46
+ for (const entry of entries) {
47
+ if (!entry.isFile()) continue;
48
+ const ext = path.extname(entry.name);
49
+ if (!['.yaml', '.yml', '.json', '.md'].includes(ext)) continue;
50
+
51
+ const filePath = path.join(dir, entry.name);
52
+ try {
53
+ const content = fs.readFileSync(filePath, 'utf-8');
54
+ const agent = parseAgentDefinition(content, ext);
55
+ if (agent && agent.name && !this.agents.has(agent.name)) {
56
+ this.agents.set(agent.name, { ...agent, source: filePath });
57
+ }
58
+ } catch (err) {
59
+ if (process.env.DEBUG) {
60
+ console.error(`Failed to load agent ${filePath}: ${err.message}`);
61
+ }
62
+ }
63
+ }
64
+ } catch {
65
+ // Directory does not exist
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Get an agent definition by name.
71
+ * @param {string} name
72
+ * @returns {object|null}
73
+ */
74
+ get(name) {
75
+ return this.agents.get(name) || null;
76
+ }
77
+
78
+ /**
79
+ * List all loaded agents.
80
+ * @returns {Array<object>}
81
+ */
82
+ list() {
83
+ return [...this.agents.values()];
84
+ }
85
+
86
+ /**
87
+ * Check if an agent exists.
88
+ * @param {string} name
89
+ * @returns {boolean}
90
+ */
91
+ has(name) {
92
+ return this.agents.has(name);
93
+ }
94
+ }