@pennyfarthing/cyclist 10.4.0 → 11.0.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 (384) hide show
  1. package/dist/api/agent-load.d.ts +1 -2
  2. package/dist/api/agent-load.d.ts.map +1 -1
  3. package/dist/api/agent-load.js +2 -123
  4. package/dist/api/agent-load.js.map +1 -1
  5. package/dist/api/audit-log.d.ts +1 -17
  6. package/dist/api/audit-log.d.ts.map +1 -1
  7. package/dist/api/audit-log.js +2 -162
  8. package/dist/api/audit-log.js.map +1 -1
  9. package/dist/api/background-tasks.d.ts +1 -26
  10. package/dist/api/background-tasks.d.ts.map +1 -1
  11. package/dist/api/background-tasks.js +2 -55
  12. package/dist/api/background-tasks.js.map +1 -1
  13. package/dist/api/bell.d.ts +1 -18
  14. package/dist/api/bell.d.ts.map +1 -1
  15. package/dist/api/bell.js +2 -33
  16. package/dist/api/bell.js.map +1 -1
  17. package/dist/api/code-markers.d.ts +1 -8
  18. package/dist/api/code-markers.d.ts.map +1 -1
  19. package/dist/api/code-markers.js +2 -61
  20. package/dist/api/code-markers.js.map +1 -1
  21. package/dist/api/complexity.d.ts +1 -2
  22. package/dist/api/complexity.d.ts.map +1 -1
  23. package/dist/api/complexity.js +2 -46
  24. package/dist/api/complexity.js.map +1 -1
  25. package/dist/api/context.d.ts +1 -37
  26. package/dist/api/context.d.ts.map +1 -1
  27. package/dist/api/context.js +2 -143
  28. package/dist/api/context.js.map +1 -1
  29. package/dist/api/dead-code.d.ts +1 -2
  30. package/dist/api/dead-code.d.ts.map +1 -1
  31. package/dist/api/dead-code.js +2 -69
  32. package/dist/api/dead-code.js.map +1 -1
  33. package/dist/api/dependencies.d.ts +1 -2
  34. package/dist/api/dependencies.d.ts.map +1 -1
  35. package/dist/api/dependencies.js +2 -42
  36. package/dist/api/dependencies.js.map +1 -1
  37. package/dist/api/evaluation.d.ts +1 -19
  38. package/dist/api/evaluation.d.ts.map +1 -1
  39. package/dist/api/evaluation.js +2 -127
  40. package/dist/api/evaluation.js.map +1 -1
  41. package/dist/api/file-browser.d.ts +1 -8
  42. package/dist/api/file-browser.d.ts.map +1 -1
  43. package/dist/api/file-browser.js +2 -114
  44. package/dist/api/file-browser.js.map +1 -1
  45. package/dist/api/git.d.ts +1 -46
  46. package/dist/api/git.d.ts.map +1 -1
  47. package/dist/api/git.js +2 -354
  48. package/dist/api/git.js.map +1 -1
  49. package/dist/api/health-score.d.ts +1 -2
  50. package/dist/api/health-score.d.ts.map +1 -1
  51. package/dist/api/health-score.js +2 -46
  52. package/dist/api/health-score.js.map +1 -1
  53. package/dist/api/hook-request.d.ts +1 -40
  54. package/dist/api/hook-request.d.ts.map +1 -1
  55. package/dist/api/hook-request.js +2 -277
  56. package/dist/api/hook-request.js.map +1 -1
  57. package/dist/api/hotspots.d.ts +1 -2
  58. package/dist/api/hotspots.d.ts.map +1 -1
  59. package/dist/api/hotspots.js +2 -61
  60. package/dist/api/hotspots.js.map +1 -1
  61. package/dist/api/identity.d.ts +1 -16
  62. package/dist/api/identity.d.ts.map +1 -1
  63. package/dist/api/identity.js +2 -78
  64. package/dist/api/identity.js.map +1 -1
  65. package/dist/api/index.d.ts +1 -34
  66. package/dist/api/index.d.ts.map +1 -1
  67. package/dist/api/index.js +2 -44
  68. package/dist/api/index.js.map +1 -1
  69. package/dist/api/mode.d.ts +1 -22
  70. package/dist/api/mode.d.ts.map +1 -1
  71. package/dist/api/mode.js +2 -37
  72. package/dist/api/mode.js.map +1 -1
  73. package/dist/api/otlp.d.ts +1 -2
  74. package/dist/api/otlp.d.ts.map +1 -1
  75. package/dist/api/otlp.js +2 -46
  76. package/dist/api/otlp.js.map +1 -1
  77. package/dist/api/permissions.d.ts +1 -15
  78. package/dist/api/permissions.d.ts.map +1 -1
  79. package/dist/api/permissions.js +2 -66
  80. package/dist/api/permissions.js.map +1 -1
  81. package/dist/api/persona.d.ts +1 -8
  82. package/dist/api/persona.d.ts.map +1 -1
  83. package/dist/api/persona.js +2 -67
  84. package/dist/api/persona.js.map +1 -1
  85. package/dist/api/portrait.d.ts +1 -5
  86. package/dist/api/portrait.d.ts.map +1 -1
  87. package/dist/api/portrait.js +2 -27
  88. package/dist/api/portrait.js.map +1 -1
  89. package/dist/api/settings.d.ts +1 -53
  90. package/dist/api/settings.d.ts.map +1 -1
  91. package/dist/api/settings.js +2 -464
  92. package/dist/api/settings.js.map +1 -1
  93. package/dist/api/spans.d.ts +1 -16
  94. package/dist/api/spans.d.ts.map +1 -1
  95. package/dist/api/spans.js +2 -244
  96. package/dist/api/spans.js.map +1 -1
  97. package/dist/api/stats.d.ts +1 -12
  98. package/dist/api/stats.d.ts.map +1 -1
  99. package/dist/api/stats.js +2 -84
  100. package/dist/api/stats.js.map +1 -1
  101. package/dist/api/story.d.ts +1 -2
  102. package/dist/api/story.d.ts.map +1 -1
  103. package/dist/api/story.js +2 -14
  104. package/dist/api/story.js.map +1 -1
  105. package/dist/api/telemetry.d.ts +1 -18
  106. package/dist/api/telemetry.d.ts.map +1 -1
  107. package/dist/api/telemetry.js +2 -164
  108. package/dist/api/telemetry.js.map +1 -1
  109. package/dist/api/theme-agents.d.ts +1 -60
  110. package/dist/api/theme-agents.d.ts.map +1 -1
  111. package/dist/api/theme-agents.js +2 -213
  112. package/dist/api/theme-agents.js.map +1 -1
  113. package/dist/api/todos.d.ts +1 -32
  114. package/dist/api/todos.d.ts.map +1 -1
  115. package/dist/api/todos.js +2 -43
  116. package/dist/api/todos.js.map +1 -1
  117. package/dist/api/token-stats.d.ts +1 -7
  118. package/dist/api/token-stats.d.ts.map +1 -1
  119. package/dist/api/token-stats.js +2 -35
  120. package/dist/api/token-stats.js.map +1 -1
  121. package/dist/api/welcome.d.ts +1 -21
  122. package/dist/api/welcome.d.ts.map +1 -1
  123. package/dist/api/welcome.js +2 -34
  124. package/dist/api/welcome.js.map +1 -1
  125. package/dist/bikerack.js +2 -2
  126. package/dist/bikerack.js.map +1 -1
  127. package/dist/env.d.ts +6 -0
  128. package/dist/env.d.ts.map +1 -0
  129. package/dist/env.js +10 -0
  130. package/dist/env.js.map +1 -0
  131. package/dist/focus.d.ts +53 -0
  132. package/dist/focus.d.ts.map +1 -0
  133. package/dist/focus.js +122 -0
  134. package/dist/focus.js.map +1 -0
  135. package/dist/git-cache.d.ts +1 -0
  136. package/dist/git-cache.d.ts.map +1 -1
  137. package/dist/git-cache.js +3 -1
  138. package/dist/git-cache.js.map +1 -1
  139. package/dist/menu-builder.d.ts.map +1 -1
  140. package/dist/menu-builder.js +0 -1
  141. package/dist/menu-builder.js.map +1 -1
  142. package/dist/prime.d.ts +3 -3
  143. package/dist/prime.d.ts.map +1 -1
  144. package/dist/prime.js +38 -14
  145. package/dist/prime.js.map +1 -1
  146. package/dist/public/css/react.css +1 -1
  147. package/dist/public/js/react/react.js +53 -61
  148. package/dist/server.d.ts +18 -85
  149. package/dist/server.d.ts.map +1 -1
  150. package/dist/server.js +105 -405
  151. package/dist/server.js.map +1 -1
  152. package/dist/sprint-data.d.ts +1 -1
  153. package/dist/sprint-data.d.ts.map +1 -1
  154. package/dist/sprint-data.js +2 -2
  155. package/dist/sprint-data.js.map +1 -1
  156. package/dist/theme-metadata.d.ts +3 -3
  157. package/dist/theme-metadata.d.ts.map +1 -1
  158. package/dist/theme-metadata.js +4 -4
  159. package/dist/theme-metadata.js.map +1 -1
  160. package/dist/websocket.d.ts +2 -0
  161. package/dist/websocket.d.ts.map +1 -1
  162. package/dist/websocket.js +53 -75
  163. package/dist/websocket.js.map +1 -1
  164. package/package.json +2 -6
  165. package/portraits/hogans-heroes/large/burkhalter-35312.png +0 -0
  166. package/portraits/hogans-heroes/large/carter-34352.png +0 -0
  167. package/portraits/hogans-heroes/large/hochstetter-45314.png +0 -0
  168. package/portraits/hogans-heroes/large/hogan-44541.png +0 -0
  169. package/portraits/hogans-heroes/large/kinch-35241.png +0 -0
  170. package/portraits/hogans-heroes/large/klink-23434.png +0 -0
  171. package/portraits/hogans-heroes/large/lebeau-45443.png +0 -0
  172. package/portraits/hogans-heroes/large/marya-53543.png +0 -0
  173. package/portraits/hogans-heroes/large/newkirk-54432.png +0 -0
  174. package/portraits/hogans-heroes/large/schultz-42453.png +0 -0
  175. package/portraits/hogans-heroes/large/underground-55131.png +0 -0
  176. package/portraits/hogans-heroes/medium/burkhalter-35312.png +0 -0
  177. package/portraits/hogans-heroes/medium/carter-34352.png +0 -0
  178. package/portraits/hogans-heroes/medium/hochstetter-45314.png +0 -0
  179. package/portraits/hogans-heroes/medium/hogan-44541.png +0 -0
  180. package/portraits/hogans-heroes/medium/kinch-35241.png +0 -0
  181. package/portraits/hogans-heroes/medium/klink-23434.png +0 -0
  182. package/portraits/hogans-heroes/medium/lebeau-45443.png +0 -0
  183. package/portraits/hogans-heroes/medium/marya-53543.png +0 -0
  184. package/portraits/hogans-heroes/medium/newkirk-54432.png +0 -0
  185. package/portraits/hogans-heroes/medium/schultz-42453.png +0 -0
  186. package/portraits/hogans-heroes/medium/underground-55131.png +0 -0
  187. package/portraits/monty-python/large/announcer-44441.png +0 -0
  188. package/portraits/monty-python/large/arguer-35412.png +0 -0
  189. package/portraits/monty-python/large/bicycle-repair-man-35241.png +0 -0
  190. package/portraits/monty-python/large/colonel-35423.png +0 -0
  191. package/portraits/monty-python/large/counsellor-45341.png +0 -0
  192. package/portraits/monty-python/large/gumbys-23524.png +0 -0
  193. package/portraits/monty-python/large/nudge-43533.png +0 -0
  194. package/portraits/monty-python/large/praline-45413.png +0 -0
  195. package/portraits/monty-python/large/silly-walks-55322.png +0 -0
  196. package/portraits/monty-python/large/wensleydale-54451.png +0 -0
  197. package/portraits/monty-python/large/xim-nez-43534.png +0 -0
  198. package/portraits/monty-python/medium/announcer-44441.png +0 -0
  199. package/portraits/monty-python/medium/arguer-35412.png +0 -0
  200. package/portraits/monty-python/medium/bicycle-repair-man-35241.png +0 -0
  201. package/portraits/monty-python/medium/colonel-35423.png +0 -0
  202. package/portraits/monty-python/medium/counsellor-45341.png +0 -0
  203. package/portraits/monty-python/medium/gumbys-23524.png +0 -0
  204. package/portraits/monty-python/medium/nudge-43533.png +0 -0
  205. package/portraits/monty-python/medium/praline-45413.png +0 -0
  206. package/portraits/monty-python/medium/silly-walks-55322.png +0 -0
  207. package/portraits/monty-python/medium/wensleydale-54451.png +0 -0
  208. package/portraits/monty-python/medium/xim-nez-43534.png +0 -0
  209. package/portraits/stephen-king/large/andy-55231.png +0 -0
  210. package/portraits/stephen-king/large/christine-25112.png +0 -0
  211. package/portraits/stephen-king/large/danny-53243.png +0 -0
  212. package/portraits/stephen-king/large/flagg-55311.png +0 -0
  213. package/portraits/stephen-king/large/gaunt-54421.png +0 -0
  214. package/portraits/stephen-king/large/jack-44224.png +0 -0
  215. package/portraits/stephen-king/large/johnny-44353.png +0 -0
  216. package/portraits/stephen-king/large/margaret-15415.png +0 -0
  217. package/portraits/stephen-king/large/paul-45233.png +0 -0
  218. package/portraits/stephen-king/large/pennywise-54411.png +0 -0
  219. package/portraits/stephen-king/large/roland-35121.png +0 -0
  220. package/portraits/stephen-king/medium/andy-55231.png +0 -0
  221. package/portraits/stephen-king/medium/christine-25112.png +0 -0
  222. package/portraits/stephen-king/medium/danny-53243.png +0 -0
  223. package/portraits/stephen-king/medium/flagg-55311.png +0 -0
  224. package/portraits/stephen-king/medium/gaunt-54421.png +0 -0
  225. package/portraits/stephen-king/medium/jack-44224.png +0 -0
  226. package/portraits/stephen-king/medium/johnny-44353.png +0 -0
  227. package/portraits/stephen-king/medium/margaret-15415.png +0 -0
  228. package/portraits/stephen-king/medium/paul-45233.png +0 -0
  229. package/portraits/stephen-king/medium/pennywise-54411.png +0 -0
  230. package/portraits/stephen-king/medium/roland-35121.png +0 -0
  231. package/portraits/star-trek-tng/large/beverly-44352.png +0 -0
  232. package/portraits/star-trek-tng/large/data-55241.png +0 -0
  233. package/portraits/star-trek-tng/large/deanna-43353.png +0 -0
  234. package/portraits/star-trek-tng/large/geordi-54342.png +0 -0
  235. package/portraits/star-trek-tng/large/jean-luc-45342.png +0 -0
  236. package/portraits/star-trek-tng/large/kathryn-45332.png +0 -0
  237. package/portraits/star-trek-tng/large/miles-35342.png +0 -0
  238. package/portraits/star-trek-tng/large/q-53521.png +0 -0
  239. package/portraits/star-trek-tng/large/spock-45231.png +0 -0
  240. package/portraits/star-trek-tng/large/troi-44352.png +0 -0
  241. package/portraits/star-trek-tng/medium/beverly-44352.png +0 -0
  242. package/portraits/star-trek-tng/medium/data-55241.png +0 -0
  243. package/portraits/star-trek-tng/medium/deanna-43353.png +0 -0
  244. package/portraits/star-trek-tng/medium/geordi-54342.png +0 -0
  245. package/portraits/star-trek-tng/medium/jean-luc-45342.png +0 -0
  246. package/portraits/star-trek-tng/medium/kathryn-45332.png +0 -0
  247. package/portraits/star-trek-tng/medium/miles-35342.png +0 -0
  248. package/portraits/star-trek-tng/medium/q-53521.png +0 -0
  249. package/portraits/star-trek-tng/medium/spock-45231.png +0 -0
  250. package/portraits/star-trek-tng/medium/troi-44352.png +0 -0
  251. package/src/public/App.tsx +0 -340
  252. package/src/public/components/AgentLoadDialog.tsx +0 -202
  253. package/src/public/components/AgentPopup.tsx +0 -308
  254. package/src/public/components/ApprovalModal/ApprovalModal.css +0 -35
  255. package/src/public/components/ApprovalModal/index.tsx +0 -632
  256. package/src/public/components/BikeRackIndex.tsx +0 -54
  257. package/src/public/components/BikeRackWorkspace.tsx +0 -142
  258. package/src/public/components/CommandPalette.tsx +0 -555
  259. package/src/public/components/ConfirmDialog.tsx +0 -168
  260. package/src/public/components/ContextIndicator/ContextIndicator.css +0 -85
  261. package/src/public/components/ContextIndicator/index.tsx +0 -330
  262. package/src/public/components/ContextSparkline.tsx +0 -56
  263. package/src/public/components/ControlBar.tsx +0 -636
  264. package/src/public/components/DeadCodeDialog.tsx +0 -169
  265. package/src/public/components/DiffViewer.tsx +0 -585
  266. package/src/public/components/DockviewWorkspace.tsx +0 -737
  267. package/src/public/components/Editor.tsx +0 -630
  268. package/src/public/components/ErrorBoundary.tsx +0 -67
  269. package/src/public/components/FileTree.tsx +0 -379
  270. package/src/public/components/FontPicker/FontPicker.css +0 -276
  271. package/src/public/components/FontPicker/index.tsx +0 -430
  272. package/src/public/components/FullFileTree.tsx +0 -237
  273. package/src/public/components/HealthGauge.tsx +0 -181
  274. package/src/public/components/Message.tsx +0 -225
  275. package/src/public/components/MessageList.tsx +0 -98
  276. package/src/public/components/MessageView.tsx +0 -400
  277. package/src/public/components/ModeSwitch/ModeSwitch.css +0 -165
  278. package/src/public/components/ModeSwitch/index.tsx +0 -372
  279. package/src/public/components/PersonaHeader.tsx +0 -240
  280. package/src/public/components/QuickActions.tsx +0 -267
  281. package/src/public/components/SpanTimeline.tsx +0 -352
  282. package/src/public/components/StandalonePanel.tsx +0 -84
  283. package/src/public/components/StatsStrip.tsx +0 -162
  284. package/src/public/components/StreamingContent.tsx +0 -77
  285. package/src/public/components/SubagentSpan.tsx +0 -180
  286. package/src/public/components/TandemPortrait.tsx +0 -72
  287. package/src/public/components/ThemePalette/ThemePalette.css +0 -179
  288. package/src/public/components/ThemePalette/index.tsx +0 -326
  289. package/src/public/components/ToolCallBlock.tsx +0 -252
  290. package/src/public/components/ToolStack.tsx +0 -209
  291. package/src/public/components/ToolStatus.tsx +0 -57
  292. package/src/public/components/dialogs/CodeMarkersDialog.tsx +0 -169
  293. package/src/public/components/dialogs/ComplexityDialog.tsx +0 -163
  294. package/src/public/components/dialogs/DependenciesDialog.tsx +0 -120
  295. package/src/public/components/dialogs/HotspotsDialog.tsx +0 -451
  296. package/src/public/components/dialogs/ToolDialog.tsx +0 -43
  297. package/src/public/components/panel-registry.ts +0 -11
  298. package/src/public/components/panels/ACPanel.tsx +0 -93
  299. package/src/public/components/panels/AcceptanceCriteriaPanel.tsx +0 -104
  300. package/src/public/components/panels/AuditLogPanel.tsx +0 -465
  301. package/src/public/components/panels/BackgroundPanel.tsx +0 -115
  302. package/src/public/components/panels/BikeLanePanel.tsx +0 -214
  303. package/src/public/components/panels/ChangedPanel.tsx +0 -65
  304. package/src/public/components/panels/DebugPanel.tsx +0 -344
  305. package/src/public/components/panels/DiffsPanel.tsx +0 -155
  306. package/src/public/components/panels/GitPanel.tsx +0 -216
  307. package/src/public/components/panels/HotspotsPanel.tsx +0 -365
  308. package/src/public/components/panels/MessagePanel.tsx +0 -497
  309. package/src/public/components/panels/SettingsPanel.tsx +0 -453
  310. package/src/public/components/panels/SprintPanel.tsx +0 -670
  311. package/src/public/components/panels/TTYPanel.tsx +0 -299
  312. package/src/public/components/panels/TodoPanel.tsx +0 -142
  313. package/src/public/components/panels/WorkflowPanel.tsx +0 -224
  314. package/src/public/components/panels/index.ts +0 -24
  315. package/src/public/components/ui/alert-dialog.tsx +0 -139
  316. package/src/public/components/ui/badge.tsx +0 -36
  317. package/src/public/components/ui/button.tsx +0 -57
  318. package/src/public/components/ui/checkbox.tsx +0 -28
  319. package/src/public/components/ui/collapsible.tsx +0 -9
  320. package/src/public/components/ui/command.tsx +0 -151
  321. package/src/public/components/ui/dialog.tsx +0 -120
  322. package/src/public/components/ui/popover.tsx +0 -31
  323. package/src/public/components/ui/progress.tsx +0 -28
  324. package/src/public/components/ui/scroll-area.tsx +0 -46
  325. package/src/public/components/ui/select.tsx +0 -157
  326. package/src/public/components/ui/separator.tsx +0 -29
  327. package/src/public/components/ui/skeleton.tsx +0 -15
  328. package/src/public/components/ui/switch.tsx +0 -27
  329. package/src/public/components/ui/toggle-group.tsx +0 -59
  330. package/src/public/components/ui/toggle.tsx +0 -43
  331. package/src/public/components/ui/tooltip.tsx +0 -30
  332. package/src/public/contexts/ClaudeContext.tsx +0 -311
  333. package/src/public/contexts/MessageQueueContext.tsx +0 -143
  334. package/src/public/css/theme-browser.css +0 -550
  335. package/src/public/css/theme-system.css +0 -630
  336. package/src/public/hooks/index.ts +0 -49
  337. package/src/public/hooks/useAgentLoad.ts +0 -105
  338. package/src/public/hooks/useBackgroundTasks.ts +0 -131
  339. package/src/public/hooks/useClaude.ts +0 -234
  340. package/src/public/hooks/useCodeMarkers.ts +0 -101
  341. package/src/public/hooks/useColorScheme.ts +0 -42
  342. package/src/public/hooks/useCommandHistory.ts +0 -99
  343. package/src/public/hooks/useComplexity.ts +0 -80
  344. package/src/public/hooks/useDeadCode.ts +0 -99
  345. package/src/public/hooks/useDependencies.ts +0 -82
  346. package/src/public/hooks/useDiffs.ts +0 -143
  347. package/src/public/hooks/useFileBrowser.ts +0 -71
  348. package/src/public/hooks/useGitStatus.ts +0 -233
  349. package/src/public/hooks/useHealthScore.ts +0 -69
  350. package/src/public/hooks/useHotspots.ts +0 -123
  351. package/src/public/hooks/useLayoutPersistence.ts +0 -138
  352. package/src/public/hooks/useMarkdownParser.ts +0 -36
  353. package/src/public/hooks/useMarkerActions.ts +0 -234
  354. package/src/public/hooks/useMessageQueue.ts +0 -380
  355. package/src/public/hooks/useMessageStream.ts +0 -131
  356. package/src/public/hooks/usePersona.ts +0 -112
  357. package/src/public/hooks/usePlanModeExit.ts +0 -105
  358. package/src/public/hooks/useResponsiveLayout.ts +0 -173
  359. package/src/public/hooks/useSprint.ts +0 -147
  360. package/src/public/hooks/useStatsStrip.ts +0 -204
  361. package/src/public/hooks/useStory.ts +0 -135
  362. package/src/public/hooks/useSubagentHelper.ts +0 -64
  363. package/src/public/hooks/useSyntaxHighlighter.ts +0 -52
  364. package/src/public/hooks/useTabCompletion.ts +0 -124
  365. package/src/public/hooks/useTodos.ts +0 -93
  366. package/src/public/hooks/useUserAvatar.ts +0 -54
  367. package/src/public/index.tsx +0 -10
  368. package/src/public/lib/utils.ts +0 -6
  369. package/src/public/styles/dockview-theme.css +0 -459
  370. package/src/public/styles/tailwind.css +0 -4396
  371. package/src/public/types/electron.d.ts +0 -18
  372. package/src/public/types/message.ts +0 -51
  373. package/src/public/utils/avatar-service.ts +0 -73
  374. package/src/public/utils/color-presets.ts +0 -940
  375. package/src/public/utils/font-presets.ts +0 -362
  376. package/src/public/utils/formatDuration.ts +0 -14
  377. package/src/public/utils/markdown.ts +0 -249
  378. package/src/public/utils/messageFilters.ts +0 -128
  379. package/src/public/utils/slash-commands.ts +0 -353
  380. package/src/public/utils/subagent-display.ts +0 -146
  381. package/src/public/utils/syntax.ts +0 -219
  382. package/src/public/utils/toolIntentSummarizer.ts +0 -199
  383. package/src/public/utils/toolStackGrouper.ts +0 -106
  384. package/src/public/utils/toolTypeColors.ts +0 -45
