@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,61 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
pre-compact.py - Receive Cursor context metrics and calibrate estimates
|
|
4
|
+
|
|
5
|
+
Called on Cursor's preCompact hook.
|
|
6
|
+
This is the KEY hook that provides context usage metrics for Cursor!
|
|
7
|
+
|
|
8
|
+
The preCompact event fires when Cursor is about to compact the context,
|
|
9
|
+
and contains valuable information about current context window usage.
|
|
10
|
+
|
|
11
|
+
Additionally, this hook calibrates token estimation by comparing
|
|
12
|
+
actual metrics with previous estimates.
|
|
13
|
+
"""
|
|
14
|
+
import sys
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
# Add parent directory to path for adapter imports
|
|
18
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
19
|
+
|
|
20
|
+
from adapters.cursor import CursorAdapter
|
|
21
|
+
from adapters import calibration
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def main():
|
|
25
|
+
adapter = CursorAdapter()
|
|
26
|
+
|
|
27
|
+
# Parse input from stdin
|
|
28
|
+
input_data = adapter.parse_input()
|
|
29
|
+
if not input_data:
|
|
30
|
+
sys.exit(0)
|
|
31
|
+
|
|
32
|
+
# Debug logging (important for understanding Cursor's data format)
|
|
33
|
+
adapter.log_debug(input_data, 'preCompact')
|
|
34
|
+
|
|
35
|
+
# Get session ID and actual token count for calibration
|
|
36
|
+
session_id = input_data.get('conversation_id')
|
|
37
|
+
actual_tokens = input_data.get('context_tokens', 0)
|
|
38
|
+
|
|
39
|
+
if session_id and actual_tokens > 0:
|
|
40
|
+
# Calibrate: compare actual vs estimated
|
|
41
|
+
factor = calibration.calibrate_from_actual(session_id, actual_tokens)
|
|
42
|
+
|
|
43
|
+
if factor:
|
|
44
|
+
# Log calibration for debugging
|
|
45
|
+
try:
|
|
46
|
+
with open('/tmp/jacques-hook-debug.log', 'a') as f:
|
|
47
|
+
f.write(f"[calibration] session={session_id[:8]}... ")
|
|
48
|
+
f.write(f"actual={actual_tokens} factor={factor:.2f}\n")
|
|
49
|
+
except:
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
# Build and send context_update payload (with actual values)
|
|
53
|
+
payload = adapter.build_pre_compact_payload(input_data)
|
|
54
|
+
if payload:
|
|
55
|
+
# Mark this as actual (not estimate) by ensuring is_estimate is False/absent
|
|
56
|
+
payload['is_estimate'] = False
|
|
57
|
+
adapter.send_event(payload, use_fallback=False)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
if __name__ == '__main__':
|
|
61
|
+
main()
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
session-end.py - Unregister Cursor session from Jacques
|
|
4
|
+
|
|
5
|
+
Called on Cursor's sessionEnd hook.
|
|
6
|
+
Removes Cursor session from Jacques server.
|
|
7
|
+
"""
|
|
8
|
+
import sys
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
# Add parent directory to path for adapter imports
|
|
12
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
13
|
+
|
|
14
|
+
from adapters.cursor import CursorAdapter
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def main():
|
|
18
|
+
adapter = CursorAdapter()
|
|
19
|
+
|
|
20
|
+
# Parse input from stdin
|
|
21
|
+
input_data = adapter.parse_input()
|
|
22
|
+
if not input_data:
|
|
23
|
+
sys.exit(0)
|
|
24
|
+
|
|
25
|
+
# Build and send session_end payload
|
|
26
|
+
payload = adapter.build_session_end_payload(input_data)
|
|
27
|
+
if payload:
|
|
28
|
+
adapter.send_event(payload, use_fallback=False)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
main()
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
session-start.py - Register Cursor session with Jacques
|
|
4
|
+
|
|
5
|
+
Called on Cursor's sessionStart hook.
|
|
6
|
+
Registers new Cursor Native AI session with the Jacques server.
|
|
7
|
+
|
|
8
|
+
Also sends initial context estimate based on installed skills.
|
|
9
|
+
Cursor injects all agent_skills into every chat context, so we estimate
|
|
10
|
+
that overhead to show a realistic starting percentage instead of 0%.
|
|
11
|
+
|
|
12
|
+
Typical overhead:
|
|
13
|
+
- 21 skills ≈ 34,000 tokens
|
|
14
|
+
- On 200k context (Claude): ~17% used by skills alone
|
|
15
|
+
"""
|
|
16
|
+
import sys
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
# Add parent directory to path for adapter imports
|
|
20
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
21
|
+
|
|
22
|
+
from adapters.cursor import CursorAdapter
|
|
23
|
+
from adapters import skills
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def main():
|
|
27
|
+
adapter = CursorAdapter()
|
|
28
|
+
|
|
29
|
+
# Parse input from stdin
|
|
30
|
+
input_data = adapter.parse_input()
|
|
31
|
+
if not input_data:
|
|
32
|
+
sys.exit(0)
|
|
33
|
+
|
|
34
|
+
# Debug logging
|
|
35
|
+
adapter.log_debug(input_data, 'sessionStart')
|
|
36
|
+
|
|
37
|
+
# Build and send session_start payload
|
|
38
|
+
payload = adapter.build_session_start_payload(input_data)
|
|
39
|
+
if payload:
|
|
40
|
+
adapter.send_event(payload, use_fallback=True)
|
|
41
|
+
|
|
42
|
+
# Estimate initial context from installed skills
|
|
43
|
+
# Cursor injects all skills into context, so this is more accurate than 0%
|
|
44
|
+
model = adapter.get_model(input_data)
|
|
45
|
+
initial_estimate = skills.get_initial_context_estimate(model)
|
|
46
|
+
|
|
47
|
+
# Log skill overhead for debugging
|
|
48
|
+
try:
|
|
49
|
+
with open('/tmp/jacques-hook-debug.log', 'a') as f:
|
|
50
|
+
f.write(f"[session-start] Initial estimate: {skills.get_skills_summary()}\n")
|
|
51
|
+
f.write(f"[session-start] Starting at {initial_estimate['used_percentage']}%\n")
|
|
52
|
+
except:
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
# Send initial context estimate (skills + system prompt overhead)
|
|
56
|
+
context_payload = adapter.build_context_estimate_payload(
|
|
57
|
+
input_data,
|
|
58
|
+
estimated_tokens=initial_estimate['total_initial_tokens'],
|
|
59
|
+
model=model,
|
|
60
|
+
)
|
|
61
|
+
if context_payload:
|
|
62
|
+
adapter.send_event(context_payload, use_fallback=False)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
if __name__ == '__main__':
|
|
66
|
+
main()
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# git-detect.sh - Single source of truth for git detection
|
|
4
|
+
#
|
|
5
|
+
# Usage: git-detect.sh <project_dir>
|
|
6
|
+
# Outputs 3 lines:
|
|
7
|
+
# 1. git_branch - current branch name (empty if not git)
|
|
8
|
+
# 2. git_worktree - worktree basename (empty if main repo)
|
|
9
|
+
# 3. git_repo_root - main worktree root path (empty if not git)
|
|
10
|
+
#
|
|
11
|
+
# Detection algorithm:
|
|
12
|
+
# git rev-parse --abbrev-ref HEAD -> branch name
|
|
13
|
+
# git rev-parse --git-common-dir -> shared .git path
|
|
14
|
+
# Returns ".git" (relative) -> normal repo -> repo_root = project_dir
|
|
15
|
+
# Returns absolute path -> worktree -> repo_root = dirname(path)
|
|
16
|
+
|
|
17
|
+
project_dir="$1"
|
|
18
|
+
|
|
19
|
+
if [ -z "$project_dir" ] || [ ! -d "$project_dir" ]; then
|
|
20
|
+
printf '\n\n\n'
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Single git command to get both branch and common-dir
|
|
25
|
+
git_output=$(git -C "$project_dir" rev-parse --abbrev-ref HEAD --git-common-dir 2>/dev/null)
|
|
26
|
+
|
|
27
|
+
if [ -z "$git_output" ]; then
|
|
28
|
+
printf '\n\n\n'
|
|
29
|
+
exit 0
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
branch=$(echo "$git_output" | sed -n '1p')
|
|
33
|
+
common=$(echo "$git_output" | sed -n '2p')
|
|
34
|
+
|
|
35
|
+
worktree=""
|
|
36
|
+
repo_root=""
|
|
37
|
+
|
|
38
|
+
if [ "$common" = ".git" ]; then
|
|
39
|
+
# Normal repo (not a worktree) - resolve to absolute path
|
|
40
|
+
repo_root=$(cd "$project_dir" && pwd)
|
|
41
|
+
elif [ -n "$common" ]; then
|
|
42
|
+
# Worktree - common dir is absolute path to shared .git
|
|
43
|
+
repo_root=$(dirname "$common")
|
|
44
|
+
worktree=$(basename "$project_dir")
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
printf '%s\n%s\n%s\n' "$branch" "$worktree" "$repo_root"
|
package/hooks/install.py
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
install.py - Unified installer for Jacques hooks
|
|
4
|
+
|
|
5
|
+
Installs hooks for various AI tools:
|
|
6
|
+
- Claude Code CLI: ~/.claude/settings.json
|
|
7
|
+
- Cursor Native: .cursor/hooks.json (per-project)
|
|
8
|
+
|
|
9
|
+
Usage:
|
|
10
|
+
python3 install.py --source claude_code # Install Claude Code hooks
|
|
11
|
+
python3 install.py --source cursor # Install Cursor hooks
|
|
12
|
+
python3 install.py --all # Install all sources
|
|
13
|
+
python3 install.py --list # Show available sources
|
|
14
|
+
python3 install.py --status # Show installation status
|
|
15
|
+
"""
|
|
16
|
+
import argparse
|
|
17
|
+
import json
|
|
18
|
+
import os
|
|
19
|
+
import shutil
|
|
20
|
+
import sys
|
|
21
|
+
from datetime import datetime
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from typing import Optional, List, Dict, Any
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# ============================================================================
|
|
27
|
+
# Configuration
|
|
28
|
+
# ============================================================================
|
|
29
|
+
|
|
30
|
+
JACQUES_HOME = Path.home() / '.jacques'
|
|
31
|
+
HOOKS_DIR = JACQUES_HOME / 'hooks'
|
|
32
|
+
SCRIPT_DIR = Path(__file__).parent
|
|
33
|
+
|
|
34
|
+
SOURCES = {
|
|
35
|
+
'claude_code': {
|
|
36
|
+
'name': 'Claude Code CLI',
|
|
37
|
+
'description': 'Claude Code CLI (standalone or in Cursor terminal)',
|
|
38
|
+
'config_path': Path.home() / '.claude' / 'settings.json',
|
|
39
|
+
'hooks_subdir': 'claude-code',
|
|
40
|
+
'hooks': {
|
|
41
|
+
'SessionStart': 'register-session.py',
|
|
42
|
+
'PreToolUse': 'pre-tool-use.py',
|
|
43
|
+
'PostToolUse': 'report-activity.py',
|
|
44
|
+
'Stop': 'session-idle.py',
|
|
45
|
+
'SessionEnd': 'unregister-session.py',
|
|
46
|
+
},
|
|
47
|
+
'statusline': 'statusline.sh',
|
|
48
|
+
},
|
|
49
|
+
'cursor': {
|
|
50
|
+
'name': 'Cursor Native',
|
|
51
|
+
'description': 'Cursor Native AI (sidebar chat)',
|
|
52
|
+
'config_template': SCRIPT_DIR / 'cursor' / 'hooks.json.template',
|
|
53
|
+
'hooks_subdir': 'cursor',
|
|
54
|
+
'hooks': {
|
|
55
|
+
'sessionStart': 'session-start.py',
|
|
56
|
+
'sessionEnd': 'session-end.py',
|
|
57
|
+
'postToolUse': 'post-tool-use.py',
|
|
58
|
+
'preCompact': 'pre-compact.py',
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# ============================================================================
|
|
65
|
+
# Utility Functions
|
|
66
|
+
# ============================================================================
|
|
67
|
+
|
|
68
|
+
def log(message: str, level: str = 'info') -> None:
|
|
69
|
+
"""Print a log message with color."""
|
|
70
|
+
colors = {
|
|
71
|
+
'info': '\033[0m', # Default
|
|
72
|
+
'success': '\033[92m', # Green
|
|
73
|
+
'warning': '\033[93m', # Yellow
|
|
74
|
+
'error': '\033[91m', # Red
|
|
75
|
+
}
|
|
76
|
+
reset = '\033[0m'
|
|
77
|
+
color = colors.get(level, colors['info'])
|
|
78
|
+
prefix = {
|
|
79
|
+
'info': ' ',
|
|
80
|
+
'success': '✓ ',
|
|
81
|
+
'warning': '⚠ ',
|
|
82
|
+
'error': '✗ ',
|
|
83
|
+
}.get(level, ' ')
|
|
84
|
+
print(f"{color}{prefix}{message}{reset}")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def backup_file(path: Path) -> Optional[Path]:
|
|
88
|
+
"""Create a backup of a file. Returns backup path or None if file doesn't exist."""
|
|
89
|
+
if not path.exists():
|
|
90
|
+
return None
|
|
91
|
+
|
|
92
|
+
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
|
|
93
|
+
backup_path = path.parent / f"{path.name}.backup_{timestamp}"
|
|
94
|
+
shutil.copy2(path, backup_path)
|
|
95
|
+
log(f"Backed up {path} → {backup_path}", 'info')
|
|
96
|
+
return backup_path
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def ensure_directory(path: Path) -> None:
|
|
100
|
+
"""Create directory if it doesn't exist."""
|
|
101
|
+
path.mkdir(parents=True, exist_ok=True)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ============================================================================
|
|
105
|
+
# Installation Functions
|
|
106
|
+
# ============================================================================
|
|
107
|
+
|
|
108
|
+
def install_hook_files(source: str) -> bool:
|
|
109
|
+
"""
|
|
110
|
+
Install hook files to ~/.jacques/hooks/{source}/
|
|
111
|
+
|
|
112
|
+
Returns True if successful.
|
|
113
|
+
"""
|
|
114
|
+
config = SOURCES[source]
|
|
115
|
+
hooks_subdir = config['hooks_subdir']
|
|
116
|
+
|
|
117
|
+
# Source and destination directories
|
|
118
|
+
src_dir = SCRIPT_DIR / hooks_subdir
|
|
119
|
+
dst_dir = HOOKS_DIR / hooks_subdir
|
|
120
|
+
adapters_src = SCRIPT_DIR / 'adapters'
|
|
121
|
+
adapters_dst = HOOKS_DIR / 'adapters'
|
|
122
|
+
|
|
123
|
+
if not src_dir.exists():
|
|
124
|
+
log(f"Source directory not found: {src_dir}", 'error')
|
|
125
|
+
return False
|
|
126
|
+
|
|
127
|
+
# Create destination directories
|
|
128
|
+
ensure_directory(dst_dir)
|
|
129
|
+
ensure_directory(adapters_dst)
|
|
130
|
+
|
|
131
|
+
# Copy adapters
|
|
132
|
+
log(f"Installing adapters to {adapters_dst}", 'info')
|
|
133
|
+
for file in adapters_src.glob('*.py'):
|
|
134
|
+
dst_file = adapters_dst / file.name
|
|
135
|
+
# Skip if source and dest are the same file (e.g., symlinks)
|
|
136
|
+
try:
|
|
137
|
+
if file.resolve() == dst_file.resolve():
|
|
138
|
+
log(f" Skipped {file.name} (same file)", 'info')
|
|
139
|
+
continue
|
|
140
|
+
except:
|
|
141
|
+
pass
|
|
142
|
+
shutil.copy2(file, dst_file)
|
|
143
|
+
log(f" Copied {file.name}", 'info')
|
|
144
|
+
|
|
145
|
+
# Copy hook files
|
|
146
|
+
log(f"Installing {config['name']} hooks to {dst_dir}", 'info')
|
|
147
|
+
for hook_name, filename in config['hooks'].items():
|
|
148
|
+
src_file = src_dir / filename
|
|
149
|
+
if src_file.exists():
|
|
150
|
+
dst_file = dst_dir / filename
|
|
151
|
+
# Skip if source and dest are the same file
|
|
152
|
+
try:
|
|
153
|
+
if src_file.resolve() == dst_file.resolve():
|
|
154
|
+
log(f" {hook_name} → {filename} (already linked)", 'success')
|
|
155
|
+
continue
|
|
156
|
+
except:
|
|
157
|
+
pass
|
|
158
|
+
shutil.copy2(src_file, dst_file)
|
|
159
|
+
# Make executable
|
|
160
|
+
os.chmod(dst_file, 0o755)
|
|
161
|
+
log(f" {hook_name} → {filename}", 'success')
|
|
162
|
+
else:
|
|
163
|
+
log(f" Missing: {filename}", 'warning')
|
|
164
|
+
|
|
165
|
+
# Copy statusline script if exists
|
|
166
|
+
if 'statusline' in config:
|
|
167
|
+
statusline_src = src_dir / config['statusline']
|
|
168
|
+
if statusline_src.exists():
|
|
169
|
+
statusline_dst = dst_dir / config['statusline']
|
|
170
|
+
# Skip if source and dest are the same file
|
|
171
|
+
try:
|
|
172
|
+
if statusline_src.resolve() == statusline_dst.resolve():
|
|
173
|
+
log(f" statusLine → {config['statusline']} (already linked)", 'success')
|
|
174
|
+
else:
|
|
175
|
+
shutil.copy2(statusline_src, statusline_dst)
|
|
176
|
+
os.chmod(statusline_dst, 0o755)
|
|
177
|
+
log(f" statusLine → {config['statusline']}", 'success')
|
|
178
|
+
except:
|
|
179
|
+
shutil.copy2(statusline_src, statusline_dst)
|
|
180
|
+
os.chmod(statusline_dst, 0o755)
|
|
181
|
+
log(f" statusLine → {config['statusline']}", 'success')
|
|
182
|
+
|
|
183
|
+
return True
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
def install_claude_code() -> bool:
|
|
187
|
+
"""
|
|
188
|
+
Install Claude Code hooks by updating ~/.claude/settings.json
|
|
189
|
+
|
|
190
|
+
Returns True if successful.
|
|
191
|
+
"""
|
|
192
|
+
# First, install hook files
|
|
193
|
+
if not install_hook_files('claude_code'):
|
|
194
|
+
return False
|
|
195
|
+
|
|
196
|
+
config = SOURCES['claude_code']
|
|
197
|
+
settings_path = config['config_path']
|
|
198
|
+
|
|
199
|
+
# Load or create settings
|
|
200
|
+
settings: Dict[str, Any] = {}
|
|
201
|
+
if settings_path.exists():
|
|
202
|
+
backup_file(settings_path)
|
|
203
|
+
try:
|
|
204
|
+
with open(settings_path, 'r') as f:
|
|
205
|
+
settings = json.load(f)
|
|
206
|
+
except json.JSONDecodeError:
|
|
207
|
+
log(f"Invalid JSON in {settings_path}, creating new", 'warning')
|
|
208
|
+
settings = {}
|
|
209
|
+
|
|
210
|
+
# Build hooks configuration
|
|
211
|
+
hooks_base = str(HOOKS_DIR / config['hooks_subdir'])
|
|
212
|
+
|
|
213
|
+
hooks_config = {
|
|
214
|
+
'SessionStart': [f"python3 {hooks_base}/register-session.py"],
|
|
215
|
+
'PreToolUse': [f"python3 {hooks_base}/pre-tool-use.py"],
|
|
216
|
+
'PostToolUse': [f"python3 {hooks_base}/report-activity.py"],
|
|
217
|
+
'Stop': [f"python3 {hooks_base}/session-idle.py"],
|
|
218
|
+
'SessionEnd': [f"python3 {hooks_base}/unregister-session.py"],
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
# Build statusLine configuration
|
|
222
|
+
statusline_path = f"{hooks_base}/statusline.sh"
|
|
223
|
+
|
|
224
|
+
# Update settings
|
|
225
|
+
settings['hooks'] = hooks_config
|
|
226
|
+
settings['statusLine'] = statusline_path
|
|
227
|
+
|
|
228
|
+
# Write settings
|
|
229
|
+
ensure_directory(settings_path.parent)
|
|
230
|
+
with open(settings_path, 'w') as f:
|
|
231
|
+
json.dump(settings, f, indent=2)
|
|
232
|
+
|
|
233
|
+
log(f"Updated {settings_path}", 'success')
|
|
234
|
+
log("Claude Code hooks installed successfully!", 'success')
|
|
235
|
+
|
|
236
|
+
return True
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def install_cursor(project_path: Optional[Path] = None) -> bool:
|
|
240
|
+
"""
|
|
241
|
+
Install Cursor hooks by copying hooks.json template.
|
|
242
|
+
|
|
243
|
+
Args:
|
|
244
|
+
project_path: Optional project directory. If not provided, installs globally.
|
|
245
|
+
|
|
246
|
+
Returns True if successful.
|
|
247
|
+
"""
|
|
248
|
+
# First, install hook files
|
|
249
|
+
if not install_hook_files('cursor'):
|
|
250
|
+
return False
|
|
251
|
+
|
|
252
|
+
config = SOURCES['cursor']
|
|
253
|
+
template_path = config['config_template']
|
|
254
|
+
|
|
255
|
+
if not template_path.exists():
|
|
256
|
+
log(f"Template not found: {template_path}", 'error')
|
|
257
|
+
return False
|
|
258
|
+
|
|
259
|
+
# Determine destination
|
|
260
|
+
if project_path:
|
|
261
|
+
dest_path = project_path / '.cursor' / 'hooks.json'
|
|
262
|
+
else:
|
|
263
|
+
# Print instructions for manual installation
|
|
264
|
+
log("Cursor hooks installed to ~/.jacques/hooks/cursor/", 'success')
|
|
265
|
+
log("", 'info')
|
|
266
|
+
log("To enable for a project, copy the template:", 'info')
|
|
267
|
+
log(f" cp {template_path} /path/to/project/.cursor/hooks.json", 'info')
|
|
268
|
+
log("", 'info')
|
|
269
|
+
log("Or copy to current directory:", 'info')
|
|
270
|
+
log(f" mkdir -p .cursor && cp {template_path} .cursor/hooks.json", 'info')
|
|
271
|
+
return True
|
|
272
|
+
|
|
273
|
+
# Copy template
|
|
274
|
+
ensure_directory(dest_path.parent)
|
|
275
|
+
if dest_path.exists():
|
|
276
|
+
backup_file(dest_path)
|
|
277
|
+
|
|
278
|
+
shutil.copy2(template_path, dest_path)
|
|
279
|
+
log(f"Installed hooks to {dest_path}", 'success')
|
|
280
|
+
log("Cursor hooks installed successfully!", 'success')
|
|
281
|
+
|
|
282
|
+
return True
|
|
283
|
+
|
|
284
|
+
|
|
285
|
+
def install_source(source: str, project_path: Optional[Path] = None) -> bool:
|
|
286
|
+
"""Install hooks for a specific source."""
|
|
287
|
+
if source not in SOURCES:
|
|
288
|
+
log(f"Unknown source: {source}", 'error')
|
|
289
|
+
log(f"Available sources: {', '.join(SOURCES.keys())}", 'info')
|
|
290
|
+
return False
|
|
291
|
+
|
|
292
|
+
log(f"Installing {SOURCES[source]['name']} hooks...", 'info')
|
|
293
|
+
|
|
294
|
+
if source == 'claude_code':
|
|
295
|
+
return install_claude_code()
|
|
296
|
+
elif source == 'cursor':
|
|
297
|
+
return install_cursor(project_path)
|
|
298
|
+
|
|
299
|
+
return False
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
def install_all() -> bool:
|
|
303
|
+
"""Install all available sources."""
|
|
304
|
+
success = True
|
|
305
|
+
for source in SOURCES:
|
|
306
|
+
log(f"\n--- {SOURCES[source]['name']} ---", 'info')
|
|
307
|
+
if not install_source(source):
|
|
308
|
+
success = False
|
|
309
|
+
return success
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
# ============================================================================
|
|
313
|
+
# Status Functions
|
|
314
|
+
# ============================================================================
|
|
315
|
+
|
|
316
|
+
def check_status() -> None:
|
|
317
|
+
"""Check installation status for all sources."""
|
|
318
|
+
log("Jacques Hook Installation Status", 'info')
|
|
319
|
+
log("=" * 40, 'info')
|
|
320
|
+
|
|
321
|
+
# Check ~/.jacques directory
|
|
322
|
+
if JACQUES_HOME.exists():
|
|
323
|
+
log(f"Jacques home: {JACQUES_HOME}", 'success')
|
|
324
|
+
else:
|
|
325
|
+
log(f"Jacques home not found: {JACQUES_HOME}", 'warning')
|
|
326
|
+
|
|
327
|
+
# Check adapters
|
|
328
|
+
adapters_dir = HOOKS_DIR / 'adapters'
|
|
329
|
+
if adapters_dir.exists() and (adapters_dir / 'base.py').exists():
|
|
330
|
+
log(f"Adapters: Installed", 'success')
|
|
331
|
+
else:
|
|
332
|
+
log(f"Adapters: Not installed", 'warning')
|
|
333
|
+
|
|
334
|
+
log("", 'info')
|
|
335
|
+
|
|
336
|
+
# Check each source
|
|
337
|
+
for source, config in SOURCES.items():
|
|
338
|
+
log(f"{config['name']}:", 'info')
|
|
339
|
+
|
|
340
|
+
# Check hooks directory
|
|
341
|
+
hooks_dir = HOOKS_DIR / config['hooks_subdir']
|
|
342
|
+
if hooks_dir.exists():
|
|
343
|
+
hook_count = len(list(hooks_dir.glob('*.py')))
|
|
344
|
+
log(f" Hooks directory: {hooks_dir} ({hook_count} files)", 'success')
|
|
345
|
+
else:
|
|
346
|
+
log(f" Hooks directory: Not found", 'warning')
|
|
347
|
+
|
|
348
|
+
# Check config file
|
|
349
|
+
if source == 'claude_code':
|
|
350
|
+
settings_path = config['config_path']
|
|
351
|
+
if settings_path.exists():
|
|
352
|
+
try:
|
|
353
|
+
with open(settings_path, 'r') as f:
|
|
354
|
+
settings = json.load(f)
|
|
355
|
+
if 'hooks' in settings:
|
|
356
|
+
log(f" Config: {settings_path} (hooks configured)", 'success')
|
|
357
|
+
else:
|
|
358
|
+
log(f" Config: {settings_path} (no hooks)", 'warning')
|
|
359
|
+
except:
|
|
360
|
+
log(f" Config: {settings_path} (invalid JSON)", 'error')
|
|
361
|
+
else:
|
|
362
|
+
log(f" Config: Not found", 'warning')
|
|
363
|
+
|
|
364
|
+
log("", 'info')
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def list_sources() -> None:
|
|
368
|
+
"""List available sources."""
|
|
369
|
+
log("Available Sources:", 'info')
|
|
370
|
+
log("=" * 40, 'info')
|
|
371
|
+
for source, config in SOURCES.items():
|
|
372
|
+
log(f" {source}: {config['description']}", 'info')
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
# ============================================================================
|
|
376
|
+
# Main
|
|
377
|
+
# ============================================================================
|
|
378
|
+
|
|
379
|
+
def main():
|
|
380
|
+
parser = argparse.ArgumentParser(
|
|
381
|
+
description='Install Jacques hooks for AI tools',
|
|
382
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
383
|
+
epilog="""
|
|
384
|
+
Examples:
|
|
385
|
+
python3 install.py --source claude_code Install Claude Code hooks
|
|
386
|
+
python3 install.py --source cursor Install Cursor hooks
|
|
387
|
+
python3 install.py --all Install all sources
|
|
388
|
+
python3 install.py --list List available sources
|
|
389
|
+
python3 install.py --status Show installation status
|
|
390
|
+
"""
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
parser.add_argument(
|
|
394
|
+
'--source', '-s',
|
|
395
|
+
help='Source to install (claude_code, cursor)',
|
|
396
|
+
choices=list(SOURCES.keys()),
|
|
397
|
+
)
|
|
398
|
+
parser.add_argument(
|
|
399
|
+
'--all', '-a',
|
|
400
|
+
action='store_true',
|
|
401
|
+
help='Install all available sources',
|
|
402
|
+
)
|
|
403
|
+
parser.add_argument(
|
|
404
|
+
'--list', '-l',
|
|
405
|
+
action='store_true',
|
|
406
|
+
help='List available sources',
|
|
407
|
+
)
|
|
408
|
+
parser.add_argument(
|
|
409
|
+
'--status',
|
|
410
|
+
action='store_true',
|
|
411
|
+
help='Show installation status',
|
|
412
|
+
)
|
|
413
|
+
parser.add_argument(
|
|
414
|
+
'--project', '-p',
|
|
415
|
+
type=Path,
|
|
416
|
+
help='Project directory for Cursor hooks',
|
|
417
|
+
)
|
|
418
|
+
|
|
419
|
+
args = parser.parse_args()
|
|
420
|
+
|
|
421
|
+
if args.list:
|
|
422
|
+
list_sources()
|
|
423
|
+
return 0
|
|
424
|
+
|
|
425
|
+
if args.status:
|
|
426
|
+
check_status()
|
|
427
|
+
return 0
|
|
428
|
+
|
|
429
|
+
if args.all:
|
|
430
|
+
return 0 if install_all() else 1
|
|
431
|
+
|
|
432
|
+
if args.source:
|
|
433
|
+
return 0 if install_source(args.source, args.project) else 1
|
|
434
|
+
|
|
435
|
+
# No arguments - show help
|
|
436
|
+
parser.print_help()
|
|
437
|
+
return 0
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
if __name__ == '__main__':
|
|
441
|
+
sys.exit(main())
|