@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.
- package/dist/assets/mascot-ansi.d.ts +8 -0
- package/dist/assets/mascot-ansi.d.ts.map +1 -0
- package/dist/assets/mascot-ansi.js +15 -0
- package/dist/assets/mascot-ansi.js.map +1 -0
- package/dist/cli.d.ts +15 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/client-helper.d.ts +14 -0
- package/dist/commands/client-helper.d.ts.map +1 -0
- package/dist/commands/client-helper.js +38 -0
- package/dist/commands/client-helper.js.map +1 -0
- package/dist/commands/dashboard.d.ts +8 -0
- package/dist/commands/dashboard.d.ts.map +1 -0
- package/dist/commands/dashboard.js +159 -0
- package/dist/commands/dashboard.js.map +1 -0
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +6 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/list.d.ts +5 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +13 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/search.d.ts +13 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +79 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/setup.d.ts +8 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +32 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/status.d.ts +5 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +27 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/components/ActiveSessionsView.d.ts +18 -0
- package/dist/components/ActiveSessionsView.d.ts.map +1 -0
- package/dist/components/ActiveSessionsView.js +68 -0
- package/dist/components/ActiveSessionsView.js.map +1 -0
- package/dist/components/AddContextConfirmView.d.ts +21 -0
- package/dist/components/AddContextConfirmView.d.ts.map +1 -0
- package/dist/components/AddContextConfirmView.js +44 -0
- package/dist/components/AddContextConfirmView.js.map +1 -0
- package/dist/components/App.d.ts +11 -0
- package/dist/components/App.d.ts.map +1 -0
- package/dist/components/App.js +292 -0
- package/dist/components/App.js.map +1 -0
- package/dist/components/ArchiveBrowserView.d.ts +40 -0
- package/dist/components/ArchiveBrowserView.d.ts.map +1 -0
- package/dist/components/ArchiveBrowserView.js +161 -0
- package/dist/components/ArchiveBrowserView.js.map +1 -0
- package/dist/components/ArchiveInitProgressView.d.ts +16 -0
- package/dist/components/ArchiveInitProgressView.d.ts.map +1 -0
- package/dist/components/ArchiveInitProgressView.js +72 -0
- package/dist/components/ArchiveInitProgressView.js.map +1 -0
- package/dist/components/AutoCompactToggle.d.ts +16 -0
- package/dist/components/AutoCompactToggle.d.ts.map +1 -0
- package/dist/components/AutoCompactToggle.js +12 -0
- package/dist/components/AutoCompactToggle.js.map +1 -0
- package/dist/components/BottomControls.d.ts +12 -0
- package/dist/components/BottomControls.d.ts.map +1 -0
- package/dist/components/BottomControls.js +11 -0
- package/dist/components/BottomControls.js.map +1 -0
- package/dist/components/CompactHeader.d.ts +21 -0
- package/dist/components/CompactHeader.d.ts.map +1 -0
- package/dist/components/CompactHeader.js +63 -0
- package/dist/components/CompactHeader.js.map +1 -0
- package/dist/components/CompactPanel.d.ts +22 -0
- package/dist/components/CompactPanel.d.ts.map +1 -0
- package/dist/components/CompactPanel.js +31 -0
- package/dist/components/CompactPanel.js.map +1 -0
- package/dist/components/ContentBox.d.ts +14 -0
- package/dist/components/ContentBox.d.ts.map +1 -0
- package/dist/components/ContentBox.js +24 -0
- package/dist/components/ContentBox.js.map +1 -0
- package/dist/components/ContextProgress.d.ts +14 -0
- package/dist/components/ContextProgress.d.ts.map +1 -0
- package/dist/components/ContextProgress.js +36 -0
- package/dist/components/ContextProgress.js.map +1 -0
- package/dist/components/Dashboard.d.ts +46 -0
- package/dist/components/Dashboard.d.ts.map +1 -0
- package/dist/components/Dashboard.js +67 -0
- package/dist/components/Dashboard.js.map +1 -0
- package/dist/components/FilterSelectionView.d.ts +15 -0
- package/dist/components/FilterSelectionView.d.ts.map +1 -0
- package/dist/components/FilterSelectionView.js +27 -0
- package/dist/components/FilterSelectionView.js.map +1 -0
- package/dist/components/GoogleDocsBrowserView.d.ts +20 -0
- package/dist/components/GoogleDocsBrowserView.d.ts.map +1 -0
- package/dist/components/GoogleDocsBrowserView.js +72 -0
- package/dist/components/GoogleDocsBrowserView.js.map +1 -0
- package/dist/components/HandoffBrowserView.d.ts +20 -0
- package/dist/components/HandoffBrowserView.d.ts.map +1 -0
- package/dist/components/HandoffBrowserView.js +66 -0
- package/dist/components/HandoffBrowserView.js.map +1 -0
- package/dist/components/Header.d.ts +14 -0
- package/dist/components/Header.d.ts.map +1 -0
- package/dist/components/Header.js +16 -0
- package/dist/components/Header.js.map +1 -0
- package/dist/components/HorizontalMenu.d.ts +24 -0
- package/dist/components/HorizontalMenu.d.ts.map +1 -0
- package/dist/components/HorizontalMenu.js +20 -0
- package/dist/components/HorizontalMenu.js.map +1 -0
- package/dist/components/ImageMascot.d.ts +8 -0
- package/dist/components/ImageMascot.d.ts.map +1 -0
- package/dist/components/ImageMascot.js +7 -0
- package/dist/components/ImageMascot.js.map +1 -0
- package/dist/components/LLMWorkingView.d.ts +19 -0
- package/dist/components/LLMWorkingView.d.ts.map +1 -0
- package/dist/components/LLMWorkingView.js +72 -0
- package/dist/components/LLMWorkingView.js.map +1 -0
- package/dist/components/LoadContextView.d.ts +22 -0
- package/dist/components/LoadContextView.d.ts.map +1 -0
- package/dist/components/LoadContextView.js +83 -0
- package/dist/components/LoadContextView.js.map +1 -0
- package/dist/components/MainMenuView.d.ts +20 -0
- package/dist/components/MainMenuView.d.ts.map +1 -0
- package/dist/components/MainMenuView.js +49 -0
- package/dist/components/MainMenuView.js.map +1 -0
- package/dist/components/Mascot.d.ts +24 -0
- package/dist/components/Mascot.d.ts.map +1 -0
- package/dist/components/Mascot.js +32 -0
- package/dist/components/Mascot.js.map +1 -0
- package/dist/components/Menu.d.ts +22 -0
- package/dist/components/Menu.d.ts.map +1 -0
- package/dist/components/Menu.js +28 -0
- package/dist/components/Menu.js.map +1 -0
- package/dist/components/NotionBrowserView.d.ts +21 -0
- package/dist/components/NotionBrowserView.d.ts.map +1 -0
- package/dist/components/NotionBrowserView.js +75 -0
- package/dist/components/NotionBrowserView.js.map +1 -0
- package/dist/components/ObsidianBrowserView.d.ts +21 -0
- package/dist/components/ObsidianBrowserView.d.ts.map +1 -0
- package/dist/components/ObsidianBrowserView.js +74 -0
- package/dist/components/ObsidianBrowserView.js.map +1 -0
- package/dist/components/ObsidianConfigView.d.ts +19 -0
- package/dist/components/ObsidianConfigView.d.ts.map +1 -0
- package/dist/components/ObsidianConfigView.js +45 -0
- package/dist/components/ObsidianConfigView.js.map +1 -0
- package/dist/components/PlaceholderView.d.ts +15 -0
- package/dist/components/PlaceholderView.d.ts.map +1 -0
- package/dist/components/PlaceholderView.js +20 -0
- package/dist/components/PlaceholderView.js.map +1 -0
- package/dist/components/PlanViewerView.d.ts +26 -0
- package/dist/components/PlanViewerView.d.ts.map +1 -0
- package/dist/components/PlanViewerView.js +170 -0
- package/dist/components/PlanViewerView.js.map +1 -0
- package/dist/components/ProgressBar.d.ts +24 -0
- package/dist/components/ProgressBar.d.ts.map +1 -0
- package/dist/components/ProgressBar.js +23 -0
- package/dist/components/ProgressBar.js.map +1 -0
- package/dist/components/ProjectDashboardView.d.ts +38 -0
- package/dist/components/ProjectDashboardView.d.ts.map +1 -0
- package/dist/components/ProjectDashboardView.js +129 -0
- package/dist/components/ProjectDashboardView.js.map +1 -0
- package/dist/components/SaveContextView.d.ts +32 -0
- package/dist/components/SaveContextView.d.ts.map +1 -0
- package/dist/components/SaveContextView.js +41 -0
- package/dist/components/SaveContextView.js.map +1 -0
- package/dist/components/SessionDetails.d.ts +14 -0
- package/dist/components/SessionDetails.d.ts.map +1 -0
- package/dist/components/SessionDetails.js +87 -0
- package/dist/components/SessionDetails.js.map +1 -0
- package/dist/components/SessionsExperimentView.d.ts +35 -0
- package/dist/components/SessionsExperimentView.d.ts.map +1 -0
- package/dist/components/SessionsExperimentView.js +347 -0
- package/dist/components/SessionsExperimentView.js.map +1 -0
- package/dist/components/SessionsList.d.ts +20 -0
- package/dist/components/SessionsList.d.ts.map +1 -0
- package/dist/components/SessionsList.js +75 -0
- package/dist/components/SessionsList.js.map +1 -0
- package/dist/components/SettingsView.d.ts +48 -0
- package/dist/components/SettingsView.d.ts.map +1 -0
- package/dist/components/SettingsView.js +156 -0
- package/dist/components/SettingsView.js.map +1 -0
- package/dist/components/SourceSelectionView.d.ts +26 -0
- package/dist/components/SourceSelectionView.d.ts.map +1 -0
- package/dist/components/SourceSelectionView.js +109 -0
- package/dist/components/SourceSelectionView.js.map +1 -0
- package/dist/components/VerticalMenu.d.ts +18 -0
- package/dist/components/VerticalMenu.d.ts.map +1 -0
- package/dist/components/VerticalMenu.js +15 -0
- package/dist/components/VerticalMenu.js.map +1 -0
- package/dist/components/ascii-art/index.d.ts +6 -0
- package/dist/components/ascii-art/index.d.ts.map +1 -0
- package/dist/components/ascii-art/index.js +6 -0
- package/dist/components/ascii-art/index.js.map +1 -0
- package/dist/components/ascii-art/progress.d.ts +53 -0
- package/dist/components/ascii-art/progress.d.ts.map +1 -0
- package/dist/components/ascii-art/progress.js +102 -0
- package/dist/components/ascii-art/progress.js.map +1 -0
- package/dist/components/ascii-art/scene.d.ts +34 -0
- package/dist/components/ascii-art/scene.d.ts.map +1 -0
- package/dist/components/ascii-art/scene.js +72 -0
- package/dist/components/ascii-art/scene.js.map +1 -0
- package/dist/components/index.d.ts +27 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +25 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/layout/HorizontalLayout.d.ts +19 -0
- package/dist/components/layout/HorizontalLayout.d.ts.map +1 -0
- package/dist/components/layout/HorizontalLayout.js +62 -0
- package/dist/components/layout/HorizontalLayout.js.map +1 -0
- package/dist/components/layout/VerticalLayout.d.ts +16 -0
- package/dist/components/layout/VerticalLayout.d.ts.map +1 -0
- package/dist/components/layout/VerticalLayout.js +32 -0
- package/dist/components/layout/VerticalLayout.js.map +1 -0
- package/dist/components/layout/index.d.ts +6 -0
- package/dist/components/layout/index.d.ts.map +1 -0
- package/dist/components/layout/index.js +4 -0
- package/dist/components/layout/index.js.map +1 -0
- package/dist/components/layout/theme.d.ts +20 -0
- package/dist/components/layout/theme.d.ts.map +1 -0
- package/dist/components/layout/theme.js +23 -0
- package/dist/components/layout/theme.js.map +1 -0
- package/dist/components/setup/DoneStep.d.ts +7 -0
- package/dist/components/setup/DoneStep.d.ts.map +1 -0
- package/dist/components/setup/DoneStep.js +31 -0
- package/dist/components/setup/DoneStep.js.map +1 -0
- package/dist/components/setup/InstallingStep.d.ts +11 -0
- package/dist/components/setup/InstallingStep.d.ts.map +1 -0
- package/dist/components/setup/InstallingStep.js +27 -0
- package/dist/components/setup/InstallingStep.js.map +1 -0
- package/dist/components/setup/OptionsStep.d.ts +9 -0
- package/dist/components/setup/OptionsStep.d.ts.map +1 -0
- package/dist/components/setup/OptionsStep.js +39 -0
- package/dist/components/setup/OptionsStep.js.map +1 -0
- package/dist/components/setup/PrerequisitesStep.d.ts +7 -0
- package/dist/components/setup/PrerequisitesStep.d.ts.map +1 -0
- package/dist/components/setup/PrerequisitesStep.js +31 -0
- package/dist/components/setup/PrerequisitesStep.js.map +1 -0
- package/dist/components/setup/SetupFrame.d.ts +17 -0
- package/dist/components/setup/SetupFrame.d.ts.map +1 -0
- package/dist/components/setup/SetupFrame.js +33 -0
- package/dist/components/setup/SetupFrame.js.map +1 -0
- package/dist/components/setup/SetupWizard.d.ts +9 -0
- package/dist/components/setup/SetupWizard.d.ts.map +1 -0
- package/dist/components/setup/SetupWizard.js +149 -0
- package/dist/components/setup/SetupWizard.js.map +1 -0
- package/dist/components/setup/Spinner.d.ts +10 -0
- package/dist/components/setup/Spinner.d.ts.map +1 -0
- package/dist/components/setup/Spinner.js +20 -0
- package/dist/components/setup/Spinner.js.map +1 -0
- package/dist/components/setup/SyncStep.d.ts +11 -0
- package/dist/components/setup/SyncStep.d.ts.map +1 -0
- package/dist/components/setup/SyncStep.js +47 -0
- package/dist/components/setup/SyncStep.js.map +1 -0
- package/dist/components/setup/VerificationStep.d.ts +7 -0
- package/dist/components/setup/VerificationStep.d.ts.map +1 -0
- package/dist/components/setup/VerificationStep.js +27 -0
- package/dist/components/setup/VerificationStep.js.map +1 -0
- package/dist/components/setup/WelcomeStep.d.ts +6 -0
- package/dist/components/setup/WelcomeStep.d.ts.map +1 -0
- package/dist/components/setup/WelcomeStep.js +17 -0
- package/dist/components/setup/WelcomeStep.js.map +1 -0
- package/dist/components/shared/ProgressLine.d.ts +10 -0
- package/dist/components/shared/ProgressLine.d.ts.map +1 -0
- package/dist/components/shared/ProgressLine.js +18 -0
- package/dist/components/shared/ProgressLine.js.map +1 -0
- package/dist/components/shared/ProjectLine.d.ts +10 -0
- package/dist/components/shared/ProjectLine.d.ts.map +1 -0
- package/dist/components/shared/ProjectLine.js +19 -0
- package/dist/components/shared/ProjectLine.js.map +1 -0
- package/dist/components/shared/ScanningIndicator.d.ts +9 -0
- package/dist/components/shared/ScanningIndicator.d.ts.map +1 -0
- package/dist/components/shared/ScanningIndicator.js +22 -0
- package/dist/components/shared/ScanningIndicator.js.map +1 -0
- package/dist/components/shared/StatusLine.d.ts +13 -0
- package/dist/components/shared/StatusLine.d.ts.map +1 -0
- package/dist/components/shared/StatusLine.js +24 -0
- package/dist/components/shared/StatusLine.js.map +1 -0
- package/dist/components/shared/StatusLine.test.d.ts +8 -0
- package/dist/components/shared/StatusLine.test.d.ts.map +1 -0
- package/dist/components/shared/StatusLine.test.js +50 -0
- package/dist/components/shared/StatusLine.test.js.map +1 -0
- package/dist/components/shared/index.d.ts +4 -0
- package/dist/components/shared/index.d.ts.map +1 -0
- package/dist/components/shared/index.js +4 -0
- package/dist/components/shared/index.js.map +1 -0
- package/dist/handoff/catalog.test.d.ts +5 -0
- package/dist/handoff/catalog.test.d.ts.map +1 -0
- package/dist/handoff/catalog.test.js +172 -0
- package/dist/handoff/catalog.test.js.map +1 -0
- package/dist/handoff/subagents.test.d.ts +8 -0
- package/dist/handoff/subagents.test.d.ts.map +1 -0
- package/dist/handoff/subagents.test.js +139 -0
- package/dist/handoff/subagents.test.js.map +1 -0
- package/dist/hooks/useAddContextFlow.d.ts +29 -0
- package/dist/hooks/useAddContextFlow.d.ts.map +1 -0
- package/dist/hooks/useAddContextFlow.js +83 -0
- package/dist/hooks/useAddContextFlow.js.map +1 -0
- package/dist/hooks/useArchiveBrowser.d.ts +37 -0
- package/dist/hooks/useArchiveBrowser.d.ts.map +1 -0
- package/dist/hooks/useArchiveBrowser.js +175 -0
- package/dist/hooks/useArchiveBrowser.js.map +1 -0
- package/dist/hooks/useClaudeToken.d.ts +29 -0
- package/dist/hooks/useClaudeToken.d.ts.map +1 -0
- package/dist/hooks/useClaudeToken.js +166 -0
- package/dist/hooks/useClaudeToken.js.map +1 -0
- package/dist/hooks/useGoogleDocsBrowser.d.ts +29 -0
- package/dist/hooks/useGoogleDocsBrowser.d.ts.map +1 -0
- package/dist/hooks/useGoogleDocsBrowser.js +146 -0
- package/dist/hooks/useGoogleDocsBrowser.js.map +1 -0
- package/dist/hooks/useHandoffBrowser.d.ts +27 -0
- package/dist/hooks/useHandoffBrowser.d.ts.map +1 -0
- package/dist/hooks/useHandoffBrowser.js +92 -0
- package/dist/hooks/useHandoffBrowser.js.map +1 -0
- package/dist/hooks/useJacquesClient.d.ts +69 -0
- package/dist/hooks/useJacquesClient.d.ts.map +1 -0
- package/dist/hooks/useJacquesClient.js +248 -0
- package/dist/hooks/useJacquesClient.js.map +1 -0
- package/dist/hooks/useLlmWorking.d.ts +30 -0
- package/dist/hooks/useLlmWorking.d.ts.map +1 -0
- package/dist/hooks/useLlmWorking.js +127 -0
- package/dist/hooks/useLlmWorking.js.map +1 -0
- package/dist/hooks/useLoadContext.d.ts +27 -0
- package/dist/hooks/useLoadContext.d.ts.map +1 -0
- package/dist/hooks/useLoadContext.js +102 -0
- package/dist/hooks/useLoadContext.js.map +1 -0
- package/dist/hooks/useNotification.d.ts +36 -0
- package/dist/hooks/useNotification.d.ts.map +1 -0
- package/dist/hooks/useNotification.js +89 -0
- package/dist/hooks/useNotification.js.map +1 -0
- package/dist/hooks/useNotification.test.d.ts +9 -0
- package/dist/hooks/useNotification.test.d.ts.map +1 -0
- package/dist/hooks/useNotification.test.js +144 -0
- package/dist/hooks/useNotification.test.js.map +1 -0
- package/dist/hooks/useNotionBrowser.d.ts +30 -0
- package/dist/hooks/useNotionBrowser.d.ts.map +1 -0
- package/dist/hooks/useNotionBrowser.js +154 -0
- package/dist/hooks/useNotionBrowser.js.map +1 -0
- package/dist/hooks/useObsidianBrowser.d.ts +42 -0
- package/dist/hooks/useObsidianBrowser.d.ts.map +1 -0
- package/dist/hooks/useObsidianBrowser.js +63 -0
- package/dist/hooks/useObsidianBrowser.js.map +1 -0
- package/dist/hooks/useObsidianConfig.d.ts +28 -0
- package/dist/hooks/useObsidianConfig.d.ts.map +1 -0
- package/dist/hooks/useObsidianConfig.js +119 -0
- package/dist/hooks/useObsidianConfig.js.map +1 -0
- package/dist/hooks/useObsidianFileBrowser.d.ts +29 -0
- package/dist/hooks/useObsidianFileBrowser.d.ts.map +1 -0
- package/dist/hooks/useObsidianFileBrowser.js +114 -0
- package/dist/hooks/useObsidianFileBrowser.js.map +1 -0
- package/dist/hooks/useProjectDashboard.d.ts +38 -0
- package/dist/hooks/useProjectDashboard.d.ts.map +1 -0
- package/dist/hooks/useProjectDashboard.js +224 -0
- package/dist/hooks/useProjectDashboard.js.map +1 -0
- package/dist/hooks/useProjectSelector.d.ts +17 -0
- package/dist/hooks/useProjectSelector.d.ts.map +1 -0
- package/dist/hooks/useProjectSelector.js +43 -0
- package/dist/hooks/useProjectSelector.js.map +1 -0
- package/dist/hooks/useProjectSelector.test.d.ts +7 -0
- package/dist/hooks/useProjectSelector.test.d.ts.map +1 -0
- package/dist/hooks/useProjectSelector.test.js +117 -0
- package/dist/hooks/useProjectSelector.test.js.map +1 -0
- package/dist/hooks/useSaveFlow.d.ts +30 -0
- package/dist/hooks/useSaveFlow.d.ts.map +1 -0
- package/dist/hooks/useSaveFlow.js +195 -0
- package/dist/hooks/useSaveFlow.js.map +1 -0
- package/dist/hooks/useSessions.test.d.ts +7 -0
- package/dist/hooks/useSessions.test.d.ts.map +1 -0
- package/dist/hooks/useSessions.test.js +153 -0
- package/dist/hooks/useSessions.test.js.map +1 -0
- package/dist/hooks/useSessionsExperiment.d.ts +97 -0
- package/dist/hooks/useSessionsExperiment.d.ts.map +1 -0
- package/dist/hooks/useSessionsExperiment.js +321 -0
- package/dist/hooks/useSessionsExperiment.js.map +1 -0
- package/dist/hooks/useSettings.d.ts +47 -0
- package/dist/hooks/useSettings.d.ts.map +1 -0
- package/dist/hooks/useSettings.js +245 -0
- package/dist/hooks/useSettings.js.map +1 -0
- package/dist/hooks/useSetupWizard.d.ts +35 -0
- package/dist/hooks/useSetupWizard.d.ts.map +1 -0
- package/dist/hooks/useSetupWizard.js +438 -0
- package/dist/hooks/useSetupWizard.js.map +1 -0
- package/dist/hooks/useUsageLimits.d.ts +24 -0
- package/dist/hooks/useUsageLimits.d.ts.map +1 -0
- package/dist/hooks/useUsageLimits.js +58 -0
- package/dist/hooks/useUsageLimits.js.map +1 -0
- package/dist/hooks/useUsageLimits.test.d.ts +7 -0
- package/dist/hooks/useUsageLimits.test.d.ts.map +1 -0
- package/dist/hooks/useUsageLimits.test.js +136 -0
- package/dist/hooks/useUsageLimits.test.js.map +1 -0
- package/dist/hooks/useWorktrees.d.ts +28 -0
- package/dist/hooks/useWorktrees.d.ts.map +1 -0
- package/dist/hooks/useWorktrees.js +57 -0
- package/dist/hooks/useWorktrees.js.map +1 -0
- package/dist/hooks/useWorktrees.test.d.ts +7 -0
- package/dist/hooks/useWorktrees.test.d.ts.map +1 -0
- package/dist/hooks/useWorktrees.test.js +119 -0
- package/dist/hooks/useWorktrees.test.js.map +1 -0
- package/dist/templates/compact-prompt.d.ts +16 -0
- package/dist/templates/compact-prompt.d.ts.map +1 -0
- package/dist/templates/compact-prompt.js +47 -0
- package/dist/templates/compact-prompt.js.map +1 -0
- package/dist/templates/context-skill.d.ts +8 -0
- package/dist/templates/context-skill.d.ts.map +1 -0
- package/dist/templates/context-skill.js +42 -0
- package/dist/templates/context-skill.js.map +1 -0
- package/dist/types.d.ts +127 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +8 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/activity.d.ts +17 -0
- package/dist/utils/activity.d.ts.map +1 -0
- package/dist/utils/activity.js +78 -0
- package/dist/utils/activity.js.map +1 -0
- package/dist/utils/bottom-controls.d.ts +24 -0
- package/dist/utils/bottom-controls.d.ts.map +1 -0
- package/dist/utils/bottom-controls.js +29 -0
- package/dist/utils/bottom-controls.js.map +1 -0
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +20 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/constants.d.ts +6 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +6 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/format.d.ts +17 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +31 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/session-mode.d.ts +14 -0
- package/dist/utils/session-mode.d.ts.map +1 -0
- package/dist/utils/session-mode.js +29 -0
- package/dist/utils/session-mode.js.map +1 -0
- package/dist/utils/session-mode.test.d.ts +7 -0
- package/dist/utils/session-mode.test.d.ts.map +1 -0
- package/dist/utils/session-mode.test.js +102 -0
- package/dist/utils/session-mode.test.js.map +1 -0
- package/dist/utils/sessions-items-builder.d.ts +29 -0
- package/dist/utils/sessions-items-builder.d.ts.map +1 -0
- package/dist/utils/sessions-items-builder.js +394 -0
- package/dist/utils/sessions-items-builder.js.map +1 -0
- package/dist/utils/settings.d.ts +100 -0
- package/dist/utils/settings.d.ts.map +1 -0
- package/dist/utils/settings.js +206 -0
- package/dist/utils/settings.js.map +1 -0
- package/dist/websocket-client.d.ts +70 -0
- package/dist/websocket-client.d.ts.map +1 -0
- package/dist/websocket-client.js +188 -0
- package/dist/websocket-client.js.map +1 -0
- package/hooks/adapters/__init__.py +17 -0
- package/hooks/adapters/__pycache__/__init__.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/__init__.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/__init__.cpython-314.pyc +0 -0
- package/hooks/adapters/__pycache__/base.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/base.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/base.cpython-314.pyc +0 -0
- package/hooks/adapters/__pycache__/calibration.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/calibration.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/calibration.cpython-314.pyc +0 -0
- package/hooks/adapters/__pycache__/claude_code.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/claude_code.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/claude_code.cpython-314.pyc +0 -0
- package/hooks/adapters/__pycache__/cursor.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/cursor.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/cursor.cpython-314.pyc +0 -0
- package/hooks/adapters/__pycache__/skills.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/skills.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/skills.cpython-314.pyc +0 -0
- package/hooks/adapters/__pycache__/test_adapters.cpython-311-pytest-9.0.2.pyc +0 -0
- package/hooks/adapters/__pycache__/test_adapters.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/test_calibration.cpython-311-pytest-9.0.2.pyc +0 -0
- package/hooks/adapters/__pycache__/test_skills.cpython-311-pytest-9.0.2.pyc +0 -0
- package/hooks/adapters/__pycache__/test_tokenizer.cpython-311-pytest-9.0.2.pyc +0 -0
- package/hooks/adapters/__pycache__/tokenizer.cpython-311.pyc +0 -0
- package/hooks/adapters/__pycache__/tokenizer.cpython-313.pyc +0 -0
- package/hooks/adapters/__pycache__/tokenizer.cpython-314.pyc +0 -0
- package/hooks/adapters/base.py +459 -0
- package/hooks/adapters/calibration.py +236 -0
- package/hooks/adapters/claude_code.py +316 -0
- package/hooks/adapters/context_parser.py +288 -0
- package/hooks/adapters/cursor.py +258 -0
- package/hooks/adapters/skills.py +160 -0
- package/hooks/adapters/template.py +281 -0
- package/hooks/adapters/test_adapters.py +516 -0
- package/hooks/adapters/test_calibration.py +235 -0
- package/hooks/adapters/test_skills.py +162 -0
- package/hooks/adapters/test_tokenizer.py +158 -0
- package/hooks/adapters/tokenizer.py +192 -0
- package/hooks/claude-code/pre-tool-use.py +36 -0
- package/hooks/claude-code/register-session.py +35 -0
- package/hooks/claude-code/report-activity.py +32 -0
- package/hooks/claude-code/session-idle.py +32 -0
- package/hooks/claude-code/statusline.sh +91 -0
- package/hooks/claude-code/unregister-session.py +32 -0
- package/hooks/cursor/README.md +61 -0
- package/hooks/cursor/after-agent-response.py +97 -0
- package/hooks/cursor/hooks.json.template +30 -0
- package/hooks/cursor/post-tool-use.py +32 -0
- package/hooks/cursor/pre-compact.py +61 -0
- package/hooks/cursor/session-end.py +32 -0
- package/hooks/cursor/session-start.py +66 -0
- package/hooks/git-detect.sh +47 -0
- package/hooks/install.py +441 -0
- package/hooks/jacques-register-session.py +286 -0
- package/hooks/jacques-report-activity.py +145 -0
- package/hooks/jacques-session-idle.py +57 -0
- package/hooks/jacques-unregister-session.py +57 -0
- package/hooks/requirements.txt +9 -0
- package/hooks/statusline.py +457 -0
- package/hooks/statusline.sh +212 -0
- package/package.json +63 -0
- package/skills/jacques-continue/SKILL.md +87 -0
- 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")
|