package/dist/server.d.ts CHANGED
@@ -1,90 +1,23 @@
1
- import { Express } from 'express';
2
- import { Server } from 'http';
3
- export { broadcastStats } from './api/index.js';
4
- export { getStoryInfo } from './story-parser.js';
5
- export type { StoryInfo, WorkflowStep, CriteriaItem } from './story-parser.js';
6
- export { getGitInfo, getAllReposGitInfo, getAllReposGitInfoAsync } from './api/index.js';
7
- export type { GitInfo } from './api/index.js';
8
- export declare function isBikeRackMode(): boolean;
9
- export declare const app: Express;
10
- export declare function createTerminalServer(): Server;
11
- /**
12
- * Find an available port starting from the given port.
13
- * Tries ports sequentially until one is available or maxAttempts reached.
14
- * Used by both Electron mode and standalone server mode.
15
- */
16
- export declare function findAvailablePort(startPort: number, maxAttempts?: number): Promise<number>;
17
- /**
18
- * Write the server port to a .cyclist-port file for auto-discovery.
19
- * Called when Cyclist server starts to enable hook-based OTEL configuration.
20
- */
21
- export declare function writePortFile(projectDir: string, port: number): void;
22
- /**
23
- * Remove the .cyclist-port file during shutdown.
24
- * Prevents stale port files from pointing to non-existent servers.
25
- */
26
- export declare function cleanupPortFile(projectDir: string): void;
27
- /**
28
- * Read the port number from .cyclist-port file.
29
- * Returns null if file doesn't exist, is empty, or contains invalid content.
30
- */
31
- export declare function readPortFile(projectDir: string): number | null;
32
- /**
33
- * Write the approval server port to .cyclist-approval-port file.
34
- * Enables hook script to discover which port this instance is using.
35
- */
36
- export declare function writeApprovalPortFile(projectDir: string, port: number): void;
37
- /**
38
- * Remove the .cyclist-approval-port file during shutdown.
39
- * Prevents stale port files from causing cross-instance interference.
40
- */
41
- export declare function cleanupApprovalPortFile(projectDir: string): void;
42
- /**
43
- * Read the approval server port from .cyclist-approval-port file.
44
- * Returns null if file doesn't exist or contains invalid content.
45
- */
46
- export declare function readApprovalPortFile(projectDir: string): number | null;
47
1
  /**
48
- * Write the Claude process PID to .cyclist-pid file.
49
- * Used to track which Claude process belongs to this Cyclist instance.
50
- */
51
- export declare function writePidFile(projectDir: string, pid: number): void;
52
- /**
53
- * Remove the .cyclist-pid file during shutdown.
54
- * Prevents stale PID files from causing incorrect process termination.
55
- */
56
- export declare function cleanupPidFile(projectDir: string): void;
57
- /**
58
- * Read the PID from .cyclist-pid file.
59
- * Returns null if file doesn't exist, is empty, or contains invalid content.
60
- */
61
- export declare function readPidFile(projectDir: string): number | null;
62
- /**
63
- * Check if a process with the given PID is still running.
64
- * Returns true if process exists, false otherwise.
65
- */
66
- export declare function isProcessRunning(pid: number): boolean;
67
- /**
68
- * OTEL configuration type for Claude Code telemetry
69
- * Extends Record<string, string> for compatibility with process.env spreading
70
- */
71
- export interface OtelConfig extends Record<string, string> {
72
- CLAUDE_CODE_ENABLE_TELEMETRY: string;
73
- OTEL_LOGS_EXPORTER: string;
74
- OTEL_METRICS_EXPORTER: string;
75
- OTEL_EXPORTER_OTLP_PROTOCOL: string;
76
- OTEL_EXPORTER_OTLP_ENDPOINT: string;
77
- }
78
- /**
79
- * Get OTEL configuration environment variables based on port file.
80
- * Returns null if no valid port file exists.
2
+ * Server module for Cyclist.
3
+ *
4
+ * Thin wrapper around @pennyfarthing/core/server that overrides
5
+ * createTerminalServer to use Cyclist's real WebSocket implementation
6
+ * and wires the real OTLP receiver into core's API routes.
81
7
  *
82
- * Claude Code requires explicit opt-in for telemetry:
83
- * - CLAUDE_CODE_ENABLE_TELEMETRY=1 to enable telemetry
84
- * - OTEL_LOGS_EXPORTER=otlp to export tool events
85
- * - OTEL_METRICS_EXPORTER=otlp to export token metrics
8
+ * All Express app configuration, API routes, settings initialization,
9
+ * and utility functions are provided by core. Cyclist adds WebSocket support
10
+ * and the real OTLP data source.
86
11
  *
87
- * @see https://code.claude.com/docs/en/monitoring-usage
12
+ * Story 98-17: Move web server and API layer into core.
88
13
  */
