@jacques-ai/cli 0.0.7-alpha.1

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 (508) hide show
  1. package/dist/assets/mascot-ansi.d.ts +8 -0
  2. package/dist/assets/mascot-ansi.d.ts.map +1 -0
  3. package/dist/assets/mascot-ansi.js +15 -0
  4. package/dist/assets/mascot-ansi.js.map +1 -0
  5. package/dist/cli.d.ts +15 -0
  6. package/dist/cli.d.ts.map +1 -0
  7. package/dist/cli.js +53 -0
  8. package/dist/cli.js.map +1 -0
  9. package/dist/commands/client-helper.d.ts +14 -0
  10. package/dist/commands/client-helper.d.ts.map +1 -0
  11. package/dist/commands/client-helper.js +38 -0
  12. package/dist/commands/client-helper.js.map +1 -0
  13. package/dist/commands/dashboard.d.ts +8 -0
  14. package/dist/commands/dashboard.d.ts.map +1 -0
  15. package/dist/commands/dashboard.js +159 -0
  16. package/dist/commands/dashboard.js.map +1 -0
  17. package/dist/commands/index.d.ts +6 -0
  18. package/dist/commands/index.d.ts.map +1 -0
  19. package/dist/commands/index.js +6 -0
  20. package/dist/commands/index.js.map +1 -0
  21. package/dist/commands/list.d.ts +5 -0
  22. package/dist/commands/list.d.ts.map +1 -0
  23. package/dist/commands/list.js +13 -0
  24. package/dist/commands/list.js.map +1 -0
  25. package/dist/commands/search.d.ts +13 -0
  26. package/dist/commands/search.d.ts.map +1 -0
  27. package/dist/commands/search.js +79 -0
  28. package/dist/commands/search.js.map +1 -0
  29. package/dist/commands/setup.d.ts +8 -0
  30. package/dist/commands/setup.d.ts.map +1 -0
  31. package/dist/commands/setup.js +32 -0
  32. package/dist/commands/setup.js.map +1 -0
  33. package/dist/commands/status.d.ts +5 -0
  34. package/dist/commands/status.d.ts.map +1 -0
  35. package/dist/commands/status.js +27 -0
  36. package/dist/commands/status.js.map +1 -0
  37. package/dist/components/ActiveSessionsView.d.ts +18 -0
  38. package/dist/components/ActiveSessionsView.d.ts.map +1 -0
  39. package/dist/components/ActiveSessionsView.js +68 -0
  40. package/dist/components/ActiveSessionsView.js.map +1 -0
  41. package/dist/components/AddContextConfirmView.d.ts +21 -0
  42. package/dist/components/AddContextConfirmView.d.ts.map +1 -0
  43. package/dist/components/AddContextConfirmView.js +44 -0
  44. package/dist/components/AddContextConfirmView.js.map +1 -0
  45. package/dist/components/App.d.ts +11 -0
  46. package/dist/components/App.d.ts.map +1 -0
  47. package/dist/components/App.js +292 -0
  48. package/dist/components/App.js.map +1 -0
  49. package/dist/components/ArchiveBrowserView.d.ts +40 -0
  50. package/dist/components/ArchiveBrowserView.d.ts.map +1 -0
  51. package/dist/components/ArchiveBrowserView.js +161 -0
  52. package/dist/components/ArchiveBrowserView.js.map +1 -0
  53. package/dist/components/ArchiveInitProgressView.d.ts +16 -0
  54. package/dist/components/ArchiveInitProgressView.d.ts.map +1 -0
  55. package/dist/components/ArchiveInitProgressView.js +72 -0
  56. package/dist/components/ArchiveInitProgressView.js.map +1 -0
  57. package/dist/components/AutoCompactToggle.d.ts +16 -0
  58. package/dist/components/AutoCompactToggle.d.ts.map +1 -0
  59. package/dist/components/AutoCompactToggle.js +12 -0
  60. package/dist/components/AutoCompactToggle.js.map +1 -0
  61. package/dist/components/BottomControls.d.ts +12 -0
  62. package/dist/components/BottomControls.d.ts.map +1 -0
  63. package/dist/components/BottomControls.js +11 -0
  64. package/dist/components/BottomControls.js.map +1 -0
  65. package/dist/components/CompactHeader.d.ts +21 -0
  66. package/dist/components/CompactHeader.d.ts.map +1 -0
  67. package/dist/components/CompactHeader.js +63 -0
  68. package/dist/components/CompactHeader.js.map +1 -0
  69. package/dist/components/CompactPanel.d.ts +22 -0
  70. package/dist/components/CompactPanel.d.ts.map +1 -0
  71. package/dist/components/CompactPanel.js +31 -0
  72. package/dist/components/CompactPanel.js.map +1 -0
  73. package/dist/components/ContentBox.d.ts +14 -0
  74. package/dist/components/ContentBox.d.ts.map +1 -0
  75. package/dist/components/ContentBox.js +24 -0
  76. package/dist/components/ContentBox.js.map +1 -0
  77. package/dist/components/ContextProgress.d.ts +14 -0
  78. package/dist/components/ContextProgress.d.ts.map +1 -0
  79. package/dist/components/ContextProgress.js +36 -0
  80. package/dist/components/ContextProgress.js.map +1 -0
  81. package/dist/components/Dashboard.d.ts +46 -0
  82. package/dist/components/Dashboard.d.ts.map +1 -0
  83. package/dist/components/Dashboard.js +67 -0
  84. package/dist/components/Dashboard.js.map +1 -0
  85. package/dist/components/FilterSelectionView.d.ts +15 -0
  86. package/dist/components/FilterSelectionView.d.ts.map +1 -0
  87. package/dist/components/FilterSelectionView.js +27 -0
  88. package/dist/components/FilterSelectionView.js.map +1 -0
  89. package/dist/components/GoogleDocsBrowserView.d.ts +20 -0
  90. package/dist/components/GoogleDocsBrowserView.d.ts.map +1 -0
  91. package/dist/components/GoogleDocsBrowserView.js +72 -0
  92. package/dist/components/GoogleDocsBrowserView.js.map +1 -0
  93. package/dist/components/HandoffBrowserView.d.ts +20 -0
  94. package/dist/components/HandoffBrowserView.d.ts.map +1 -0
  95. package/dist/components/HandoffBrowserView.js +66 -0
  96. package/dist/components/HandoffBrowserView.js.map +1 -0
  97. package/dist/components/Header.d.ts +14 -0
  98. package/dist/components/Header.d.ts.map +1 -0
  99. package/dist/components/Header.js +16 -0
  100. package/dist/components/Header.js.map +1 -0
  101. package/dist/components/HorizontalMenu.d.ts +24 -0
  102. package/dist/components/HorizontalMenu.d.ts.map +1 -0
  103. package/dist/components/HorizontalMenu.js +20 -0
  104. package/dist/components/HorizontalMenu.js.map +1 -0
  105. package/dist/components/ImageMascot.d.ts +8 -0
  106. package/dist/components/ImageMascot.d.ts.map +1 -0
  107. package/dist/components/ImageMascot.js +7 -0
  108. package/dist/components/ImageMascot.js.map +1 -0
  109. package/dist/components/LLMWorkingView.d.ts +19 -0
  110. package/dist/components/LLMWorkingView.d.ts.map +1 -0
  111. package/dist/components/LLMWorkingView.js +72 -0
  112. package/dist/components/LLMWorkingView.js.map +1 -0
  113. package/dist/components/LoadContextView.d.ts +22 -0
  114. package/dist/components/LoadContextView.d.ts.map +1 -0
  115. package/dist/components/LoadContextView.js +83 -0
  116. package/dist/components/LoadContextView.js.map +1 -0
  117. package/dist/components/MainMenuView.d.ts +20 -0
  118. package/dist/components/MainMenuView.d.ts.map +1 -0
  119. package/dist/components/MainMenuView.js +49 -0
  120. package/dist/components/MainMenuView.js.map +1 -0
  121. package/dist/components/Mascot.d.ts +24 -0
  122. package/dist/components/Mascot.d.ts.map +1 -0
  123. package/dist/components/Mascot.js +32 -0
  124. package/dist/components/Mascot.js.map +1 -0
  125. package/dist/components/Menu.d.ts +22 -0
  126. package/dist/components/Menu.d.ts.map +1 -0
  127. package/dist/components/Menu.js +28 -0
  128. package/dist/components/Menu.js.map +1 -0
  129. package/dist/components/NotionBrowserView.d.ts +21 -0
  130. package/dist/components/NotionBrowserView.d.ts.map +1 -0
  131. package/dist/components/NotionBrowserView.js +75 -0
  132. package/dist/components/NotionBrowserView.js.map +1 -0
  133. package/dist/components/ObsidianBrowserView.d.ts +21 -0
  134. package/dist/components/ObsidianBrowserView.d.ts.map +1 -0
  135. package/dist/components/ObsidianBrowserView.js +74 -0
  136. package/dist/components/ObsidianBrowserView.js.map +1 -0
  137. package/dist/components/ObsidianConfigView.d.ts +19 -0
  138. package/dist/components/ObsidianConfigView.d.ts.map +1 -0
  139. package/dist/components/ObsidianConfigView.js +45 -0
  140. package/dist/components/ObsidianConfigView.js.map +1 -0
  141. package/dist/components/PlaceholderView.d.ts +15 -0
  142. package/dist/components/PlaceholderView.d.ts.map +1 -0
  143. package/dist/components/PlaceholderView.js +20 -0
  144. package/dist/components/PlaceholderView.js.map +1 -0
  145. package/dist/components/PlanViewerView.d.ts +26 -0
  146. package/dist/components/PlanViewerView.d.ts.map +1 -0
  147. package/dist/components/PlanViewerView.js +170 -0
  148. package/dist/components/PlanViewerView.js.map +1 -0
  149. package/dist/components/ProgressBar.d.ts +24 -0
  150. package/dist/components/ProgressBar.d.ts.map +1 -0
  151. package/dist/components/ProgressBar.js +23 -0
  152. package/dist/components/ProgressBar.js.map +1 -0
  153. package/dist/components/ProjectDashboardView.d.ts +38 -0
  154. package/dist/components/ProjectDashboardView.d.ts.map +1 -0
  155. package/dist/components/ProjectDashboardView.js +129 -0
  156. package/dist/components/ProjectDashboardView.js.map +1 -0
  157. package/dist/components/SaveContextView.d.ts +32 -0
  158. package/dist/components/SaveContextView.d.ts.map +1 -0
  159. package/dist/components/SaveContextView.js +41 -0
  160. package/dist/components/SaveContextView.js.map +1 -0
  161. package/dist/components/SessionDetails.d.ts +14 -0
  162. package/dist/components/SessionDetails.d.ts.map +1 -0
  163. package/dist/components/SessionDetails.js +87 -0
  164. package/dist/components/SessionDetails.js.map +1 -0
  165. package/dist/components/SessionsExperimentView.d.ts +35 -0
  166. package/dist/components/SessionsExperimentView.d.ts.map +1 -0
  167. package/dist/components/SessionsExperimentView.js +347 -0
  168. package/dist/components/SessionsExperimentView.js.map +1 -0
  169. package/dist/components/SessionsList.d.ts +20 -0
  170. package/dist/components/SessionsList.d.ts.map +1 -0
  171. package/dist/components/SessionsList.js +75 -0
  172. package/dist/components/SessionsList.js.map +1 -0
  173. package/dist/components/SettingsView.d.ts +48 -0
  174. package/dist/components/SettingsView.d.ts.map +1 -0
  175. package/dist/components/SettingsView.js +156 -0
  176. package/dist/components/SettingsView.js.map +1 -0
  177. package/dist/components/SourceSelectionView.d.ts +26 -0
  178. package/dist/components/SourceSelectionView.d.ts.map +1 -0
  179. package/dist/components/SourceSelectionView.js +109 -0
  180. package/dist/components/SourceSelectionView.js.map +1 -0
  181. package/dist/components/VerticalMenu.d.ts +18 -0
  182. package/dist/components/VerticalMenu.d.ts.map +1 -0
  183. package/dist/components/VerticalMenu.js +15 -0
  184. package/dist/components/VerticalMenu.js.map +1 -0
  185. package/dist/components/ascii-art/index.d.ts +6 -0
  186. package/dist/components/ascii-art/index.d.ts.map +1 -0
  187. package/dist/components/ascii-art/index.js +6 -0
  188. package/dist/components/ascii-art/index.js.map +1 -0
  189. package/dist/components/ascii-art/progress.d.ts +53 -0
  190. package/dist/components/ascii-art/progress.d.ts.map +1 -0
  191. package/dist/components/ascii-art/progress.js +102 -0
  192. package/dist/components/ascii-art/progress.js.map +1 -0
  193. package/dist/components/ascii-art/scene.d.ts +34 -0
  194. package/dist/components/ascii-art/scene.d.ts.map +1 -0
  195. package/dist/components/ascii-art/scene.js +72 -0
  196. package/dist/components/ascii-art/scene.js.map +1 -0
  197. package/dist/components/index.d.ts +27 -0
  198. package/dist/components/index.d.ts.map +1 -0
  199. package/dist/components/index.js +25 -0
  200. package/dist/components/index.js.map +1 -0
  201. package/dist/components/layout/HorizontalLayout.d.ts +19 -0
  202. package/dist/components/layout/HorizontalLayout.d.ts.map +1 -0
  203. package/dist/components/layout/HorizontalLayout.js +62 -0
  204. package/dist/components/layout/HorizontalLayout.js.map +1 -0
  205. package/dist/components/layout/VerticalLayout.d.ts +16 -0
  206. package/dist/components/layout/VerticalLayout.d.ts.map +1 -0
  207. package/dist/components/layout/VerticalLayout.js +32 -0
  208. package/dist/components/layout/VerticalLayout.js.map +1 -0
  209. package/dist/components/layout/index.d.ts +6 -0
  210. package/dist/components/layout/index.d.ts.map +1 -0
  211. package/dist/components/layout/index.js +4 -0
  212. package/dist/components/layout/index.js.map +1 -0
  213. package/dist/components/layout/theme.d.ts +20 -0
  214. package/dist/components/layout/theme.d.ts.map +1 -0
  215. package/dist/components/layout/theme.js +23 -0
  216. package/dist/components/layout/theme.js.map +1 -0
  217. package/dist/components/setup/DoneStep.d.ts +7 -0
  218. package/dist/components/setup/DoneStep.d.ts.map +1 -0
  219. package/dist/components/setup/DoneStep.js +31 -0
  220. package/dist/components/setup/DoneStep.js.map +1 -0
  221. package/dist/components/setup/InstallingStep.d.ts +11 -0
  222. package/dist/components/setup/InstallingStep.d.ts.map +1 -0
  223. package/dist/components/setup/InstallingStep.js +27 -0
  224. package/dist/components/setup/InstallingStep.js.map +1 -0
  225. package/dist/components/setup/OptionsStep.d.ts +9 -0
  226. package/dist/components/setup/OptionsStep.d.ts.map +1 -0
  227. package/dist/components/setup/OptionsStep.js +39 -0
  228. package/dist/components/setup/OptionsStep.js.map +1 -0
  229. package/dist/components/setup/PrerequisitesStep.d.ts +7 -0
  230. package/dist/components/setup/PrerequisitesStep.d.ts.map +1 -0
  231. package/dist/components/setup/PrerequisitesStep.js +31 -0
  232. package/dist/components/setup/PrerequisitesStep.js.map +1 -0
  233. package/dist/components/setup/SetupFrame.d.ts +17 -0
  234. package/dist/components/setup/SetupFrame.d.ts.map +1 -0
  235. package/dist/components/setup/SetupFrame.js +33 -0
  236. package/dist/components/setup/SetupFrame.js.map +1 -0
  237. package/dist/components/setup/SetupWizard.d.ts +9 -0
  238. package/dist/components/setup/SetupWizard.d.ts.map +1 -0
  239. package/dist/components/setup/SetupWizard.js +149 -0
  240. package/dist/components/setup/SetupWizard.js.map +1 -0
  241. package/dist/components/setup/Spinner.d.ts +10 -0
  242. package/dist/components/setup/Spinner.d.ts.map +1 -0
  243. package/dist/components/setup/Spinner.js +20 -0
  244. package/dist/components/setup/Spinner.js.map +1 -0
  245. package/dist/components/setup/SyncStep.d.ts +11 -0
  246. package/dist/components/setup/SyncStep.d.ts.map +1 -0
  247. package/dist/components/setup/SyncStep.js +47 -0
  248. package/dist/components/setup/SyncStep.js.map +1 -0
  249. package/dist/components/setup/VerificationStep.d.ts +7 -0
  250. package/dist/components/setup/VerificationStep.d.ts.map +1 -0
  251. package/dist/components/setup/VerificationStep.js +27 -0
  252. package/dist/components/setup/VerificationStep.js.map +1 -0
  253. package/dist/components/setup/WelcomeStep.d.ts +6 -0
  254. package/dist/components/setup/WelcomeStep.d.ts.map +1 -0
  255. package/dist/components/setup/WelcomeStep.js +17 -0
  256. package/dist/components/setup/WelcomeStep.js.map +1 -0
  257. package/dist/components/shared/ProgressLine.d.ts +10 -0
  258. package/dist/components/shared/ProgressLine.d.ts.map +1 -0
  259. package/dist/components/shared/ProgressLine.js +18 -0
  260. package/dist/components/shared/ProgressLine.js.map +1 -0
  261. package/dist/components/shared/ProjectLine.d.ts +10 -0
  262. package/dist/components/shared/ProjectLine.d.ts.map +1 -0
  263. package/dist/components/shared/ProjectLine.js +19 -0
  264. package/dist/components/shared/ProjectLine.js.map +1 -0
  265. package/dist/components/shared/ScanningIndicator.d.ts +9 -0
  266. package/dist/components/shared/ScanningIndicator.d.ts.map +1 -0
  267. package/dist/components/shared/ScanningIndicator.js +22 -0
  268. package/dist/components/shared/ScanningIndicator.js.map +1 -0
  269. package/dist/components/shared/StatusLine.d.ts +13 -0
  270. package/dist/components/shared/StatusLine.d.ts.map +1 -0
  271. package/dist/components/shared/StatusLine.js +24 -0
  272. package/dist/components/shared/StatusLine.js.map +1 -0
  273. package/dist/components/shared/StatusLine.test.d.ts +8 -0
  274. package/dist/components/shared/StatusLine.test.d.ts.map +1 -0
  275. package/dist/components/shared/StatusLine.test.js +50 -0
  276. package/dist/components/shared/StatusLine.test.js.map +1 -0
  277. package/dist/components/shared/index.d.ts +4 -0
  278. package/dist/components/shared/index.d.ts.map +1 -0
  279. package/dist/components/shared/index.js +4 -0
  280. package/dist/components/shared/index.js.map +1 -0
  281. package/dist/handoff/catalog.test.d.ts +5 -0
  282. package/dist/handoff/catalog.test.d.ts.map +1 -0
  283. package/dist/handoff/catalog.test.js +172 -0
  284. package/dist/handoff/catalog.test.js.map +1 -0
  285. package/dist/handoff/subagents.test.d.ts +8 -0
  286. package/dist/handoff/subagents.test.d.ts.map +1 -0
  287. package/dist/handoff/subagents.test.js +139 -0
  288. package/dist/handoff/subagents.test.js.map +1 -0
  289. package/dist/hooks/useAddContextFlow.d.ts +29 -0
  290. package/dist/hooks/useAddContextFlow.d.ts.map +1 -0
  291. package/dist/hooks/useAddContextFlow.js +83 -0
  292. package/dist/hooks/useAddContextFlow.js.map +1 -0
  293. package/dist/hooks/useArchiveBrowser.d.ts +37 -0
  294. package/dist/hooks/useArchiveBrowser.d.ts.map +1 -0
  295. package/dist/hooks/useArchiveBrowser.js +175 -0
  296. package/dist/hooks/useArchiveBrowser.js.map +1 -0
  297. package/dist/hooks/useClaudeToken.d.ts +29 -0
  298. package/dist/hooks/useClaudeToken.d.ts.map +1 -0
  299. package/dist/hooks/useClaudeToken.js +166 -0
  300. package/dist/hooks/useClaudeToken.js.map +1 -0
  301. package/dist/hooks/useGoogleDocsBrowser.d.ts +29 -0
  302. package/dist/hooks/useGoogleDocsBrowser.d.ts.map +1 -0
  303. package/dist/hooks/useGoogleDocsBrowser.js +146 -0
  304. package/dist/hooks/useGoogleDocsBrowser.js.map +1 -0
  305. package/dist/hooks/useHandoffBrowser.d.ts +27 -0
  306. package/dist/hooks/useHandoffBrowser.d.ts.map +1 -0
  307. package/dist/hooks/useHandoffBrowser.js +92 -0
  308. package/dist/hooks/useHandoffBrowser.js.map +1 -0
  309. package/dist/hooks/useJacquesClient.d.ts +69 -0
  310. package/dist/hooks/useJacquesClient.d.ts.map +1 -0
  311. package/dist/hooks/useJacquesClient.js +248 -0
  312. package/dist/hooks/useJacquesClient.js.map +1 -0
  313. package/dist/hooks/useLlmWorking.d.ts +30 -0
  314. package/dist/hooks/useLlmWorking.d.ts.map +1 -0
  315. package/dist/hooks/useLlmWorking.js +127 -0
  316. package/dist/hooks/useLlmWorking.js.map +1 -0
  317. package/dist/hooks/useLoadContext.d.ts +27 -0
  318. package/dist/hooks/useLoadContext.d.ts.map +1 -0
  319. package/dist/hooks/useLoadContext.js +102 -0
  320. package/dist/hooks/useLoadContext.js.map +1 -0
  321. package/dist/hooks/useNotification.d.ts +36 -0
  322. package/dist/hooks/useNotification.d.ts.map +1 -0
  323. package/dist/hooks/useNotification.js +89 -0
  324. package/dist/hooks/useNotification.js.map +1 -0
  325. package/dist/hooks/useNotification.test.d.ts +9 -0
  326. package/dist/hooks/useNotification.test.d.ts.map +1 -0
  327. package/dist/hooks/useNotification.test.js +144 -0
  328. package/dist/hooks/useNotification.test.js.map +1 -0
  329. package/dist/hooks/useNotionBrowser.d.ts +30 -0
  330. package/dist/hooks/useNotionBrowser.d.ts.map +1 -0
  331. package/dist/hooks/useNotionBrowser.js +154 -0
  332. package/dist/hooks/useNotionBrowser.js.map +1 -0
  333. package/dist/hooks/useObsidianBrowser.d.ts +42 -0
  334. package/dist/hooks/useObsidianBrowser.d.ts.map +1 -0
  335. package/dist/hooks/useObsidianBrowser.js +63 -0
  336. package/dist/hooks/useObsidianBrowser.js.map +1 -0
  337. package/dist/hooks/useObsidianConfig.d.ts +28 -0
  338. package/dist/hooks/useObsidianConfig.d.ts.map +1 -0
  339. package/dist/hooks/useObsidianConfig.js +119 -0
  340. package/dist/hooks/useObsidianConfig.js.map +1 -0
  341. package/dist/hooks/useObsidianFileBrowser.d.ts +29 -0
  342. package/dist/hooks/useObsidianFileBrowser.d.ts.map +1 -0
  343. package/dist/hooks/useObsidianFileBrowser.js +114 -0
  344. package/dist/hooks/useObsidianFileBrowser.js.map +1 -0
  345. package/dist/hooks/useProjectDashboard.d.ts +38 -0
  346. package/dist/hooks/useProjectDashboard.d.ts.map +1 -0
  347. package/dist/hooks/useProjectDashboard.js +224 -0
  348. package/dist/hooks/useProjectDashboard.js.map +1 -0
  349. package/dist/hooks/useProjectSelector.d.ts +17 -0
  350. package/dist/hooks/useProjectSelector.d.ts.map +1 -0
  351. package/dist/hooks/useProjectSelector.js +43 -0
  352. package/dist/hooks/useProjectSelector.js.map +1 -0
  353. package/dist/hooks/useProjectSelector.test.d.ts +7 -0
  354. package/dist/hooks/useProjectSelector.test.d.ts.map +1 -0
  355. package/dist/hooks/useProjectSelector.test.js +117 -0
  356. package/dist/hooks/useProjectSelector.test.js.map +1 -0
  357. package/dist/hooks/useSaveFlow.d.ts +30 -0
  358. package/dist/hooks/useSaveFlow.d.ts.map +1 -0
  359. package/dist/hooks/useSaveFlow.js +195 -0
  360. package/dist/hooks/useSaveFlow.js.map +1 -0
  361. package/dist/hooks/useSessions.test.d.ts +7 -0
  362. package/dist/hooks/useSessions.test.d.ts.map +1 -0
  363. package/dist/hooks/useSessions.test.js +153 -0
  364. package/dist/hooks/useSessions.test.js.map +1 -0
  365. package/dist/hooks/useSessionsExperiment.d.ts +97 -0
  366. package/dist/hooks/useSessionsExperiment.d.ts.map +1 -0
  367. package/dist/hooks/useSessionsExperiment.js +321 -0
  368. package/dist/hooks/useSessionsExperiment.js.map +1 -0
  369. package/dist/hooks/useSettings.d.ts +47 -0
  370. package/dist/hooks/useSettings.d.ts.map +1 -0
  371. package/dist/hooks/useSettings.js +245 -0
  372. package/dist/hooks/useSettings.js.map +1 -0
  373. package/dist/hooks/useSetupWizard.d.ts +35 -0
  374. package/dist/hooks/useSetupWizard.d.ts.map +1 -0
  375. package/dist/hooks/useSetupWizard.js +438 -0
  376. package/dist/hooks/useSetupWizard.js.map +1 -0
  377. package/dist/hooks/useUsageLimits.d.ts +24 -0
  378. package/dist/hooks/useUsageLimits.d.ts.map +1 -0
  379. package/dist/hooks/useUsageLimits.js +58 -0
  380. package/dist/hooks/useUsageLimits.js.map +1 -0
  381. package/dist/hooks/useUsageLimits.test.d.ts +7 -0
  382. package/dist/hooks/useUsageLimits.test.d.ts.map +1 -0
  383. package/dist/hooks/useUsageLimits.test.js +136 -0
  384. package/dist/hooks/useUsageLimits.test.js.map +1 -0
  385. package/dist/hooks/useWorktrees.d.ts +28 -0
  386. package/dist/hooks/useWorktrees.d.ts.map +1 -0
  387. package/dist/hooks/useWorktrees.js +57 -0
  388. package/dist/hooks/useWorktrees.js.map +1 -0
  389. package/dist/hooks/useWorktrees.test.d.ts +7 -0
  390. package/dist/hooks/useWorktrees.test.d.ts.map +1 -0
  391. package/dist/hooks/useWorktrees.test.js +119 -0
  392. package/dist/hooks/useWorktrees.test.js.map +1 -0
  393. package/dist/templates/compact-prompt.d.ts +16 -0
  394. package/dist/templates/compact-prompt.d.ts.map +1 -0
  395. package/dist/templates/compact-prompt.js +47 -0
  396. package/dist/templates/compact-prompt.js.map +1 -0
  397. package/dist/templates/context-skill.d.ts +8 -0
  398. package/dist/templates/context-skill.d.ts.map +1 -0
  399. package/dist/templates/context-skill.js +42 -0
  400. package/dist/templates/context-skill.js.map +1 -0
  401. package/dist/types.d.ts +127 -0
  402. package/dist/types.d.ts.map +1 -0
  403. package/dist/types.js +8 -0
  404. package/dist/types.js.map +1 -0
  405. package/dist/utils/activity.d.ts +17 -0
  406. package/dist/utils/activity.d.ts.map +1 -0
  407. package/dist/utils/activity.js +78 -0
  408. package/dist/utils/activity.js.map +1 -0
  409. package/dist/utils/bottom-controls.d.ts +24 -0
  410. package/dist/utils/bottom-controls.d.ts.map +1 -0
  411. package/dist/utils/bottom-controls.js +29 -0
  412. package/dist/utils/bottom-controls.js.map +1 -0
  413. package/dist/utils/clipboard.d.ts +2 -0
  414. package/dist/utils/clipboard.d.ts.map +1 -0
  415. package/dist/utils/clipboard.js +20 -0
  416. package/dist/utils/clipboard.js.map +1 -0
  417. package/dist/utils/constants.d.ts +6 -0
  418. package/dist/utils/constants.d.ts.map +1 -0
  419. package/dist/utils/constants.js +6 -0
  420. package/dist/utils/constants.js.map +1 -0
  421. package/dist/utils/format.d.ts +17 -0
  422. package/dist/utils/format.d.ts.map +1 -0
  423. package/dist/utils/format.js +31 -0
  424. package/dist/utils/format.js.map +1 -0
  425. package/dist/utils/session-mode.d.ts +14 -0
  426. package/dist/utils/session-mode.d.ts.map +1 -0
  427. package/dist/utils/session-mode.js +29 -0
  428. package/dist/utils/session-mode.js.map +1 -0
  429. package/dist/utils/session-mode.test.d.ts +7 -0
  430. package/dist/utils/session-mode.test.d.ts.map +1 -0
  431. package/dist/utils/session-mode.test.js +102 -0
  432. package/dist/utils/session-mode.test.js.map +1 -0
  433. package/dist/utils/sessions-items-builder.d.ts +29 -0
  434. package/dist/utils/sessions-items-builder.d.ts.map +1 -0
  435. package/dist/utils/sessions-items-builder.js +394 -0
  436. package/dist/utils/sessions-items-builder.js.map +1 -0
  437. package/dist/utils/settings.d.ts +100 -0
  438. package/dist/utils/settings.d.ts.map +1 -0
  439. package/dist/utils/settings.js +206 -0
  440. package/dist/utils/settings.js.map +1 -0
  441. package/dist/websocket-client.d.ts +70 -0
  442. package/dist/websocket-client.d.ts.map +1 -0
  443. package/dist/websocket-client.js +188 -0
  444. package/dist/websocket-client.js.map +1 -0
  445. package/hooks/adapters/__init__.py +17 -0
  446. package/hooks/adapters/__pycache__/__init__.cpython-311.pyc +0 -0
  447. package/hooks/adapters/__pycache__/__init__.cpython-313.pyc +0 -0
  448. package/hooks/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
  449. package/hooks/adapters/__pycache__/base.cpython-311.pyc +0 -0
  450. package/hooks/adapters/__pycache__/base.cpython-313.pyc +0 -0
  451. package/hooks/adapters/__pycache__/base.cpython-314.pyc +0 -0
  452. package/hooks/adapters/__pycache__/calibration.cpython-311.pyc +0 -0
  453. package/hooks/adapters/__pycache__/calibration.cpython-313.pyc +0 -0
  454. package/hooks/adapters/__pycache__/calibration.cpython-314.pyc +0 -0
  455. package/hooks/adapters/__pycache__/claude_code.cpython-311.pyc +0 -0
  456. package/hooks/adapters/__pycache__/claude_code.cpython-313.pyc +0 -0
  457. package/hooks/adapters/__pycache__/claude_code.cpython-314.pyc +0 -0
  458. package/hooks/adapters/__pycache__/cursor.cpython-311.pyc +0 -0
  459. package/hooks/adapters/__pycache__/cursor.cpython-313.pyc +0 -0
  460. package/hooks/adapters/__pycache__/cursor.cpython-314.pyc +0 -0
  461. package/hooks/adapters/__pycache__/skills.cpython-311.pyc +0 -0
  462. package/hooks/adapters/__pycache__/skills.cpython-313.pyc +0 -0
  463. package/hooks/adapters/__pycache__/skills.cpython-314.pyc +0 -0
  464. package/hooks/adapters/__pycache__/test_adapters.cpython-311-pytest-9.0.2.pyc +0 -0
  465. package/hooks/adapters/__pycache__/test_adapters.cpython-313.pyc +0 -0
  466. package/hooks/adapters/__pycache__/test_calibration.cpython-311-pytest-9.0.2.pyc +0 -0
  467. package/hooks/adapters/__pycache__/test_skills.cpython-311-pytest-9.0.2.pyc +0 -0
  468. package/hooks/adapters/__pycache__/test_tokenizer.cpython-311-pytest-9.0.2.pyc +0 -0
  469. package/hooks/adapters/__pycache__/tokenizer.cpython-311.pyc +0 -0
  470. package/hooks/adapters/__pycache__/tokenizer.cpython-313.pyc +0 -0
  471. package/hooks/adapters/__pycache__/tokenizer.cpython-314.pyc +0 -0
  472. package/hooks/adapters/base.py +459 -0
  473. package/hooks/adapters/calibration.py +236 -0
  474. package/hooks/adapters/claude_code.py +316 -0
  475. package/hooks/adapters/context_parser.py +288 -0
  476. package/hooks/adapters/cursor.py +258 -0
  477. package/hooks/adapters/skills.py +160 -0
  478. package/hooks/adapters/template.py +281 -0
  479. package/hooks/adapters/test_adapters.py +516 -0
  480. package/hooks/adapters/test_calibration.py +235 -0
  481. package/hooks/adapters/test_skills.py +162 -0
  482. package/hooks/adapters/test_tokenizer.py +158 -0
  483. package/hooks/adapters/tokenizer.py +192 -0
  484. package/hooks/claude-code/pre-tool-use.py +36 -0
  485. package/hooks/claude-code/register-session.py +35 -0
  486. package/hooks/claude-code/report-activity.py +32 -0
  487. package/hooks/claude-code/session-idle.py +32 -0
  488. package/hooks/claude-code/statusline.sh +91 -0
  489. package/hooks/claude-code/unregister-session.py +32 -0
  490. package/hooks/cursor/README.md +61 -0
  491. package/hooks/cursor/after-agent-response.py +97 -0
  492. package/hooks/cursor/hooks.json.template +30 -0
  493. package/hooks/cursor/post-tool-use.py +32 -0
  494. package/hooks/cursor/pre-compact.py +61 -0
  495. package/hooks/cursor/session-end.py +32 -0
  496. package/hooks/cursor/session-start.py +66 -0
  497. package/hooks/git-detect.sh +47 -0
  498. package/hooks/install.py +441 -0
  499. package/hooks/jacques-register-session.py +286 -0
  500. package/hooks/jacques-report-activity.py +145 -0
  501. package/hooks/jacques-session-idle.py +57 -0
  502. package/hooks/jacques-unregister-session.py +57 -0
  503. package/hooks/requirements.txt +9 -0
  504. package/hooks/statusline.py +457 -0
  505. package/hooks/statusline.sh +212 -0
  506. package/package.json +63 -0
  507. package/skills/jacques-continue/SKILL.md +87 -0
  508. package/skills/jacques-handoff/SKILL.md +147 -0
