@akiojin/gwt 2.0.0 → 2.0.3
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/claude-history.d.ts +60 -0
- package/dist/claude-history.d.ts.map +1 -0
- package/dist/claude-history.js +606 -0
- package/dist/claude-history.js.map +1 -0
- package/dist/claude.d.ts +12 -0
- package/dist/claude.d.ts.map +1 -0
- package/dist/claude.js +222 -0
- package/dist/claude.js.map +1 -0
- package/dist/cli/ui/components/App.d.ts +22 -0
- package/dist/cli/ui/components/App.d.ts.map +1 -0
- package/dist/cli/ui/components/App.js +557 -0
- package/dist/cli/ui/components/App.js.map +1 -0
- package/dist/cli/ui/components/common/Confirm.d.ts +13 -0
- package/dist/cli/ui/components/common/Confirm.d.ts.map +1 -0
- package/dist/cli/ui/components/common/Confirm.js +20 -0
- package/dist/cli/ui/components/common/Confirm.js.map +1 -0
- package/dist/cli/ui/components/common/ErrorBoundary.d.ts +23 -0
- package/dist/cli/ui/components/common/ErrorBoundary.d.ts.map +1 -0
- package/dist/cli/ui/components/common/ErrorBoundary.js +37 -0
- package/dist/cli/ui/components/common/ErrorBoundary.js.map +1 -0
- package/dist/cli/ui/components/common/Input.d.ts +14 -0
- package/dist/cli/ui/components/common/Input.d.ts.map +1 -0
- package/dist/cli/ui/components/common/Input.js +14 -0
- package/dist/cli/ui/components/common/Input.js.map +1 -0
- package/dist/cli/ui/components/common/LoadingIndicator.d.ts +19 -0
- package/dist/cli/ui/components/common/LoadingIndicator.d.ts.map +1 -0
- package/dist/cli/ui/components/common/LoadingIndicator.js +61 -0
- package/dist/cli/ui/components/common/LoadingIndicator.js.map +1 -0
- package/dist/cli/ui/components/common/Select.d.ts +30 -0
- package/dist/cli/ui/components/common/Select.d.ts.map +1 -0
- package/dist/cli/ui/components/common/Select.js +140 -0
- package/dist/cli/ui/components/common/Select.js.map +1 -0
- package/dist/cli/ui/components/parts/Footer.d.ts +15 -0
- package/dist/cli/ui/components/parts/Footer.d.ts.map +1 -0
- package/dist/cli/ui/components/parts/Footer.js +20 -0
- package/dist/cli/ui/components/parts/Footer.js.map +1 -0
- package/dist/cli/ui/components/parts/Header.d.ts +29 -0
- package/dist/cli/ui/components/parts/Header.d.ts.map +1 -0
- package/dist/cli/ui/components/parts/Header.js +19 -0
- package/dist/cli/ui/components/parts/Header.js.map +1 -0
- package/dist/cli/ui/components/parts/MergeStatusList.d.ts +13 -0
- package/dist/cli/ui/components/parts/MergeStatusList.d.ts.map +1 -0
- package/dist/cli/ui/components/parts/MergeStatusList.js +52 -0
- package/dist/cli/ui/components/parts/MergeStatusList.js.map +1 -0
- package/dist/cli/ui/components/parts/ProgressBar.d.ts +13 -0
- package/dist/cli/ui/components/parts/ProgressBar.d.ts.map +1 -0
- package/dist/cli/ui/components/parts/ProgressBar.js +53 -0
- package/dist/cli/ui/components/parts/ProgressBar.js.map +1 -0
- package/dist/cli/ui/components/parts/ScrollableList.d.ts +12 -0
- package/dist/cli/ui/components/parts/ScrollableList.d.ts.map +1 -0
- package/dist/cli/ui/components/parts/ScrollableList.js +11 -0
- package/dist/cli/ui/components/parts/ScrollableList.js.map +1 -0
- package/dist/cli/ui/components/parts/Stats.d.ts +13 -0
- package/dist/cli/ui/components/parts/Stats.d.ts.map +1 -0
- package/dist/cli/ui/components/parts/Stats.js +42 -0
- package/dist/cli/ui/components/parts/Stats.js.map +1 -0
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.d.ts +20 -0
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.js +77 -0
- package/dist/cli/ui/components/screens/AIToolSelectorScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts +14 -0
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js +41 -0
- package/dist/cli/ui/components/screens/BatchMergeProgressScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts +14 -0
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.js +71 -0
- package/dist/cli/ui/components/screens/BatchMergeResultScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts +15 -0
- package/dist/cli/ui/components/screens/BranchCreatorScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/BranchCreatorScreen.js +142 -0
- package/dist/cli/ui/components/screens/BranchCreatorScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts +39 -0
- package/dist/cli/ui/components/screens/BranchListScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/BranchListScreen.js +172 -0
- package/dist/cli/ui/components/screens/BranchListScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts +29 -0
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js +92 -0
- package/dist/cli/ui/components/screens/ExecutionModeSelectorScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts +23 -0
- package/dist/cli/ui/components/screens/PRCleanupScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/PRCleanupScreen.js +94 -0
- package/dist/cli/ui/components/screens/PRCleanupScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts +17 -0
- package/dist/cli/ui/components/screens/SessionSelectorScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/SessionSelectorScreen.js +55 -0
- package/dist/cli/ui/components/screens/SessionSelectorScreen.js.map +1 -0
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.d.ts +20 -0
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.d.ts.map +1 -0
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.js +65 -0
- package/dist/cli/ui/components/screens/WorktreeManagerScreen.js.map +1 -0
- package/dist/cli/ui/hooks/useBatchMerge.d.ts +17 -0
- package/dist/cli/ui/hooks/useBatchMerge.d.ts.map +1 -0
- package/dist/cli/ui/hooks/useBatchMerge.js +77 -0
- package/dist/cli/ui/hooks/useBatchMerge.js.map +1 -0
- package/dist/cli/ui/hooks/useGitData.d.ts +20 -0
- package/dist/cli/ui/hooks/useGitData.d.ts.map +1 -0
- package/dist/cli/ui/hooks/useGitData.js +116 -0
- package/dist/cli/ui/hooks/useGitData.js.map +1 -0
- package/dist/cli/ui/hooks/useScreenState.d.ts +12 -0
- package/dist/cli/ui/hooks/useScreenState.d.ts.map +1 -0
- package/dist/cli/ui/hooks/useScreenState.js +30 -0
- package/dist/cli/ui/hooks/useScreenState.js.map +1 -0
- package/dist/cli/ui/hooks/useTerminalSize.d.ts +9 -0
- package/dist/cli/ui/hooks/useTerminalSize.d.ts.map +1 -0
- package/dist/cli/ui/hooks/useTerminalSize.js +24 -0
- package/dist/cli/ui/hooks/useTerminalSize.js.map +1 -0
- package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts +21 -0
- package/dist/cli/ui/screens/BranchActionSelectorScreen.d.ts.map +1 -0
- package/dist/cli/ui/screens/BranchActionSelectorScreen.js +61 -0
- package/dist/cli/ui/screens/BranchActionSelectorScreen.js.map +1 -0
- package/dist/cli/ui/types.d.ts +245 -0
- package/dist/cli/ui/types.d.ts.map +1 -0
- package/dist/cli/ui/types.js +2 -0
- package/dist/cli/ui/types.js.map +1 -0
- package/dist/cli/ui/utils/baseBranch.d.ts +4 -0
- package/dist/cli/ui/utils/baseBranch.d.ts.map +1 -0
- package/dist/cli/ui/utils/baseBranch.js +17 -0
- package/dist/cli/ui/utils/baseBranch.js.map +1 -0
- package/dist/cli/ui/utils/branchFormatter.d.ts +13 -0
- package/dist/cli/ui/utils/branchFormatter.d.ts.map +1 -0
- package/dist/cli/ui/utils/branchFormatter.js +202 -0
- package/dist/cli/ui/utils/branchFormatter.js.map +1 -0
- package/dist/cli/ui/utils/statisticsCalculator.d.ts +9 -0
- package/dist/cli/ui/utils/statisticsCalculator.d.ts.map +1 -0
- package/dist/cli/ui/utils/statisticsCalculator.js +37 -0
- package/dist/cli/ui/utils/statisticsCalculator.js.map +1 -0
- package/dist/client/assets/index-CqaYsI0z.js +81 -0
- package/dist/client/assets/index-Dy3OxWpP.css +32 -0
- package/dist/client/index.html +13 -0
- package/dist/codex.d.ts +12 -0
- package/dist/codex.d.ts.map +1 -0
- package/dist/codex.js +106 -0
- package/dist/codex.js.map +1 -0
- package/dist/config/builtin-tools.d.ts +19 -0
- package/dist/config/builtin-tools.d.ts.map +1 -0
- package/dist/config/builtin-tools.js +40 -0
- package/dist/config/builtin-tools.js.map +1 -0
- package/dist/config/constants.d.ts +74 -0
- package/dist/config/constants.d.ts.map +1 -0
- package/dist/config/constants.js +90 -0
- package/dist/config/constants.js.map +1 -0
- package/dist/config/env-history.d.ts +4 -0
- package/dist/config/env-history.d.ts.map +1 -0
- package/dist/config/env-history.js +34 -0
- package/dist/config/env-history.js.map +1 -0
- package/dist/config/index.d.ts +24 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +144 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/tools.d.ts +40 -0
- package/dist/config/tools.d.ts.map +1 -0
- package/dist/config/tools.js +238 -0
- package/dist/config/tools.js.map +1 -0
- package/dist/git.d.ts +145 -0
- package/dist/git.d.ts.map +1 -0
- package/dist/git.js +871 -0
- package/dist/git.js.map +1 -0
- package/dist/github.d.ts +14 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +123 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +510 -0
- package/dist/index.js.map +1 -0
- package/dist/launcher.d.ts +30 -0
- package/dist/launcher.d.ts.map +1 -0
- package/dist/launcher.js +116 -0
- package/dist/launcher.js.map +1 -0
- package/dist/repositories/git.repository.d.ts +38 -0
- package/dist/repositories/git.repository.d.ts.map +1 -0
- package/dist/repositories/git.repository.js +117 -0
- package/dist/repositories/git.repository.js.map +1 -0
- package/dist/repositories/github.repository.d.ts +16 -0
- package/dist/repositories/github.repository.d.ts.map +1 -0
- package/dist/repositories/github.repository.js +61 -0
- package/dist/repositories/github.repository.js.map +1 -0
- package/dist/repositories/worktree.repository.d.ts +18 -0
- package/dist/repositories/worktree.repository.d.ts.map +1 -0
- package/dist/repositories/worktree.repository.js +57 -0
- package/dist/repositories/worktree.repository.js.map +1 -0
- package/dist/services/BatchMergeService.d.ts +45 -0
- package/dist/services/BatchMergeService.d.ts.map +1 -0
- package/dist/services/BatchMergeService.js +197 -0
- package/dist/services/BatchMergeService.js.map +1 -0
- package/dist/services/WorktreeOrchestrator.d.ts +37 -0
- package/dist/services/WorktreeOrchestrator.d.ts.map +1 -0
- package/dist/services/WorktreeOrchestrator.js +74 -0
- package/dist/services/WorktreeOrchestrator.js.map +1 -0
- package/dist/services/dependency-installer.d.ts +26 -0
- package/dist/services/dependency-installer.d.ts.map +1 -0
- package/dist/services/dependency-installer.js +139 -0
- package/dist/services/dependency-installer.js.map +1 -0
- package/dist/services/git.service.d.ts +27 -0
- package/dist/services/git.service.d.ts.map +1 -0
- package/dist/services/git.service.js +95 -0
- package/dist/services/git.service.js.map +1 -0
- package/dist/services/github.service.d.ts +14 -0
- package/dist/services/github.service.d.ts.map +1 -0
- package/dist/services/github.service.js +52 -0
- package/dist/services/github.service.js.map +1 -0
- package/dist/services/worktree.service.d.ts +20 -0
- package/dist/services/worktree.service.d.ts.map +1 -0
- package/dist/services/worktree.service.js +52 -0
- package/dist/services/worktree.service.js.map +1 -0
- package/dist/types/api.d.ts +211 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +8 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/tools.d.ts +201 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +8 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/spinner.d.ts +6 -0
- package/dist/utils/spinner.d.ts.map +1 -0
- package/dist/utils/spinner.js +47 -0
- package/dist/utils/spinner.js.map +1 -0
- package/dist/utils/terminal.d.ts +20 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +232 -0
- package/dist/utils/terminal.js.map +1 -0
- package/dist/utils.d.ts +9 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +48 -0
- package/dist/utils.js.map +1 -0
- package/dist/web/client/src/components/BranchGraph.d.ts +8 -0
- package/dist/web/client/src/components/BranchGraph.d.ts.map +1 -0
- package/dist/web/client/src/components/BranchGraph.js +125 -0
- package/dist/web/client/src/components/BranchGraph.js.map +1 -0
- package/dist/web/client/src/components/EnvEditor.d.ts +20 -0
- package/dist/web/client/src/components/EnvEditor.d.ts.map +1 -0
- package/dist/web/client/src/components/EnvEditor.js +65 -0
- package/dist/web/client/src/components/EnvEditor.js.map +1 -0
- package/dist/web/client/src/components/Terminal.d.ts +15 -0
- package/dist/web/client/src/components/Terminal.d.ts.map +1 -0
- package/dist/web/client/src/components/Terminal.js +112 -0
- package/dist/web/client/src/components/Terminal.js.map +1 -0
- package/dist/web/client/src/hooks/useBranches.d.ts +16 -0
- package/dist/web/client/src/hooks/useBranches.d.ts.map +1 -0
- package/dist/web/client/src/hooks/useBranches.js +35 -0
- package/dist/web/client/src/hooks/useBranches.js.map +1 -0
- package/dist/web/client/src/hooks/useConfig.d.ts +13 -0
- package/dist/web/client/src/hooks/useConfig.d.ts.map +1 -0
- package/dist/web/client/src/hooks/useConfig.js +27 -0
- package/dist/web/client/src/hooks/useConfig.js.map +1 -0
- package/dist/web/client/src/hooks/useSessions.d.ts +21 -0
- package/dist/web/client/src/hooks/useSessions.d.ts.map +1 -0
- package/dist/web/client/src/hooks/useSessions.js +49 -0
- package/dist/web/client/src/hooks/useSessions.js.map +1 -0
- package/dist/web/client/src/hooks/useWorktrees.d.ts +17 -0
- package/dist/web/client/src/hooks/useWorktrees.d.ts.map +1 -0
- package/dist/web/client/src/hooks/useWorktrees.js +41 -0
- package/dist/web/client/src/hooks/useWorktrees.js.map +1 -0
- package/dist/web/client/src/lib/api.d.ts +82 -0
- package/dist/web/client/src/lib/api.d.ts.map +1 -0
- package/dist/web/client/src/lib/api.js +147 -0
- package/dist/web/client/src/lib/api.js.map +1 -0
- package/dist/web/client/src/lib/websocket.d.ts +52 -0
- package/dist/web/client/src/lib/websocket.d.ts.map +1 -0
- package/dist/web/client/src/lib/websocket.js +137 -0
- package/dist/web/client/src/lib/websocket.js.map +1 -0
- package/dist/web/client/src/main.d.ts +2 -0
- package/dist/web/client/src/main.d.ts.map +1 -0
- package/dist/web/client/src/main.js +23 -0
- package/dist/web/client/src/main.js.map +1 -0
- package/dist/web/client/src/pages/BranchDetailPage.d.ts +3 -0
- package/dist/web/client/src/pages/BranchDetailPage.d.ts.map +1 -0
- package/dist/web/client/src/pages/BranchDetailPage.js +519 -0
- package/dist/web/client/src/pages/BranchDetailPage.js.map +1 -0
- package/dist/web/client/src/pages/BranchListPage.d.ts +3 -0
- package/dist/web/client/src/pages/BranchListPage.d.ts.map +1 -0
- package/dist/web/client/src/pages/BranchListPage.js +150 -0
- package/dist/web/client/src/pages/BranchListPage.js.map +1 -0
- package/dist/web/client/src/pages/ConfigManagementPage.d.ts +3 -0
- package/dist/web/client/src/pages/ConfigManagementPage.d.ts.map +1 -0
- package/dist/web/client/src/pages/ConfigManagementPage.js +125 -0
- package/dist/web/client/src/pages/ConfigManagementPage.js.map +1 -0
- package/dist/web/client/src/router.d.ts +9 -0
- package/dist/web/client/src/router.d.ts.map +1 -0
- package/dist/web/client/src/router.js +27 -0
- package/dist/web/client/src/router.js.map +1 -0
- package/dist/web/client/vite.config.d.ts +3 -0
- package/dist/web/client/vite.config.d.ts.map +1 -0
- package/dist/web/client/vite.config.js +21 -0
- package/dist/web/client/vite.config.js.map +1 -0
- package/dist/web/server/env/importer.d.ts +3 -0
- package/dist/web/server/env/importer.d.ts.map +1 -0
- package/dist/web/server/env/importer.js +47 -0
- package/dist/web/server/env/importer.js.map +1 -0
- package/dist/web/server/index.d.ts +11 -0
- package/dist/web/server/index.d.ts.map +1 -0
- package/dist/web/server/index.js +62 -0
- package/dist/web/server/index.js.map +1 -0
- package/dist/web/server/pty/manager.d.ts +50 -0
- package/dist/web/server/pty/manager.d.ts.map +1 -0
- package/dist/web/server/pty/manager.js +143 -0
- package/dist/web/server/pty/manager.js.map +1 -0
- package/dist/web/server/routes/branches.d.ts +11 -0
- package/dist/web/server/routes/branches.d.ts.map +1 -0
- package/dist/web/server/routes/branches.js +97 -0
- package/dist/web/server/routes/branches.js.map +1 -0
- package/dist/web/server/routes/config.d.ts +6 -0
- package/dist/web/server/routes/config.d.ts.map +1 -0
- package/dist/web/server/routes/config.js +162 -0
- package/dist/web/server/routes/config.js.map +1 -0
- package/dist/web/server/routes/index.d.ts +13 -0
- package/dist/web/server/routes/index.d.ts.map +1 -0
- package/dist/web/server/routes/index.js +29 -0
- package/dist/web/server/routes/index.js.map +1 -0
- package/dist/web/server/routes/sessions.d.ts +12 -0
- package/dist/web/server/routes/sessions.d.ts.map +1 -0
- package/dist/web/server/routes/sessions.js +95 -0
- package/dist/web/server/routes/sessions.js.map +1 -0
- package/dist/web/server/routes/worktrees.d.ts +11 -0
- package/dist/web/server/routes/worktrees.d.ts.map +1 -0
- package/dist/web/server/routes/worktrees.js +80 -0
- package/dist/web/server/routes/worktrees.js.map +1 -0
- package/dist/web/server/services/branches.d.ts +17 -0
- package/dist/web/server/services/branches.d.ts.map +1 -0
- package/dist/web/server/services/branches.js +262 -0
- package/dist/web/server/services/branches.js.map +1 -0
- package/dist/web/server/services/worktrees.d.ts +24 -0
- package/dist/web/server/services/worktrees.d.ts.map +1 -0
- package/dist/web/server/services/worktrees.js +60 -0
- package/dist/web/server/services/worktrees.js.map +1 -0
- package/dist/web/server/websocket/handler.d.ts +41 -0
- package/dist/web/server/websocket/handler.d.ts.map +1 -0
- package/dist/web/server/websocket/handler.js +143 -0
- package/dist/web/server/websocket/handler.js.map +1 -0
- package/dist/worktree.d.ts +53 -0
- package/dist/worktree.d.ts.map +1 -0
- package/dist/worktree.js +489 -0
- package/dist/worktree.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code conversation session information
|
|
3
|
+
*/
|
|
4
|
+
export interface ClaudeConversation {
|
|
5
|
+
id: string;
|
|
6
|
+
sessionId?: string;
|
|
7
|
+
title: string;
|
|
8
|
+
lastActivity: number;
|
|
9
|
+
messageCount: number;
|
|
10
|
+
projectPath: string;
|
|
11
|
+
filePath: string;
|
|
12
|
+
summary?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Message structure for conversation details
|
|
16
|
+
*/
|
|
17
|
+
export interface ClaudeMessage {
|
|
18
|
+
role: "user" | "assistant";
|
|
19
|
+
content: string | Array<{
|
|
20
|
+
text: string;
|
|
21
|
+
type?: string;
|
|
22
|
+
}>;
|
|
23
|
+
timestamp?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Detailed conversation with full message history
|
|
27
|
+
*/
|
|
28
|
+
export interface DetailedClaudeConversation extends ClaudeConversation {
|
|
29
|
+
messages: ClaudeMessage[];
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Claude Code history manager error
|
|
33
|
+
*/
|
|
34
|
+
export declare class ClaudeHistoryError extends Error {
|
|
35
|
+
cause?: unknown | undefined;
|
|
36
|
+
constructor(message: string, cause?: unknown | undefined);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if Claude Code is configured on this system
|
|
40
|
+
*/
|
|
41
|
+
export declare function isClaudeHistoryAvailable(): Promise<boolean>;
|
|
42
|
+
/**
|
|
43
|
+
* Get detailed conversation with all messages
|
|
44
|
+
*/
|
|
45
|
+
export declare function getDetailedConversation(conversation: ClaudeConversation): Promise<DetailedClaudeConversation | null>;
|
|
46
|
+
/**
|
|
47
|
+
* Get all Claude Code conversations
|
|
48
|
+
*/
|
|
49
|
+
export declare function getAllClaudeConversations(): Promise<ClaudeConversation[]>;
|
|
50
|
+
/**
|
|
51
|
+
* Get conversations filtered by project/worktree path
|
|
52
|
+
*/
|
|
53
|
+
export declare function getConversationsForProject(worktreePath: string): Promise<ClaudeConversation[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Launch Claude Code with a specific conversation
|
|
56
|
+
*/
|
|
57
|
+
export declare function launchClaudeWithConversation(worktreePath: string, conversation: ClaudeConversation, options?: {
|
|
58
|
+
skipPermissions?: boolean;
|
|
59
|
+
}): Promise<void>;
|
|
60
|
+
//# sourceMappingURL=claude-history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-history.d.ts","sourceRoot":"","sources":["../src/claude-history.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,0BAA2B,SAAQ,kBAAkB;IACpE,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAGlC,KAAK,CAAC,EAAE,OAAO;gBADtB,OAAO,EAAE,MAAM,EACR,KAAK,CAAC,EAAE,OAAO,YAAA;CAKzB;AAgBD;;GAEG;AACH,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAQjE;AAyVD;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,YAAY,EAAE,kBAAkB,GAC/B,OAAO,CAAC,0BAA0B,GAAG,IAAI,CAAC,CAyI5C;AA0DD;;GAEG;AACH,wBAAsB,yBAAyB,IAAI,OAAO,CACxD,kBAAkB,EAAE,CACrB,CAwBA;AAgCD;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAc/B;AAED;;GAEG;AACH,wBAAsB,4BAA4B,CAChD,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,kBAAkB,EAChC,OAAO,GAAE;IAAE,eAAe,CAAC,EAAE,OAAO,CAAA;CAAO,GAC1C,OAAO,CAAC,IAAI,CAAC,CAUf"}
|
|
@@ -0,0 +1,606 @@
|
|
|
1
|
+
import { homedir } from "node:os";
|
|
2
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Claude Code history manager error
|
|
6
|
+
*/
|
|
7
|
+
export class ClaudeHistoryError extends Error {
|
|
8
|
+
cause;
|
|
9
|
+
constructor(message, cause) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.cause = cause;
|
|
12
|
+
this.name = "ClaudeHistoryError";
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get Claude Code configuration directory
|
|
17
|
+
*/
|
|
18
|
+
function getClaudeConfigDir() {
|
|
19
|
+
return path.join(homedir(), ".claude");
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Get Claude Code projects directory
|
|
23
|
+
*/
|
|
24
|
+
function getClaudeProjectsDir() {
|
|
25
|
+
return path.join(getClaudeConfigDir(), "projects");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if Claude Code is configured on this system
|
|
29
|
+
*/
|
|
30
|
+
export async function isClaudeHistoryAvailable() {
|
|
31
|
+
try {
|
|
32
|
+
const projectsDir = getClaudeProjectsDir();
|
|
33
|
+
const stats = await stat(projectsDir);
|
|
34
|
+
return stats.isDirectory();
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Parse a JSONL conversation file
|
|
42
|
+
*/
|
|
43
|
+
async function parseConversationFile(filePath) {
|
|
44
|
+
try {
|
|
45
|
+
const content = await readFile(filePath, "utf-8");
|
|
46
|
+
const lines = content
|
|
47
|
+
.trim()
|
|
48
|
+
.split("\n")
|
|
49
|
+
.filter((line) => line.trim());
|
|
50
|
+
if (lines.length === 0) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
// Parse messages to extract information
|
|
54
|
+
const messages = lines
|
|
55
|
+
.map((line) => {
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(line);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
})
|
|
63
|
+
.filter(Boolean);
|
|
64
|
+
if (messages.length === 0) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
// Extract conversation metadata
|
|
68
|
+
const firstMessage = messages[0];
|
|
69
|
+
const lastMessage = messages[messages.length - 1];
|
|
70
|
+
// Extract session ID from messages (look for session_id, id, or conversation_id fields)
|
|
71
|
+
let sessionId;
|
|
72
|
+
for (const message of messages) {
|
|
73
|
+
if (message.session_id) {
|
|
74
|
+
sessionId = message.session_id;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
else if (message.conversation_id) {
|
|
78
|
+
sessionId = message.conversation_id;
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
else if (message.id &&
|
|
82
|
+
typeof message.id === "string" &&
|
|
83
|
+
message.id.length > 10) {
|
|
84
|
+
// If ID looks like a session ID (longer string), use it
|
|
85
|
+
sessionId = message.id;
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
// If no session ID found in messages, try to extract from filename
|
|
90
|
+
if (!sessionId) {
|
|
91
|
+
const fileName = path.basename(filePath, ".jsonl");
|
|
92
|
+
// Look for UUID-like patterns in filename
|
|
93
|
+
const uuidMatch = fileName.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/i);
|
|
94
|
+
if (uuidMatch) {
|
|
95
|
+
sessionId = uuidMatch[1];
|
|
96
|
+
}
|
|
97
|
+
else if (fileName.length > 20) {
|
|
98
|
+
// Use filename as session ID if it's long enough
|
|
99
|
+
sessionId = fileName;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Generate conversation title from first user message or file name
|
|
103
|
+
let title = "Untitled Conversation";
|
|
104
|
+
// Debug: Log raw messages for investigation
|
|
105
|
+
if (process.env.DEBUG_CLAUDE_HISTORY || process.env.CLAUDE_WORKTREE_DEBUG) {
|
|
106
|
+
console.log(`
|
|
107
|
+
[DEBUG] ===== Processing file: ${filePath} =====`);
|
|
108
|
+
console.log(`[DEBUG] File basename: ${path.basename(filePath, ".jsonl")}`);
|
|
109
|
+
console.log(`[DEBUG] Message count: ${messages.length}`);
|
|
110
|
+
// Log first 3 messages in detail
|
|
111
|
+
console.log(`[DEBUG] First 3 messages:`);
|
|
112
|
+
messages.slice(0, 3).forEach((msg, idx) => {
|
|
113
|
+
console.log(`[DEBUG] Message ${idx + 1}:`);
|
|
114
|
+
console.log(` - Type: ${typeof msg}`);
|
|
115
|
+
console.log(` - Keys: ${Object.keys(msg).join(", ")}`);
|
|
116
|
+
console.log(` - Role: ${msg.role || "undefined"}`);
|
|
117
|
+
console.log(` - Content type: ${typeof msg.content}`);
|
|
118
|
+
if (msg.content) {
|
|
119
|
+
if (typeof msg.content === "string") {
|
|
120
|
+
console.log(` - Content preview: ${msg.content.substring(0, 100)}...`);
|
|
121
|
+
}
|
|
122
|
+
else if (Array.isArray(msg.content)) {
|
|
123
|
+
console.log(` - Content is array with ${msg.content.length} items`);
|
|
124
|
+
if (msg.content[0]) {
|
|
125
|
+
console.log(` - First item type: ${typeof msg.content[0]}`);
|
|
126
|
+
console.log(` - First item keys: ${typeof msg.content[0] === "object" ? Object.keys(msg.content[0]).join(", ") : "N/A"}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
console.log(` - Content is object with keys: ${Object.keys(msg.content).join(", ")}`);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
console.log("");
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
// Find last user message - Claude Code uses different message structure
|
|
137
|
+
const lastUserMessage = messages
|
|
138
|
+
.slice()
|
|
139
|
+
.reverse()
|
|
140
|
+
.find((msg) =>
|
|
141
|
+
// Claude Code format: type='message' + userType='user'
|
|
142
|
+
(msg.type === "message" && msg.userType === "user") ||
|
|
143
|
+
// Nested format: type='user' with message.role='user'
|
|
144
|
+
(msg.type === "user" && msg.message && msg.message.role === "user") ||
|
|
145
|
+
// Legacy format
|
|
146
|
+
msg.role === "user" ||
|
|
147
|
+
msg.role === "human" ||
|
|
148
|
+
(msg.sender && msg.sender === "human") ||
|
|
149
|
+
(!msg.role && msg.content));
|
|
150
|
+
if (lastUserMessage) {
|
|
151
|
+
let extractedContent = "";
|
|
152
|
+
// Extract content based on Claude Code's actual structure
|
|
153
|
+
let messageContent = null;
|
|
154
|
+
// For Claude Code format: msg.message.content
|
|
155
|
+
if (lastUserMessage.message && lastUserMessage.message.content) {
|
|
156
|
+
messageContent = lastUserMessage.message.content;
|
|
157
|
+
}
|
|
158
|
+
// For direct message field (string)
|
|
159
|
+
else if (lastUserMessage.message &&
|
|
160
|
+
typeof lastUserMessage.message === "string") {
|
|
161
|
+
messageContent = lastUserMessage.message;
|
|
162
|
+
}
|
|
163
|
+
// For legacy content field
|
|
164
|
+
else if (lastUserMessage.content) {
|
|
165
|
+
messageContent = lastUserMessage.content;
|
|
166
|
+
}
|
|
167
|
+
// Handle different content formats that Claude Code might use
|
|
168
|
+
if (typeof messageContent === "string") {
|
|
169
|
+
extractedContent = messageContent;
|
|
170
|
+
}
|
|
171
|
+
else if (Array.isArray(messageContent)) {
|
|
172
|
+
// Handle array of content blocks
|
|
173
|
+
for (const block of messageContent) {
|
|
174
|
+
if (typeof block === "string") {
|
|
175
|
+
extractedContent = block;
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
else if (block && typeof block === "object") {
|
|
179
|
+
// Handle content blocks with type and text properties
|
|
180
|
+
if (block.text && typeof block.text === "string") {
|
|
181
|
+
extractedContent = block.text;
|
|
182
|
+
break;
|
|
183
|
+
}
|
|
184
|
+
else if (block.content && typeof block.content === "string") {
|
|
185
|
+
extractedContent = block.content;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
else if (messageContent && typeof messageContent === "object") {
|
|
192
|
+
// Handle single content object
|
|
193
|
+
if (messageContent.text) {
|
|
194
|
+
extractedContent = messageContent.text;
|
|
195
|
+
}
|
|
196
|
+
else if (messageContent.content) {
|
|
197
|
+
extractedContent = messageContent.content;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
// Clean and format the extracted content
|
|
201
|
+
if (extractedContent) {
|
|
202
|
+
// Remove system prompts or meta information
|
|
203
|
+
const cleanContent = extractedContent
|
|
204
|
+
.replace(/^(<.*?>|System:|Assistant:|Human:|User:)/i, "")
|
|
205
|
+
.replace(/<\/[^>]+>/g, "") // Remove closing tags like </local-command-stdout>
|
|
206
|
+
.replace(/^(Result of calling|Error:|Warning:|DEBUG:|LOG:)/i, "") // Remove system messages
|
|
207
|
+
.replace(/^(Tool executed|Command executed|Output:)/i, "") // Remove tool output indicators
|
|
208
|
+
.replace(/^\s*[-#*•]\s*/gm, "") // Remove list markers
|
|
209
|
+
.replace(/^https?:\/\/[^\s]+$/gm, "") // Remove standalone URLs
|
|
210
|
+
.trim();
|
|
211
|
+
// Extract first meaningful line
|
|
212
|
+
const firstLine = cleanContent.split("\n")[0]?.trim() || "";
|
|
213
|
+
// Validate that the content is meaningful
|
|
214
|
+
if (firstLine.length > 5 &&
|
|
215
|
+
!firstLine.match(/^(no content|undefined|null|\(no content\))$/i) &&
|
|
216
|
+
!firstLine.includes("</") && // Avoid HTML-like content
|
|
217
|
+
!firstLine.match(/^[^a-zA-Z]*$/) // Must contain some letters
|
|
218
|
+
) {
|
|
219
|
+
title =
|
|
220
|
+
firstLine.length > 60
|
|
221
|
+
? firstLine.substring(0, 57) + "..."
|
|
222
|
+
: firstLine;
|
|
223
|
+
}
|
|
224
|
+
// Debug: Log title extraction
|
|
225
|
+
if (process.env.DEBUG_CLAUDE_HISTORY) {
|
|
226
|
+
console.log(`[DEBUG] Extracted title: "${title}" from content: "${extractedContent.substring(0, 100)}..."`);
|
|
227
|
+
console.log(`[DEBUG] lastUserMessage structure:`, JSON.stringify(lastUserMessage, null, 2).substring(0, 500));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// If still no good title, try alternative extraction methods
|
|
232
|
+
if (!title || title === "Untitled Conversation") {
|
|
233
|
+
// Try to extract from filename patterns
|
|
234
|
+
const fileName = path.basename(filePath, ".jsonl");
|
|
235
|
+
// Remove timestamp patterns and use remaining text
|
|
236
|
+
const cleanFileName = fileName.replace(/^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}_/, "");
|
|
237
|
+
if (cleanFileName &&
|
|
238
|
+
cleanFileName.length > 0 &&
|
|
239
|
+
!cleanFileName.match(/^[0-9a-f-]+$/i)) {
|
|
240
|
+
// Only use filename if it's not just a UUID
|
|
241
|
+
title = cleanFileName.replace(/[-_]/g, " ").trim();
|
|
242
|
+
title = title.charAt(0).toUpperCase() + title.slice(1);
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
// Fallback: try to extract from any message content
|
|
246
|
+
let foundTitle = false;
|
|
247
|
+
// Try last messages first - more relevant for current context
|
|
248
|
+
for (const msg of messages.slice(-10).reverse()) {
|
|
249
|
+
// Check last 10 messages in reverse order
|
|
250
|
+
if (msg && msg.content) {
|
|
251
|
+
let content = "";
|
|
252
|
+
// Extract content regardless of format
|
|
253
|
+
if (typeof msg.content === "string") {
|
|
254
|
+
content = msg.content;
|
|
255
|
+
}
|
|
256
|
+
else if (Array.isArray(msg.content)) {
|
|
257
|
+
for (const item of msg.content) {
|
|
258
|
+
if (typeof item === "string") {
|
|
259
|
+
content = item;
|
|
260
|
+
break;
|
|
261
|
+
}
|
|
262
|
+
else if (item && typeof item === "object") {
|
|
263
|
+
content =
|
|
264
|
+
item.text ||
|
|
265
|
+
item.content ||
|
|
266
|
+
JSON.stringify(item).substring(0, 100);
|
|
267
|
+
if (content)
|
|
268
|
+
break;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
else if (typeof msg.content === "object") {
|
|
273
|
+
content =
|
|
274
|
+
msg.content.text ||
|
|
275
|
+
msg.content.content ||
|
|
276
|
+
JSON.stringify(msg.content).substring(0, 100);
|
|
277
|
+
}
|
|
278
|
+
// Clean and extract meaningful text
|
|
279
|
+
if (content && content.length > 10) {
|
|
280
|
+
// Remove common prefixes and clean up
|
|
281
|
+
const cleaned = content
|
|
282
|
+
.replace(/^(Human:|Assistant:|User:|System:|<.*?>|\[.*?\])/gi, "")
|
|
283
|
+
.replace(/^\s*[-#*•]\s*/gm, "") // Remove list markers
|
|
284
|
+
.trim();
|
|
285
|
+
if (cleaned.length > 10) {
|
|
286
|
+
// Get first sentence or line
|
|
287
|
+
const firstSentence = cleaned.match(/^[^.!?\n]{10,60}/)?.[0] ||
|
|
288
|
+
cleaned.substring(0, 50);
|
|
289
|
+
if (firstSentence && firstSentence.length > 10) {
|
|
290
|
+
title =
|
|
291
|
+
firstSentence.trim() +
|
|
292
|
+
(firstSentence.length === 50 ? "..." : "");
|
|
293
|
+
foundTitle = true;
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// If still no title, use generic title
|
|
301
|
+
if (!foundTitle) {
|
|
302
|
+
// We'll use the file stats later for the date
|
|
303
|
+
title = `Conversation (${messages.length} messages)`;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
// Get file stats for last activity time
|
|
308
|
+
const stats = await stat(filePath);
|
|
309
|
+
// Extract project path from file path
|
|
310
|
+
const projectsDir = getClaudeProjectsDir();
|
|
311
|
+
const relativePath = path.relative(projectsDir, filePath);
|
|
312
|
+
const projectPath = path.dirname(relativePath);
|
|
313
|
+
const result = {
|
|
314
|
+
id: path.basename(filePath, ".jsonl"),
|
|
315
|
+
title: title,
|
|
316
|
+
lastActivity: stats.mtime.getTime(),
|
|
317
|
+
messageCount: messages.length,
|
|
318
|
+
projectPath: projectPath === "." ? "root" : projectPath,
|
|
319
|
+
filePath: filePath,
|
|
320
|
+
summary: generateSummary(messages),
|
|
321
|
+
};
|
|
322
|
+
// Only add sessionId if it exists
|
|
323
|
+
if (sessionId) {
|
|
324
|
+
result.sessionId = sessionId;
|
|
325
|
+
}
|
|
326
|
+
return result;
|
|
327
|
+
}
|
|
328
|
+
catch (error) {
|
|
329
|
+
console.error(`Failed to parse conversation file ${filePath}:`, error);
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Get detailed conversation with all messages
|
|
335
|
+
*/
|
|
336
|
+
export async function getDetailedConversation(conversation) {
|
|
337
|
+
try {
|
|
338
|
+
const content = await readFile(conversation.filePath, "utf-8");
|
|
339
|
+
const lines = content
|
|
340
|
+
.trim()
|
|
341
|
+
.split("\n")
|
|
342
|
+
.filter((line) => line.trim());
|
|
343
|
+
if (lines.length === 0) {
|
|
344
|
+
return null;
|
|
345
|
+
}
|
|
346
|
+
// Parse all messages
|
|
347
|
+
const messages = lines
|
|
348
|
+
.map((line) => {
|
|
349
|
+
try {
|
|
350
|
+
const parsed = JSON.parse(line);
|
|
351
|
+
// Extract role and content based on Claude Code's actual structure
|
|
352
|
+
let role = "user";
|
|
353
|
+
let content = "";
|
|
354
|
+
// Determine role based on Claude Code's structure
|
|
355
|
+
if (parsed.type === "message" && parsed.userType === "user") {
|
|
356
|
+
role = "user";
|
|
357
|
+
}
|
|
358
|
+
else if (parsed.type === "user") {
|
|
359
|
+
role = "user";
|
|
360
|
+
}
|
|
361
|
+
else if (parsed.type === "assistant") {
|
|
362
|
+
role = "assistant";
|
|
363
|
+
}
|
|
364
|
+
else if (parsed.message && parsed.message.role === "user") {
|
|
365
|
+
role = "user";
|
|
366
|
+
}
|
|
367
|
+
else if (parsed.message && parsed.message.role === "assistant") {
|
|
368
|
+
role = "assistant";
|
|
369
|
+
}
|
|
370
|
+
else if (parsed.role === "user" || parsed.role === "human") {
|
|
371
|
+
role = "user";
|
|
372
|
+
}
|
|
373
|
+
else if (parsed.role === "assistant") {
|
|
374
|
+
role = "assistant";
|
|
375
|
+
}
|
|
376
|
+
else {
|
|
377
|
+
// Default based on message structure
|
|
378
|
+
role = "assistant";
|
|
379
|
+
}
|
|
380
|
+
// Extract content based on Claude Code's structure
|
|
381
|
+
if (parsed.message && parsed.message.content) {
|
|
382
|
+
// For Claude Code format: msg.message.content
|
|
383
|
+
const messageContent = parsed.message.content;
|
|
384
|
+
if (typeof messageContent === "string") {
|
|
385
|
+
content = messageContent;
|
|
386
|
+
}
|
|
387
|
+
else if (Array.isArray(messageContent)) {
|
|
388
|
+
// Handle array of content blocks
|
|
389
|
+
for (const block of messageContent) {
|
|
390
|
+
if (typeof block === "string") {
|
|
391
|
+
content = block;
|
|
392
|
+
break;
|
|
393
|
+
}
|
|
394
|
+
else if (block && typeof block === "object") {
|
|
395
|
+
// Claude Code format: {type: "text", text: "..."}
|
|
396
|
+
if (block.type === "text" &&
|
|
397
|
+
block.text &&
|
|
398
|
+
typeof block.text === "string") {
|
|
399
|
+
content = block.text;
|
|
400
|
+
break;
|
|
401
|
+
}
|
|
402
|
+
else if (block.type === "tool_use" && block.name) {
|
|
403
|
+
// Display tool usage
|
|
404
|
+
content = `🔧 Used tool: ${block.name}`;
|
|
405
|
+
break;
|
|
406
|
+
}
|
|
407
|
+
else if (block.text && typeof block.text === "string") {
|
|
408
|
+
content = block.text;
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
else if (block.content &&
|
|
412
|
+
typeof block.content === "string") {
|
|
413
|
+
content = block.content;
|
|
414
|
+
break;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
else if (parsed.message && typeof parsed.message === "string") {
|
|
421
|
+
// For direct message field (string)
|
|
422
|
+
content = parsed.message;
|
|
423
|
+
}
|
|
424
|
+
else if (parsed.content) {
|
|
425
|
+
// For legacy content field
|
|
426
|
+
if (typeof parsed.content === "string") {
|
|
427
|
+
content = parsed.content;
|
|
428
|
+
}
|
|
429
|
+
else if (Array.isArray(parsed.content)) {
|
|
430
|
+
for (const block of parsed.content) {
|
|
431
|
+
if (typeof block === "string") {
|
|
432
|
+
content = block;
|
|
433
|
+
break;
|
|
434
|
+
}
|
|
435
|
+
else if (block && typeof block === "object") {
|
|
436
|
+
// Claude Code format: {type: "text", text: "..."}
|
|
437
|
+
if (block.type === "text" &&
|
|
438
|
+
block.text &&
|
|
439
|
+
typeof block.text === "string") {
|
|
440
|
+
content = block.text;
|
|
441
|
+
break;
|
|
442
|
+
}
|
|
443
|
+
else if (block.type === "tool_use" && block.name) {
|
|
444
|
+
// Display tool usage
|
|
445
|
+
content = `🔧 Used tool: ${block.name}`;
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
else if (block.text && typeof block.text === "string") {
|
|
449
|
+
content = block.text;
|
|
450
|
+
break;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
return {
|
|
457
|
+
role,
|
|
458
|
+
content,
|
|
459
|
+
timestamp: parsed.timestamp || Date.now(),
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
catch {
|
|
463
|
+
return null;
|
|
464
|
+
}
|
|
465
|
+
})
|
|
466
|
+
.filter(Boolean);
|
|
467
|
+
if (messages.length === 0) {
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
return {
|
|
471
|
+
...conversation,
|
|
472
|
+
messages,
|
|
473
|
+
};
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
console.error(`Failed to get detailed conversation:`, error);
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Generate a summary from conversation messages
|
|
482
|
+
*/
|
|
483
|
+
function generateSummary(messages) {
|
|
484
|
+
// Find user messages with flexible role matching
|
|
485
|
+
const userMessages = messages
|
|
486
|
+
.filter((msg) => msg.role === "user" ||
|
|
487
|
+
msg.role === "human" ||
|
|
488
|
+
(msg.sender && msg.sender === "human") ||
|
|
489
|
+
(!msg.role && msg.content))
|
|
490
|
+
.slice(0, 3);
|
|
491
|
+
const topics = userMessages
|
|
492
|
+
.map((msg) => {
|
|
493
|
+
let content = "";
|
|
494
|
+
// Handle different content formats
|
|
495
|
+
if (typeof msg.content === "string") {
|
|
496
|
+
content = msg.content;
|
|
497
|
+
}
|
|
498
|
+
else if (Array.isArray(msg.content)) {
|
|
499
|
+
// Handle array of content blocks
|
|
500
|
+
for (const block of msg.content) {
|
|
501
|
+
if (typeof block === "string") {
|
|
502
|
+
content = block;
|
|
503
|
+
break;
|
|
504
|
+
}
|
|
505
|
+
else if (block && typeof block === "object") {
|
|
506
|
+
if (block.text && typeof block.text === "string") {
|
|
507
|
+
content = block.text;
|
|
508
|
+
break;
|
|
509
|
+
}
|
|
510
|
+
else if (block.content && typeof block.content === "string") {
|
|
511
|
+
content = block.content;
|
|
512
|
+
break;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
else if (msg.content && typeof msg.content === "object") {
|
|
518
|
+
if (msg.content.text) {
|
|
519
|
+
content = msg.content.text;
|
|
520
|
+
}
|
|
521
|
+
else if (msg.content.content) {
|
|
522
|
+
content = msg.content.content;
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
const firstLine = content.split("\n")[0]?.trim() || "";
|
|
526
|
+
return firstLine.length > 30
|
|
527
|
+
? firstLine.substring(0, 27) + "..."
|
|
528
|
+
: firstLine;
|
|
529
|
+
})
|
|
530
|
+
.filter((topic) => topic.length > 0);
|
|
531
|
+
return topics.length > 0 ? topics.join(" • ") : "No summary available";
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Get all Claude Code conversations
|
|
535
|
+
*/
|
|
536
|
+
export async function getAllClaudeConversations() {
|
|
537
|
+
if (!(await isClaudeHistoryAvailable())) {
|
|
538
|
+
throw new ClaudeHistoryError("Claude Code history is not available on this system");
|
|
539
|
+
}
|
|
540
|
+
try {
|
|
541
|
+
const conversations = [];
|
|
542
|
+
const projectsDir = getClaudeProjectsDir();
|
|
543
|
+
// Recursively scan for .jsonl files
|
|
544
|
+
await scanDirectoryForConversations(projectsDir, conversations);
|
|
545
|
+
// Sort by last activity (most recent first)
|
|
546
|
+
conversations.sort((a, b) => b.lastActivity - a.lastActivity);
|
|
547
|
+
return conversations;
|
|
548
|
+
}
|
|
549
|
+
catch (error) {
|
|
550
|
+
throw new ClaudeHistoryError("Failed to scan Claude Code conversations", error);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Recursively scan directory for conversation files
|
|
555
|
+
*/
|
|
556
|
+
async function scanDirectoryForConversations(dirPath, conversations) {
|
|
557
|
+
try {
|
|
558
|
+
const entries = await readdir(dirPath, { withFileTypes: true });
|
|
559
|
+
for (const entry of entries) {
|
|
560
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
561
|
+
if (entry.isDirectory()) {
|
|
562
|
+
// Recursively scan subdirectories
|
|
563
|
+
await scanDirectoryForConversations(fullPath, conversations);
|
|
564
|
+
}
|
|
565
|
+
else if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
566
|
+
// Parse conversation file
|
|
567
|
+
const conversation = await parseConversationFile(fullPath);
|
|
568
|
+
if (conversation) {
|
|
569
|
+
conversations.push(conversation);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
catch (error) {
|
|
575
|
+
// Continue scanning even if one directory fails
|
|
576
|
+
console.error(`Failed to scan directory ${dirPath}:`, error);
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Get conversations filtered by project/worktree path
|
|
581
|
+
*/
|
|
582
|
+
export async function getConversationsForProject(worktreePath) {
|
|
583
|
+
const allConversations = await getAllClaudeConversations();
|
|
584
|
+
// Extract project name from worktree path
|
|
585
|
+
const projectName = path.basename(worktreePath);
|
|
586
|
+
return allConversations.filter((conversation) => {
|
|
587
|
+
// Match by project path or conversation mentions the project
|
|
588
|
+
return (conversation.projectPath.includes(projectName) ||
|
|
589
|
+
conversation.title.toLowerCase().includes(projectName.toLowerCase()) ||
|
|
590
|
+
conversation.summary?.toLowerCase().includes(projectName.toLowerCase()));
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Launch Claude Code with a specific conversation
|
|
595
|
+
*/
|
|
596
|
+
export async function launchClaudeWithConversation(worktreePath, conversation, options = {}) {
|
|
597
|
+
const { launchClaudeCode } = await import("./claude.js");
|
|
598
|
+
// Launch Claude Code in the worktree with the conversation file
|
|
599
|
+
// Note: This might need adjustment based on how Claude Code handles specific conversation files
|
|
600
|
+
// For now, we'll use the standard launch and let Claude Code handle the session
|
|
601
|
+
await launchClaudeCode(worktreePath, {
|
|
602
|
+
mode: "resume",
|
|
603
|
+
skipPermissions: options.skipPermissions ?? false,
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
//# sourceMappingURL=claude-history.js.map
|