89
- export declare function getOtelConfig(projectDir: string): OtelConfig | null;
14
+ import { type Server } from 'http';
15
+ /**
16
+ * Create HTTP server with Cyclist's WebSocket support.
17
+ * Overrides core's no-op WebSocket stub with the real implementation
18
+ * that handles stats, persona, token-stats, bell, welcome, hooks, etc.
19
+ */
20
+ export declare function createTerminalServer(): Server;
21
+ export { app, getProjectDir, broadcastStats, getStoryInfo, getGitInfo, getAllReposGitInfo, getAllReposGitInfoAsync, publicDir, nodeModulesDir, portraitsDir, getProjectDirectory, getDistDir, setProjectDirectory, resetProjectDirectory, parseProjectDirArg, isValidProjectDirectory, findAvailablePort, writePortFile, cleanupPortFile, readPortFile, writeApprovalPortFile, cleanupApprovalPortFile, readApprovalPortFile, writePidFile, cleanupPidFile, readPidFile, isProcessRunning, getOtelConfig, isBikeRackMode, clearSessionGrants, } from '@pennyfarthing/core/server';
22
+ export type { StoryInfo, WorkflowStep, CriteriaItem, GitInfo, OtelConfig, } from '@pennyfarthing/core/server';
90
23
  //# sourceMappingURL=server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAgB,MAAM,EAAE,MAAM,MAAM,CAAC;AAqD5C,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzF,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAI9C,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,eAAO,MAAM,GAAG,EAAE,OAAmB,CAAC;AAkLtC,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAqDD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAoB5F;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAGpE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAKxD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB9D;AAOD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG5E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAKhE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoBtE;AAOD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAGlE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAKvD;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAoB7D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQrD;AAED;;;GAGG;AACH,MAAM,WAAW,UAAW,SAAQ,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IACxD,4BAA4B,EAAE,MAAM,CAAC;IACrC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,2BAA2B,EAAE,MAAM,CAAC;IACpC,2BAA2B,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAiBnE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,MAAM,CAAC;AA4GjD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAOD,OAAO,EACL,GAAG,EACH,aAAa,EAEb,cAAc,EACd,YAAY,EACZ,UAAU,EACV,kBAAkB,EAClB,uBAAuB,EAEvB,SAAS,EACT,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,UAAU,EACV,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EAEvB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,YAAY,EACZ,qBAAqB,EACrB,uBAAuB,EACvB,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,gBAAgB,EAEhB,aAAa,EAEb,cAAc,EAEd,kBAAkB,GACnB,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EACV,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,OAAO,EACP,UAAU,GACX,MAAM,4BAA4B,CAAC"}