@@ -0,0 +1,316 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ claude_code.py - Claude Code CLI Adapter for Jacques
4
+
5
+ Handles events from Claude Code CLI (standalone or in Cursor terminal).
6
+
7
+ Field Mappings:
8
+ - session_id: direct from input
9
+ - project_path: workspace.project_dir
10
+ - transcript_path: direct from input
11
+ - model: direct from input
12
+
13
+ Hook Events:
14
+ - SessionStart → session_start
15
+ - PostToolUse → activity
16
+ - Stop → idle
17
+ - SessionEnd → session_end
18
+ - statusLine → context_update (handled by statusline.sh)
19
+ """
20
+ import json
21
+ import os
22
+ from pathlib import Path
23
+ from typing import Optional
24
+ from .base import BaseAdapter
25
+
26
+
27
+ class ClaudeCodeAdapter(BaseAdapter):
28
+ """
29
+ Adapter for Claude Code CLI sessions.
30
+
31
+ Claude Code provides session data via hooks configured in
32
+ ~/.claude/settings.json
33
+ """
34
+
35
+ SETTINGS_PATH = Path.home() / '.claude' / 'settings.json'
36
+
37
+ @property
38
+ def source(self) -> str:
39
+ return 'claude_code'
40
+
41
+ # =========================================================================
42
+ # Auto-Compact Settings
43
+ # =========================================================================
44
+
45
+ def get_autocompact_settings(self) -> dict:
46
+ """
47
+ Read auto-compact settings from Claude Code config.
48
+
49
+ Checks:
50
+ 1. ~/.claude/settings.json for autoCompact field
51
+ 2. CLAUDE_AUTOCOMPACT_PCT_OVERRIDE env var for custom threshold
52
+
53
+ Returns:
54
+ Dict with enabled, threshold, and bug_threshold fields.
55
+
56
+ Known Bug (Issue #18264):
57
+ Even with autoCompact: false, compaction still triggers at ~78%.
58
+ """
59
+ enabled = True # Default is enabled
60
+ threshold = 95 # Default threshold
61
+ bug_threshold = None
62
+
63
+ # Check settings.json
64
+ if self.SETTINGS_PATH.exists():
65
+ try:
66
+ with open(self.SETTINGS_PATH) as f:
67
+ settings = json.load(f)
68
+ if 'autoCompact' in settings:
69
+ enabled = settings['autoCompact']
70
+ # If disabled, bug may trigger at ~78%
71
+ if not enabled:
72
+ bug_threshold = 78
73
+ except (json.JSONDecodeError, IOError):
74
+ pass
75
+
76
+ # Check env var for custom threshold
77
+ threshold_override = os.environ.get('CLAUDE_AUTOCOMPACT_PCT_OVERRIDE')
78
+ if threshold_override:
79
+ try:
80
+ threshold = int(threshold_override)
81
+ except ValueError:
82
+ pass
83
+
84
+ return {
85
+ 'enabled': enabled,
86
+ 'threshold': threshold,
87
+ 'bug_threshold': bug_threshold,
88
+ }
89
+
90
+ def set_autocompact(self, enabled: bool) -> bool:
91
+ """
92
+ Set auto-compact setting in ~/.claude/settings.json.
93
+
94
+ Args:
95
+ enabled: Whether to enable auto-compact
96
+
97
+ Returns:
98
+ True if successful, False otherwise.
99
+ """
100
+ try:
101
+ settings = {}
102
+ if self.SETTINGS_PATH.exists():
103
+ try:
104
+ with open(self.SETTINGS_PATH) as f:
105
+ settings = json.load(f)
106
+ except (json.JSONDecodeError, IOError):
107
+ pass
108
+
109
+ settings['autoCompact'] = enabled
110
+
111
+ # Ensure parent directory exists
112
+ self.SETTINGS_PATH.parent.mkdir(parents=True, exist_ok=True)
113
+
114
+ with open(self.SETTINGS_PATH, 'w') as f:
115
+ json.dump(settings, f, indent=2)
116
+
117
+ return True
118
+ except IOError as e:
119
+ self._log_error(f"Failed to write settings.json: {e}")
120
+ return False
121
+
122
+ def toggle_autocompact(self) -> dict:
123
+ """
124
+ Toggle auto-compact setting and return new status.
125
+
126
+ Returns:
127
+ Dict with enabled, threshold, bug_threshold, and warning.
128
+ """
129
+ current = self.get_autocompact_settings()
130
+ new_enabled = not current['enabled']
131
+
132
+ if self.set_autocompact(new_enabled):
133
+ return {
134
+ 'enabled': new_enabled,
135
+ 'threshold': current['threshold'],
136
+ 'bug_threshold': 78 if not new_enabled else None,
137
+ 'warning': 'Known bug: may still trigger at ~78%' if not new_enabled else None,
138
+ }
139
+
140
+ return current
141
+
142
+ def get_session_id(self, input_data: dict) -> Optional[str]:
143
+ """Extract session_id directly from Claude Code input."""
144
+ return input_data.get('session_id')
145
+
146
+ def get_project_path(self, input_data: dict) -> Optional[str]:
147
+ """
148
+ Extract project path from workspace.project_dir.
149
+
150
+ Claude Code provides workspace info with:
151
+ - workspace.project_dir: The actual project directory
152
+ - workspace.current_dir: Current working directory (may be subdirectory)
153
+ """
154
+ workspace = input_data.get('workspace', {})
155
+ if isinstance(workspace, dict):
156
+ return workspace.get('project_dir', '')
157
+ return ''
158
+
159
+ def get_cwd(self, input_data: dict) -> str:
160
+ """Get current working directory from input."""
161
+ workspace = input_data.get('workspace', {})
162
+ if isinstance(workspace, dict):
163
+ return workspace.get('current_dir', input_data.get('cwd', ''))
164
+ return input_data.get('cwd', '')
165
+
166
+ # =========================================================================
167
+ # Session Start Payload
168
+ # =========================================================================
169
+
170
+ def build_session_start_payload(self, input_data: dict) -> Optional[dict]:
171
+ """
172
+ Build payload for session_start event.
173
+
174
+ Called from SessionStart hook (register-session.py).
175
+ """
176
+ session_id = self.validate_session_id(input_data)
177
+ if not session_id:
178
+ return None
179
+
180
+ # Extract project info
181
+ project_info = self.extract_project_info(input_data)
182
+
183
+ # Extract transcript path and session title
184
+ transcript_path = input_data.get('transcript_path')
185
+ session_title = self.extract_session_title(transcript_path)
186
+
187
+ # Fallback title if transcript empty
188
+ if not session_title:
189
+ session_title = self.generate_fallback_title(project_info['project'])
190
+
191
+ # Get terminal identity
192
+ terminal = self.get_terminal_identity()
193
+ terminal_key = self.build_terminal_key(terminal)
194
+
195
+ # Get auto-compact settings
196
+ autocompact = self.get_autocompact_settings()
197
+
198
+ # Detect git branch and worktree
199
+ git_info = self.detect_git_info(project_info['project_path'])
200
+
201
+ return self.build_base_payload(
202
+ event='session_start',
203
+ session_id=session_id,
204
+ session_title=session_title,
205
+ transcript_path=transcript_path,
206
+ cwd=project_info['cwd'] or self.get_cwd(input_data),
207
+ project=project_info['project'],
208
+ project_dir=project_info['project_path'],
209
+ model=input_data.get('model'),
210
+ hook_source=input_data.get('source', 'startup'), # startup/resume/clear/compact
211
+ terminal=terminal,
212
+ terminal_key=terminal_key,
213
+ autocompact=autocompact,
214
+ git_branch=git_info['git_branch'],
215
+ git_worktree=git_info['git_worktree'],
216
+ git_repo_root=git_info['git_repo_root'],
217
+ permission_mode=input_data.get('permission_mode'),
218
+ )
219
+
220
+ # =========================================================================
221
+ # Activity Payload
222
+ # =========================================================================
223
+
224
+ def build_activity_payload(self, input_data: dict) -> Optional[dict]:
225
+ """
226
+ Build payload for activity event.
227
+
228
+ Called from PostToolUse hook (report-activity.py).
229
+ """
230
+ session_id = self.validate_session_id(input_data)
231
+ if not session_id:
232
+ return None
233
+
234
+ # Extract project info for fallback title
235
+ project_info = self.extract_project_info(input_data)
236
+
237
+ # Extract updated session title
238
+ transcript_path = input_data.get('transcript_path')
239
+ session_title = self.extract_session_title(transcript_path)
240
+
241
+ if not session_title:
242
+ session_title = self.generate_fallback_title(project_info['project'])
243
+
244
+ tool_name = input_data.get('tool_name', 'unknown')
245
+
246
+ return self.build_base_payload(
247
+ event='activity',
248
+ session_id=session_id,
249
+ session_title=session_title,
250
+ tool_name=tool_name,
251
+ terminal_pid=self.get_terminal_identity()['terminal_pid'],
252
+ permission_mode=input_data.get('permission_mode'),
253
+ )
254
+
255
+ # =========================================================================
256
+ # Idle Payload
257
+ # =========================================================================
258
+
259
+ def build_idle_payload(self, input_data: dict) -> Optional[dict]:
260
+ """
261
+ Build payload for idle event.
262
+
263
+ Called from Stop hook (session-idle.py).
264
+ """
265
+ session_id = self.validate_session_id(input_data)
266
+ if not session_id:
267
+ return None
268
+
269
+ return self.build_base_payload(
270
+ event='idle',
271
+ session_id=session_id,
272
+ terminal_pid=self.get_terminal_identity()['terminal_pid'],
273
+ permission_mode=input_data.get('permission_mode'),
274
+ )
275
+
276
+ # =========================================================================
277
+ # Pre-Tool-Use Payload
278
+ # =========================================================================
279
+
280
+ def build_pre_tool_use_payload(self, input_data: dict) -> Optional[dict]:
281
+ """
282
+ Build payload for pre_tool_use event.
283
+
284
+ Called from PreToolUse hook (pre-tool-use.py).
285
+ """
286
+ session_id = self.validate_session_id(input_data)
287
+ if not session_id:
288
+ return None
289
+
290
+ return self.build_base_payload(
291
+ event='pre_tool_use',
292
+ session_id=session_id,
293
+ tool_name=input_data.get('tool_name', 'unknown'),
294
+ terminal_pid=self.get_terminal_identity()['terminal_pid'],
295
+ permission_mode=input_data.get('permission_mode'),
296
+ )
297
+
298
+ # =========================================================================
299
+ # Session End Payload
300
+ # =========================================================================
301
+
302
+ def build_session_end_payload(self, input_data: dict) -> Optional[dict]:
303
+ """
304
+ Build payload for session_end event.
305
+
306
+ Called from SessionEnd hook (unregister-session.py).
307
+ """
308
+ session_id = self.validate_session_id(input_data)
309
+ if not session_id:
310
+ return None
311
+
312
+ return self.build_base_payload(
313
+ event='session_end',
314
+ session_id=session_id,
315
+ terminal_pid=self.get_terminal_identity()['terminal_pid'],
316
+ )
@@ -0,0 +1,288 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ context_parser.py - Parse Claude Code /context command output
4
+
5
+ Parses the visual output of the /context command to extract:
6
+ - Model and total context usage
7
+ - Category breakdown (system prompt, tools, MCP, memory, skills, messages)
8
+ - Individual items within each category
9
+ """
10
+ import re
11
+ from dataclasses import dataclass, field
12
+ from typing import List, Optional, Dict
13
+
14
+
15
+ @dataclass
16
+ class ContextItem:
17
+ """Individual item in a category (e.g., a specific MCP tool or skill)."""
18
+ name: str
19
+ tokens: int
20
+
21
+
22
+ @dataclass
23
+ class ContextCategory:
24
+ """A category in the context breakdown."""
25
+ name: str
26
+ tokens: int
27
+ percentage: float
28
+ items: List[ContextItem] = field(default_factory=list)
29
+
30
+
31
+ @dataclass
32
+ class ContextBreakdown:
33
+ """Full context breakdown from /context command."""
34
+ model: str
35
+ total_tokens: int
36
+ max_tokens: int
37
+ used_percentage: float
38
+
39
+ # Categories
40
+ system_prompt: Optional[ContextCategory] = None
41
+ system_tools: Optional[ContextCategory] = None
42
+ mcp_tools: Optional[ContextCategory] = None
43
+ custom_agents: Optional[ContextCategory] = None
44
+ memory_files: Optional[ContextCategory] = None
45
+ skills: Optional[ContextCategory] = None
46
+ messages: Optional[ContextCategory] = None
47
+ free_space: Optional[ContextCategory] = None
48
+ autocompact_buffer: Optional[ContextCategory] = None
49
+
50
+ # Raw data for debugging
51
+ raw_output: str = ""
52
+
53
+
54
+ def parse_context_output(output: str) -> Optional[ContextBreakdown]:
55
+ """
56
+ Parse the output of Claude Code's /context command.
57
+
58
+ Args:
59
+ output: Raw text output from /context command
60
+
61
+ Returns:
62
+ ContextBreakdown object, or None if parsing fails
63
+ """
64
+ # Check if this looks like /context output
65
+ if "Context Usage" not in output:
66
+ return None
67
+
68
+ breakdown = ContextBreakdown(
69
+ model="",
70
+ total_tokens=0,
71
+ max_tokens=0,
72
+ used_percentage=0.0,
73
+ raw_output=output
74
+ )
75
+
76
+ # Parse header: "claude-sonnet-4-5-20250929 · 48k/200k tokens (24%)"
77
+ header_match = re.search(
78
+ r'([\w-]+)\s*·\s*([\d.]+)k?\s*/\s*([\d.]+)k?\s*tokens\s*\((\d+(?:\.\d+)?)\s*%\)',
79
+ output
80
+ )
81
+ if header_match:
82
+ breakdown.model = header_match.group(1)
83
+ # Handle k suffix
84
+ total_str = header_match.group(2)
85
+ max_str = header_match.group(3)
86
+ breakdown.total_tokens = int(float(total_str) * 1000) if 'k' in output[header_match.start():header_match.end()] else int(float(total_str) * 1000)
87
+ breakdown.max_tokens = int(float(max_str) * 1000)
88
+ breakdown.used_percentage = float(header_match.group(4))
89
+
90
+ # Parse category lines: "⛁ System prompt: 2.5k tokens (1.3%)"
91
+ # Note: some values have 'k' suffix (e.g., "2.5k tokens"), some don't (e.g., "247 tokens")
92
+ category_pattern = re.compile(
93
+ r'[⛁⛀⛶⛝]\s+([\w\s]+):\s*([\d.]+)(k)?\s*tokens\s*\(([\d.]+)\s*%\)'
94
+ )
95
+
96
+ for match in category_pattern.finditer(output):
97
+ name = match.group(1).strip().lower()
98
+ token_value = float(match.group(2))
99
+ has_k_suffix = match.group(3) == 'k'
100
+ tokens = int(token_value * 1000) if has_k_suffix else int(token_value)
101
+ percentage = float(match.group(4))
102
+
103
+ category = ContextCategory(
104
+ name=match.group(1).strip(),
105
+ tokens=tokens,
106
+ percentage=percentage
107
+ )
108
+
109
+ # Map to appropriate field
110
+ if 'system prompt' in name:
111
+ breakdown.system_prompt = category
112
+ elif 'system tools' in name:
113
+ breakdown.system_tools = category
114
+ elif 'mcp tools' in name:
115
+ breakdown.mcp_tools = category
116
+ elif 'custom agents' in name or 'agents' in name:
117
+ breakdown.custom_agents = category
118
+ elif 'memory' in name:
119
+ breakdown.memory_files = category
120
+ elif 'skills' in name:
121
+ breakdown.skills = category
122
+ elif 'messages' in name:
123
+ breakdown.messages = category
124
+ elif 'free' in name:
125
+ breakdown.free_space = category
126
+ elif 'autocompact' in name or 'buffer' in name:
127
+ breakdown.autocompact_buffer = category
128
+
129
+ # Parse individual items within sections
130
+ # MCP tools section: "└ mcp__tool_name: 589 tokens"
131
+ item_pattern = re.compile(r'[└├─]\s*([\w_-]+):\s*(\d+)\s*tokens')
132
+
133
+ # Find section boundaries and parse items
134
+ sections = {
135
+ 'MCP tools': breakdown.mcp_tools,
136
+ 'Custom agents': breakdown.custom_agents,
137
+ 'Memory files': breakdown.memory_files,
138
+ 'Skills': breakdown.skills,
139
+ }
140
+
141
+ for section_name, category in sections.items():
142
+ if category is None:
143
+ continue
144
+
145
+ # Find the section in output
146
+ section_start = output.find(f'{section_name} ·')
147
+ if section_start == -1:
148
+ section_start = output.find(section_name)
149
+ if section_start == -1:
150
+ continue
151
+
152
+ # Find the next section or end
153
+ next_section = len(output)
154
+ for other_name in sections.keys():
155
+ if other_name != section_name:
156
+ pos = output.find(other_name, section_start + len(section_name))
157
+ if pos != -1 and pos < next_section:
158
+ next_section = pos
159
+
160
+ section_text = output[section_start:next_section]
161
+
162
+ # Parse items in this section
163
+ for item_match in item_pattern.finditer(section_text):
164
+ item = ContextItem(
165
+ name=item_match.group(1),
166
+ tokens=int(item_match.group(2))
167
+ )
168
+ category.items.append(item)
169
+
170
+ return breakdown
171
+
172
+
173
+ def find_context_in_terminal(terminal_output: str) -> Optional[str]:
174
+ """
175
+ Find /context command output in terminal text.
176
+
177
+ Looks for the characteristic pattern of /context output.
178
+
179
+ Args:
180
+ terminal_output: Raw terminal output text
181
+
182
+ Returns:
183
+ The /context output section, or None if not found
184
+ """
185
+ # Look for the /context command and its output
186
+ # Pattern: "/context" followed by "Context Usage" block
187
+
188
+ # Find start marker
189
+ start_markers = [
190
+ 'Context Usage',
191
+ '⛁ ⛁ ⛁', # The visual token indicator
192
+ ]
193
+
194
+ start_idx = -1
195
+ for marker in start_markers:
196
+ idx = terminal_output.rfind(marker) # Find most recent
197
+ if idx != -1 and (start_idx == -1 or idx > start_idx):
198
+ start_idx = idx
199
+
200
+ if start_idx == -1:
201
+ return None
202
+
203
+ # Find end marker (next command prompt or significant break)
204
+ end_markers = [
205
+ '\n❯ ', # Claude Code prompt
206
+ '\n> ', # Generic prompt
207
+ '\n$ ', # Shell prompt
208
+ '\n─────', # Separator
209
+ ]
210
+
211
+ # Look for end within reasonable distance (context output is ~50-100 lines)
212
+ search_end = min(start_idx + 5000, len(terminal_output))
213
+ end_idx = search_end
214
+
215
+ # Go back a bit to capture from section start
216
+ start_idx = max(0, start_idx - 200)
217
+
218
+ return terminal_output[start_idx:end_idx]
219
+
220
+
221
+ def to_dict(breakdown: ContextBreakdown) -> Dict:
222
+ """Convert ContextBreakdown to a dictionary for JSON serialization."""
223
+ def category_to_dict(cat: Optional[ContextCategory]) -> Optional[Dict]:
224
+ if cat is None:
225
+ return None
226
+ return {
227
+ 'name': cat.name,
228
+ 'tokens': cat.tokens,
229
+ 'percentage': cat.percentage,
230
+ 'items': [{'name': i.name, 'tokens': i.tokens} for i in cat.items]
231
+ }
232
+
233
+ return {
234
+ 'model': breakdown.model,
235
+ 'total_tokens': breakdown.total_tokens,
236
+ 'max_tokens': breakdown.max_tokens,
237
+ 'used_percentage': breakdown.used_percentage,
238
+ 'categories': {
239
+ 'system_prompt': category_to_dict(breakdown.system_prompt),
240
+ 'system_tools': category_to_dict(breakdown.system_tools),
241
+ 'mcp_tools': category_to_dict(breakdown.mcp_tools),
242
+ 'custom_agents': category_to_dict(breakdown.custom_agents),
243
+ 'memory_files': category_to_dict(breakdown.memory_files),
244
+ 'skills': category_to_dict(breakdown.skills),
245
+ 'messages': category_to_dict(breakdown.messages),
246
+ 'free_space': category_to_dict(breakdown.free_space),
247
+ 'autocompact_buffer': category_to_dict(breakdown.autocompact_buffer),
248
+ }
249
+ }
250
+
251
+
252
+ # Example usage and testing
253
+ if __name__ == '__main__':
254
+ # Sample /context output for testing
255
+ sample_output = """
256
+ ⎿ Context Usage
257
+ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛀ claude-sonnet-4-5-20250929 · 48k/200k tokens (24%)
258
+ ⛁ ⛀ ⛀ ⛀ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁
259
+ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛁ ⛶ ⛶ ⛶ Estimated usage by category
260
+ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛁ System prompt: 2.5k tokens (1.3%)
261
+ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛁ System tools: 17.2k tokens (8.6%)
262
+ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛁ MCP tools: 2.2k tokens (1.1%)
263
+ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛁ Custom agents: 247 tokens (0.1%)
264
+ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛁ Memory files: 843 tokens (0.4%)
265
+ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛶ ⛁ Skills: 687 tokens (0.3%)
266
+ ⛶ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛝ ⛁ Messages: 25.5k tokens (12.8%)
267
+ ⛶ Free space: 118k (58.9%)
268
+ ⛝ Autocompact buffer: 33.0k tokens (16.5%)
269
+
270
+ MCP tools · /mcp
271
+ └ mcp__youtube-transcript__get_youtube_transcript: 589 tokens
272
+ └ mcp__youtube-transcript__get_video_info: 318 tokens
273
+ └ mcp__deepwiki__read_wiki_structure: 123 tokens
274
+
275
+ Memory files · /memory
276
+ └ CLAUDE.md: 843 tokens
277
+
278
+ Skills · /skills
279
+ └ frontend-design: 67 tokens
280
+ └ receiving-code-review: 67 tokens
281
+ """
282
+
283
+ import json
284
+ breakdown = parse_context_output(sample_output)
285
+ if breakdown:
286
+ print(json.dumps(to_dict(breakdown), indent=2))
287
+ else:
288
+ print("Failed to parse")