package/dist/server.js CHANGED
@@ -1,417 +1,117 @@
1
- import express from 'express';
2
- import { fileURLToPath } from 'url';
1
+ /**
2
+ * Server module for Cyclist.
3
+ *
4
+ * Thin wrapper around @pennyfarthing/core/server that overrides
5
+ * createTerminalServer to use Cyclist's real WebSocket implementation
6
+ * and wires the real OTLP receiver into core's API routes.
7
+ *
8
+ * All Express app configuration, API routes, settings initialization,
9
+ * and utility functions are provided by core. Cyclist adds WebSocket support
10
+ * and the real OTLP data source.
11
+ *
12
+ * Story 98-17: Move web server and API layer into core.
13
+ */
3
14
  import { createServer } from 'http';
4
- import { join } from 'path';
5
- import { existsSync, writeFileSync, unlinkSync, readFileSync } from 'fs';
6
- // Path resolution
7
- import { publicDir, nodeModulesDir, portraitsDir, getProjectDirectory, getDistDir } from './paths.js';
8
- // API routers
9
- import { createStatsRouter, createPortraitRouter, createPersonaRouter, createGitRouter, createOTLPRouter, createStoryRouter, createFileBrowserRouter, createTokenStatsRouter, createContextRouter, createThemeAgentsRouter, createModeRouter, createTelemetryRouter, createEvaluationRouter, createSettingsRouter, initTokenStatsBroadcast, createBackgroundTasksRouter, initBackgroundTaskBroadcast, createSpansRouter, createHookRequestRouter, createIdentityRouter, createTodosRouter, createHotspotsRouter, createCodeMarkersRouter, createPermissionsRouter, createAgentLoadRouter, createDeadCodeRouter, createComplexityRouter, createDependenciesRouter, createHealthScoreRouter, } from './api/index.js';
10
- // Settings initialization (35-6: required for font settings persistence)
11
- import { initializeSettings, loadGrants, saveGrants } from './settings.js';
12
- // Grant initialization (MSSCI-14321: grants must be available in standalone server mode)
13
- import { initializeGrants, setGrantsPersistCallback, clearSessionGrants } from './settings-store.js';
14
- // WebSocket setup
15
+ // Import core's pre-configured Express app, project dir helper, and OTLP provider setter
16
+ import { app, getProjectDir, setOTLPProvider, initTokenStatsBroadcast, initBackgroundTaskBroadcast, } from '@pennyfarthing/core/server';
17
+ // Import Cyclist's real WebSocket implementation (1600+ lines)
18
+ // Core has a no-op stub; Cyclist provides the real thing with 15+ channel handlers
15
19
  import { setupWebSocketServers } from './websocket.js';
16
- // Plugin router loading (Story 93-6)
17
- import { initPluginRouters } from './plugin-loader.js';
18
- // Re-exports for main.ts and tests
19
- export { broadcastStats } from './api/index.js';
20
- export { getStoryInfo } from './story-parser.js';
21
- export { getGitInfo, getAllReposGitInfo, getAllReposGitInfoAsync } from './api/index.js';
22
- // BikeRack mode detection (ADR-0024, Rule 1)
23
- // Centralized gate all mode checks go through this function
24
- export function isBikeRackMode() {
25
- return process.env.IS_BIKERACK === '1';
26
- }
27
- export const app = express();
28
- // Parse JSON bodies
29
- app.use(express.json());
30
- // Serve portraits from Pennyfarthing package (must be before general static)
31
- if (portraitsDir) {
32
- app.use('/portraits', express.static(portraitsDir));
33
- }
34
- // Serve static files from public directory
35
- app.use(express.static(publicDir));
36
- // Serve Vite build output (React components) from dist/public
37
- // This is separate from src/public to avoid Vite overwriting source files
38
- const distPublicDir = join(getDistDir(), 'public');
39
- if (existsSync(distPublicDir)) {
40
- app.use(express.static(distPublicDir));
41
- }
42
- // Serve node_modules for client-side imports (xterm.js)
43
- app.use('/node_modules', express.static(nodeModulesDir));
44
- // Health check endpoint (used by hooks to verify WheelHub is running)
45
- app.get('/health', (_req, res) => {
46
- res.json({ status: 'ok' });
47
- });
48
- // Serve index.html for root route
49
- app.get('/', (_req, res) => {
50
- res.sendFile(join(publicDir, 'index.html'));
51
- });
52
- // BikeRack index page (MSSCI-14822) — serves SPA, React handles routing
53
- app.get('/bikerack', (_req, res) => {
54
- res.sendFile(join(publicDir, 'index.html'));
55
- });
56
- // Serve pennyfarthing logo from project root (for welcome message)
57
- app.get('/pennyfarthing-transparent.png', (_req, res) => {
58
- const projectDir = getProjectDirectory() || process.cwd();
59
- const logoPath = join(projectDir, 'pennyfarthing-transparent.png');
60
- res.sendFile(logoPath, (err) => {
61
- if (err) {
62
- res.status(404).send('Logo not found');
63
- }
64
- });
65
- });
66
- // Wrapper that provides fallback to cwd for standalone server mode
67
- function getProjectDir() {
68
- return getProjectDirectory() || process.cwd();
20
+ // Import real OTLP functions from Cyclist's otlp-receiver (~1000 lines)
21
+ import { getTokenStats as realGetTokenStats, addTokenStatsListener as realAddTokenStatsListener, getBackgroundTasks as realGetBackgroundTasks, setBackgroundTaskStartCallback as realSetBackgroundTaskStartCallback, setBackgroundTaskCallback as realSetBackgroundTaskCallback, parseOTLPLogs, processLogEvents, parseOTLPMetrics, aggregateTokenStats, getToolEvents, getToolEventsFiltered as realGetToolEventsFiltered, getToolTypes as realGetToolTypes, getAuditLogStats as realGetAuditLogStats, exportAuditLogAsJSON as realExportAuditLogAsJSON, exportAuditLogAsCSV as realExportAuditLogAsCSV, resetEventStore as realResetEventStore, } from './otlp-receiver.js';
22
+ // Wire the real OTLP implementation into core's API route stubs.
23
+ // Core's server.ts calls initTokenStatsBroadcast() and initBackgroundTaskBroadcast()
24
+ // at module load (before this runs), so those first calls hit the stub (no-ops).
25
+ // After setting the provider, we re-call both to register the real broadcast callbacks.
26
+ //
27
+ // Note: Cyclist's TokenStats/ToolEvent types are structurally compatible with core's
28
+ // but TypeScript sees them as distinct nominal types. The provider cast is safe because
29
+ // cyclist's types are supersets of core's (more fields, same base shape).
30
+ // Map cyclist's TokenStats (totalCostUsd, lastUpdated) to core's (totalCost, index sig)
31
+ function mapTokenStats(stats) {
32
+ return {
33
+ inputTokens: stats.inputTokens,
34
+ outputTokens: stats.outputTokens,
35
+ cacheCreationTokens: stats.cacheCreationTokens,
36
+ cacheReadTokens: stats.cacheReadTokens,
37
+ totalCost: stats.totalCostUsd,
38
+ lastUpdated: stats.lastUpdated,
39
+ };
69
40
  }
70
- // Initialize settings from file (35-6: required for font settings persistence)
71
- // Must happen before settings router is used
72
- initializeSettings(getProjectDir());
73
- // Initialize grants for standalone server mode (MSSCI-14321)
74
- // In Electron mode, main.ts handles this. In standalone/web mode, we do it here.
75
- const grants = loadGrants();
76
- initializeGrants(grants);
77
- setGrantsPersistCallback(saveGrants);
78
- // Mount API routers
79
- app.use('/api/stats', createStatsRouter());
80
- app.use('/api/portrait', createPortraitRouter());
81
- app.use('/api/persona', createPersonaRouter(getProjectDir));
82
- app.use('/api/story', createStoryRouter(getProjectDir));
83
- app.use('/api/git', createGitRouter(getProjectDir));
84
- app.use('/api/files', createFileBrowserRouter(getProjectDir));
85
- app.use('/api/token-stats', createTokenStatsRouter());
86
- app.use('/api/context', createContextRouter(getProjectDir));
87
- app.use('/api/theme-agents', createThemeAgentsRouter(getProjectDir));
88
- app.use('/api/mode', createModeRouter());
89
- app.use('/api/telemetry', createTelemetryRouter());
90
- app.use('/api/evaluation', createEvaluationRouter());
91
- // 35-1: Settings API for contextual settings
92
- app.use('/api/settings', createSettingsRouter());
93
- // 35-16: Background tasks API
94
- app.use('/api/background-tasks', createBackgroundTasksRouter());
95
- // MSSCI-11734: Enriched spans API
96
- app.use('/api/spans', createSpansRouter());
97
- // MSSCI-12409: Hook request API (WheelHub consolidation)
98
- app.use('/api/hook-request', createHookRequestRouter());
99
- // MSSCI-12469: Identity API for stats strip
100
- app.use('/api/identity', createIdentityRouter());
101
- // Todos API for web mode fallback
102
- app.use('/api/todos', createTodosRouter());
103
- // Audit log API
104
- import { createAuditLogRouter } from './api/audit-log.js';
105
- app.use('/api/audit-log', createAuditLogRouter());
106
- // MSSCI-14325: Permissions API (grant management)
107
- app.use('/api/permissions', createPermissionsRouter());
108
- // Hotspot analysis API
109
- app.use('/api/hotspots', createHotspotsRouter(getProjectDir));
110
- // MSSCI-14456: Code Markers API
111
- app.use('/api/code-markers', createCodeMarkersRouter(getProjectDir));
112
- // MSSCI-14460: Dead Code API
113
- app.use('/api/dead-code', createDeadCodeRouter(getProjectDir));
114
- // MSSCI-14461: Agent Load Analyzer
115
- app.use('/api/agent-load', createAgentLoadRouter(getProjectDir));
116
- // MSSCI-14468: Complexity + Dependencies APIs
117
- app.use('/api/complexity', createComplexityRouter(getProjectDir));
118
- app.use('/api/dependencies', createDependenciesRouter(getProjectDir));
119
- // MSSCI-14471: Health Score API
120
- app.use('/api/health-score', createHealthScoreRouter(getProjectDir));
121
- // Welcome message endpoint (triggered by SessionStart hook)
122
- // Broadcasts welcome message to /ws/welcome channel for Cyclist display
123
- import { broadcastWelcome } from './api/welcome.js';
124
- app.post('/api/welcome', (req, res) => {
125
- const { project, theme } = req.body || {};
126
- try {
127
- broadcastWelcome({ project: project || '', theme: theme || '' });
128
- res.json({ ok: true });
129
- }
130
- catch (err) {
131
- console.error('[Welcome] Broadcast error:', err);
132
- res.status(500).json({ error: 'Failed to broadcast welcome' });
133
- }
134
- });
135
- // MSSCI-12275: Bell mode queue sync endpoint
136
- // Writes message queue to .pennyfarthing/bell-queue.json for PostToolUse hook
137
- app.post('/api/bell-queue', (req, res) => {
138
- const projectDir = getProjectDir();
139
- const queuePath = join(projectDir, '.pennyfarthing', 'bell-queue.json');
140
- const configPath = join(projectDir, '.pennyfarthing', 'config.local.yaml');
141
- // Only write if bell mode is enabled (read from config.local.yaml)
142
- try {
143
- let bellModeEnabled = false;
144
- if (existsSync(configPath)) {
145
- const configContent = readFileSync(configPath, 'utf8');
146
- // Simple check for bell_mode: true in YAML
147
- bellModeEnabled = /^\s*bell_mode:\s*true/m.test(configContent);
148
- }
149
- if (bellModeEnabled) {
150
- const queue = req.body;
151
- if (Array.isArray(queue)) {
152
- writeFileSync(queuePath, JSON.stringify(queue, null, 2));
153
- }
154
- }
155
- else if (existsSync(queuePath)) {
156
- // Bell mode disabled - remove stale queue file
157
- unlinkSync(queuePath);
41
+ const provider = {
42
+ getTokenStats() {
43
+ return mapTokenStats(realGetTokenStats());
44
+ },
45
+ addTokenStatsListener(callback) {
46
+ realAddTokenStatsListener((stats) => {
47
+ callback(mapTokenStats(stats));
48
+ });
49
+ },
50
+ getBackgroundTasks() {
51
+ return realGetBackgroundTasks();
52
+ },
53
+ setBackgroundTaskStartCallback(callback) {
54
+ realSetBackgroundTaskStartCallback(callback);
55
+ },
56
+ setBackgroundTaskCallback(callback) {
57
+ realSetBackgroundTaskCallback(callback);
58
+ },
59
+ processOTLPLogs(body) {
60
+ const rawEvents = parseOTLPLogs(body);
61
+ if (rawEvents.length > 0) {
62
+ void processLogEvents(rawEvents);
158
63
  }
159
- res.json({ ok: true });
160
- }
161
- catch (err) {
162
- console.error('[Bell Queue] Sync error:', err);
163
- res.status(500).json({ error: 'Failed to sync bell queue' });
164
- }
165
- });
166
- // Bell mode message consumed endpoint (called by PostToolUse hook)
167
- // Broadcasts to browser to dequeue and display the injected message
168
- import { broadcastBellConsumed } from './api/bell.js';
169
- app.post('/api/bell-consumed', (req, res) => {
170
- const { text } = req.body || {};
171
- try {
172
- broadcastBellConsumed(text || '');
173
- res.json({ ok: true });
174
- }
175
- catch (err) {
176
- console.error('[Bell Consumed] Broadcast error:', err);
177
- res.status(500).json({ error: 'Failed to broadcast bell consumed' });
178
- }
179
- });
180
- app.use('/v1', createOTLPRouter());
181
- // Initialize token stats WebSocket broadcast callback
64
+ },
65
+ processOTLPMetrics(body) {
66
+ const parsed = parseOTLPMetrics(body);
67
+ aggregateTokenStats(parsed);
68
+ },
69
+ processOTLPTraces(_body) {
70
+ // Traces are not processed by Cyclist — no-op
71
+ },
72
+ getAuditLog() {
73
+ return getToolEvents();
74
+ },
75
+ getToolEventsFiltered(opts) {
76
+ return realGetToolEventsFiltered(opts);
77
+ },
78
+ getToolTypes: realGetToolTypes,
79
+ getAuditLogStats: realGetAuditLogStats,
80
+ exportAuditLogAsJSON: realExportAuditLogAsJSON,
81
+ exportAuditLogAsCSV: realExportAuditLogAsCSV,
82
+ resetEventStore: realResetEventStore,
83
+ };
84
+ setOTLPProvider(provider);
85
+ // Re-initialize broadcast callbacks now that the real provider is set.
86
+ // The first calls during core's module load were no-ops (stub was active).
182
87
  initTokenStatsBroadcast();
183
- // 35-16: Initialize background task broadcast callback
184
88
  initBackgroundTaskBroadcast();
185
- // Create HTTP server with WebSocket support
89
+ /**
90
+ * Create HTTP server with Cyclist's WebSocket support.
91
+ * Overrides core's no-op WebSocket stub with the real implementation
92
+ * that handles stats, persona, token-stats, bell, welcome, hooks, etc.
93
+ */
186
94
  export function createTerminalServer() {
187
95
  const server = createServer(app);
188
96
  setupWebSocketServers(server, getProjectDir);
189
97
  return server;
190
98
  }
191
- // Start server only when run directly (not imported for tests)
192
- const DEFAULT_PORT = parseInt(process.env.PORT || '1898', 10);
193
- if (process.argv[1] === fileURLToPath(import.meta.url)) {
194
- (async () => {
195
- const server = createTerminalServer();
196
- const projectDir = getProjectDir();
197
- // Load plugin API routers (Story 93-6)
198
- const pluginResult = await initPluginRouters(app, projectDir);
199
- if (pluginResult.discovered > 0) {
200
- console.log(`[Plugin] ${pluginResult.loaded} router(s) loaded, ${pluginResult.failed} failed`);
201
- }
202
- // Find available port (Story 34-3)
203
- const actualPort = await findAvailablePort(DEFAULT_PORT);
204
- if (actualPort !== DEFAULT_PORT) {
205
- console.log(`Port ${DEFAULT_PORT} in use, using ${actualPort} instead`);
206
- }
207
- server.listen(actualPort, () => {
208
- console.log(`Cyclist running at http://localhost:${actualPort}`);
209
- // Write port file for OTEL auto-configuration (Story 20-1)
210
- writePortFile(projectDir, actualPort);
211
- console.log(`[OTEL] Wrote .cyclist-port file to ${projectDir}`);
212
- });
213
- // Cleanup on shutdown
214
- process.on('SIGINT', () => {
215
- clearSessionGrants(); // MSSCI-14324: Clear session/once grants
216
- cleanupPortFile(projectDir);
217
- console.log('[OTEL] Cleaned up .cyclist-port file');
218
- process.exit(0);
219
- });
220
- process.on('SIGTERM', () => {
221
- clearSessionGrants(); // MSSCI-14324: Clear session/once grants
222
- cleanupPortFile(projectDir);
223
- process.exit(0);
224
- });
225
- })();
226
- }
227
- // ============================================================================
228
- // Port File Discovery Pattern (Story 20-1)
229
- // Port Conflict Detection (Story 34-3)
230
- // ============================================================================
231
- const PORT_FILE_NAME = '.cyclist-port';
232
- const APPROVAL_PORT_FILE_NAME = '.cyclist-approval-port';
233
- const PID_FILE_NAME = '.cyclist-pid';
234
- /**
235
- * Find an available port starting from the given port.
236
- * Tries ports sequentially until one is available or maxAttempts reached.
237
- * Used by both Electron mode and standalone server mode.
238
- */
239
- export async function findAvailablePort(startPort, maxAttempts = 10) {
240
- const net = await import('net');
241
- for (let port = startPort; port < startPort + maxAttempts; port++) {
242
- const available = await new Promise((resolve) => {
243
- const testServer = net.createServer();
244
- testServer.once('error', () => resolve(false));
245
- testServer.once('listening', () => {
246
- testServer.close();
247
- resolve(true);
248
- });
249
- testServer.listen(port);
250
- });
251
- if (available) {
252
- return port;
253
- }
254
- }
255
- throw new Error(`No available port found in range ${startPort}-${startPort + maxAttempts - 1}`);
256
- }
257
- /**
258
- * Write the server port to a .cyclist-port file for auto-discovery.
259
- * Called when Cyclist server starts to enable hook-based OTEL configuration.
260
- */
261
- export function writePortFile(projectDir, port) {
262
- const portFilePath = join(projectDir, PORT_FILE_NAME);
263
- writeFileSync(portFilePath, String(port));
264
- }
265
- /**
266
- * Remove the .cyclist-port file during shutdown.
267
- * Prevents stale port files from pointing to non-existent servers.
268
- */
269
- export function cleanupPortFile(projectDir) {
270
- const portFilePath = join(projectDir, PORT_FILE_NAME);
271
- if (existsSync(portFilePath)) {
272
- unlinkSync(portFilePath);
273
- }
274
- }
275
- /**
276
- * Read the port number from .cyclist-port file.
277
- * Returns null if file doesn't exist, is empty, or contains invalid content.
278
- */
279
- export function readPortFile(projectDir) {
280
- const portFilePath = join(projectDir, PORT_FILE_NAME);
281
- if (!existsSync(portFilePath)) {
282
- return null;
283
- }
284
- const content = readFileSync(portFilePath, 'utf-8').trim();
285
- if (!content) {
286
- return null;
287
- }
288
- const port = parseInt(content, 10);
289
- if (isNaN(port)) {
290
- return null;
291
- }
292
- return port;
293
- }
294
- // ============================================================================
295
- // Approval Port File Pattern (Story 33-7)
296
- // Enables multi-instance Cyclist with isolated approval servers
297
- // ============================================================================
298
- /**
299
- * Write the approval server port to .cyclist-approval-port file.
300
- * Enables hook script to discover which port this instance is using.
301
- */
302
- export function writeApprovalPortFile(projectDir, port) {
303
- const portFilePath = join(projectDir, APPROVAL_PORT_FILE_NAME);
304
- writeFileSync(portFilePath, String(port));
305
- }
306
- /**
307
- * Remove the .cyclist-approval-port file during shutdown.
308
- * Prevents stale port files from causing cross-instance interference.
309
- */
310
- export function cleanupApprovalPortFile(projectDir) {
311
- const portFilePath = join(projectDir, APPROVAL_PORT_FILE_NAME);
312
- if (existsSync(portFilePath)) {
313
- unlinkSync(portFilePath);
314
- }
315
- }
316
- /**
317
- * Read the approval server port from .cyclist-approval-port file.
318
- * Returns null if file doesn't exist or contains invalid content.
319
- */
320
- export function readApprovalPortFile(projectDir) {
321
- const portFilePath = join(projectDir, APPROVAL_PORT_FILE_NAME);
322
- if (!existsSync(portFilePath)) {
323
- return null;
324
- }
325
- const content = readFileSync(portFilePath, 'utf-8').trim();
326
- if (!content) {
327
- return null;
328
- }
329
- const port = parseInt(content, 10);
330
- if (isNaN(port)) {
331
- return null;
332
- }
333
- return port;
334
- }
335
- // ============================================================================
336
- // PID File Pattern (Story B-24 fix)
337
- // Tracks Claude CLI process PID to avoid killing other Cyclist sessions
338
- // ============================================================================
339
- /**
340
- * Write the Claude process PID to .cyclist-pid file.
341
- * Used to track which Claude process belongs to this Cyclist instance.
342
- */
343
- export function writePidFile(projectDir, pid) {
344
- const pidFilePath = join(projectDir, PID_FILE_NAME);
345
- writeFileSync(pidFilePath, String(pid));
346
- }
347
- /**
348
- * Remove the .cyclist-pid file during shutdown.
349
- * Prevents stale PID files from causing incorrect process termination.
350
- */
351
- export function cleanupPidFile(projectDir) {
352
- const pidFilePath = join(projectDir, PID_FILE_NAME);
353
- if (existsSync(pidFilePath)) {
354
- unlinkSync(pidFilePath);
355
- }
356
- }
357
- /**
358
- * Read the PID from .cyclist-pid file.
359
- * Returns null if file doesn't exist, is empty, or contains invalid content.
360
- */
361
- export function readPidFile(projectDir) {
362
- const pidFilePath = join(projectDir, PID_FILE_NAME);
363
- if (!existsSync(pidFilePath)) {
364
- return null;
365
- }
366
- const content = readFileSync(pidFilePath, 'utf-8').trim();
367
- if (!content) {
368
- return null;
369
- }
370
- const pid = parseInt(content, 10);
371
- if (isNaN(pid)) {
372
- return null;
373
- }
374
- return pid;
375
- }
376
- /**
377
- * Check if a process with the given PID is still running.
378
- * Returns true if process exists, false otherwise.
379
- */
380
- export function isProcessRunning(pid) {
381
- try {
382
- // Sending signal 0 doesn't kill the process, just checks if it exists
383
- process.kill(pid, 0);
384
- return true;
385
- }
386
- catch {
387
- return false;
388
- }
389
- }
390
- /**
391
- * Get OTEL configuration environment variables based on port file.
392
- * Returns null if no valid port file exists.
393
- *
394
- * Claude Code requires explicit opt-in for telemetry:
395
- * - CLAUDE_CODE_ENABLE_TELEMETRY=1 to enable telemetry
396
- * - OTEL_LOGS_EXPORTER=otlp to export tool events
397
- * - OTEL_METRICS_EXPORTER=otlp to export token metrics
398
- *
399
- * @see https://code.claude.com/docs/en/monitoring-usage
400
- */
401
- export function getOtelConfig(projectDir) {
402
- const port = readPortFile(projectDir);
403
- if (port === null) {
404
- return null;
405
- }
406
- return {
407
- // Enable telemetry (opt-in required)
408
- CLAUDE_CODE_ENABLE_TELEMETRY: '1',
409
- // Configure exporters for logs (tool events) and metrics (tokens)
410
- OTEL_LOGS_EXPORTER: 'otlp',
411
- OTEL_METRICS_EXPORTER: 'otlp',
412
- // HTTP/JSON protocol for Cyclist's Express server
413
- OTEL_EXPORTER_OTLP_PROTOCOL: 'http/json',
414
- OTEL_EXPORTER_OTLP_ENDPOINT: `http://localhost:${port}`,
415
- };
416
- }
99
+ // Re-export everything from core's server module that cyclist consumers need.
100
+ // bikerack.ts needs: createTerminalServer (overridden above), findAvailablePort
101
+ // main.ts needs: getStoryInfo, getAllReposGitInfoAsync, writePortFile, cleanupPortFile,
102
+ // writePidFile, cleanupPidFile, readPidFile, isProcessRunning, getOtelConfig
103
+ // websocket.ts needs: getOtelConfig, isBikeRackMode
104
+ export { app, getProjectDir,
105
+ // API re-exports
106
+ broadcastStats, getStoryInfo, getGitInfo, getAllReposGitInfo, getAllReposGitInfoAsync,
107
+ // Path utilities
108
+ publicDir, nodeModulesDir, portraitsDir, getProjectDirectory, getDistDir, setProjectDirectory, resetProjectDirectory, parseProjectDirArg, isValidProjectDirectory,
109
+ // Server utilities
110
+ findAvailablePort, writePortFile, cleanupPortFile, readPortFile, writeApprovalPortFile, cleanupApprovalPortFile, readApprovalPortFile, writePidFile, cleanupPidFile, readPidFile, isProcessRunning,
111
+ // OTEL
112
+ getOtelConfig,
113
+ // Env
114
+ isBikeRackMode,
115
+ // Grants
116
+ clearSessionGrants, } from '@pennyfarthing/core/server';
417
117
  //# sourceMappingURL=server.js.map