@jacques-ai/server 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/config/config.d.ts +34 -0
- package/dist/config/config.d.ts.map +1 -0
- package/dist/config/config.js +32 -0
- package/dist/config/config.js.map +1 -0
- package/dist/connection/applescript.d.ts +46 -0
- package/dist/connection/applescript.d.ts.map +1 -0
- package/dist/connection/applescript.js +62 -0
- package/dist/connection/applescript.js.map +1 -0
- package/dist/connection/applescript.test.d.ts +5 -0
- package/dist/connection/applescript.test.d.ts.map +1 -0
- package/dist/connection/applescript.test.js +64 -0
- package/dist/connection/applescript.test.js.map +1 -0
- package/dist/connection/constants.d.ts +88 -0
- package/dist/connection/constants.d.ts.map +1 -0
- package/dist/connection/constants.js +110 -0
- package/dist/connection/constants.js.map +1 -0
- package/dist/connection/git-info.d.ts +30 -0
- package/dist/connection/git-info.d.ts.map +1 -0
- package/dist/connection/git-info.js +52 -0
- package/dist/connection/git-info.js.map +1 -0
- package/dist/connection/git-info.test.d.ts +5 -0
- package/dist/connection/git-info.test.d.ts.map +1 -0
- package/dist/connection/git-info.test.js +35 -0
- package/dist/connection/git-info.test.js.map +1 -0
- package/dist/connection/index.d.ts +19 -0
- package/dist/connection/index.d.ts.map +1 -0
- package/dist/connection/index.js +36 -0
- package/dist/connection/index.js.map +1 -0
- package/dist/connection/process-detection.d.ts +58 -0
- package/dist/connection/process-detection.d.ts.map +1 -0
- package/dist/connection/process-detection.js +239 -0
- package/dist/connection/process-detection.js.map +1 -0
- package/dist/connection/process-detection.test.d.ts +5 -0
- package/dist/connection/process-detection.test.d.ts.map +1 -0
- package/dist/connection/process-detection.test.js +43 -0
- package/dist/connection/process-detection.test.js.map +1 -0
- package/dist/connection/session-discovery.d.ts +55 -0
- package/dist/connection/session-discovery.d.ts.map +1 -0
- package/dist/connection/session-discovery.js +311 -0
- package/dist/connection/session-discovery.js.map +1 -0
- package/dist/connection/terminal-key.d.ts +126 -0
- package/dist/connection/terminal-key.d.ts.map +1 -0
- package/dist/connection/terminal-key.js +271 -0
- package/dist/connection/terminal-key.js.map +1 -0
- package/dist/connection/terminal-key.test.d.ts +5 -0
- package/dist/connection/terminal-key.test.d.ts.map +1 -0
- package/dist/connection/terminal-key.test.js +221 -0
- package/dist/connection/terminal-key.test.js.map +1 -0
- package/dist/connection/worktree.d.ts +114 -0
- package/dist/connection/worktree.d.ts.map +1 -0
- package/dist/connection/worktree.js +320 -0
- package/dist/connection/worktree.js.map +1 -0
- package/dist/connection/worktree.test.d.ts +5 -0
- package/dist/connection/worktree.test.d.ts.map +1 -0
- package/dist/connection/worktree.test.js +113 -0
- package/dist/connection/worktree.test.js.map +1 -0
- package/dist/focus-watcher.d.ts +51 -0
- package/dist/focus-watcher.d.ts.map +1 -0
- package/dist/focus-watcher.js +169 -0
- package/dist/focus-watcher.js.map +1 -0
- package/dist/handlers/event-handler.d.ts +93 -0
- package/dist/handlers/event-handler.d.ts.map +1 -0
- package/dist/handlers/event-handler.js +196 -0
- package/dist/handlers/event-handler.js.map +1 -0
- package/dist/handlers/event-handler.test.d.ts +5 -0
- package/dist/handlers/event-handler.test.d.ts.map +1 -0
- package/dist/handlers/event-handler.test.js +305 -0
- package/dist/handlers/event-handler.test.js.map +1 -0
- package/dist/handlers/session-handler.d.ts +23 -0
- package/dist/handlers/session-handler.d.ts.map +1 -0
- package/dist/handlers/session-handler.js +104 -0
- package/dist/handlers/session-handler.js.map +1 -0
- package/dist/handlers/session-handler.test.d.ts +5 -0
- package/dist/handlers/session-handler.test.d.ts.map +1 -0
- package/dist/handlers/session-handler.test.js +89 -0
- package/dist/handlers/session-handler.test.js.map +1 -0
- package/dist/handlers/settings-handler.d.ts +32 -0
- package/dist/handlers/settings-handler.d.ts.map +1 -0
- package/dist/handlers/settings-handler.js +127 -0
- package/dist/handlers/settings-handler.js.map +1 -0
- package/dist/handlers/settings-handler.test.d.ts +5 -0
- package/dist/handlers/settings-handler.test.d.ts.map +1 -0
- package/dist/handlers/settings-handler.test.js +105 -0
- package/dist/handlers/settings-handler.test.js.map +1 -0
- package/dist/handlers/window-handler.d.ts +30 -0
- package/dist/handlers/window-handler.d.ts.map +1 -0
- package/dist/handlers/window-handler.js +486 -0
- package/dist/handlers/window-handler.js.map +1 -0
- package/dist/handlers/window-handler.test.d.ts +8 -0
- package/dist/handlers/window-handler.test.d.ts.map +1 -0
- package/dist/handlers/window-handler.test.js +167 -0
- package/dist/handlers/window-handler.test.js.map +1 -0
- package/dist/handlers/worktree-handler.d.ts +28 -0
- package/dist/handlers/worktree-handler.d.ts.map +1 -0
- package/dist/handlers/worktree-handler.js +268 -0
- package/dist/handlers/worktree-handler.js.map +1 -0
- package/dist/handlers/worktree-handler.test.d.ts +8 -0
- package/dist/handlers/worktree-handler.test.d.ts.map +1 -0
- package/dist/handlers/worktree-handler.test.js +118 -0
- package/dist/handlers/worktree-handler.test.js.map +1 -0
- package/dist/handlers/ws-utils.d.ts +12 -0
- package/dist/handlers/ws-utils.d.ts.map +1 -0
- package/dist/handlers/ws-utils.js +16 -0
- package/dist/handlers/ws-utils.js.map +1 -0
- package/dist/http-api.d.ts +26 -0
- package/dist/http-api.d.ts.map +1 -0
- package/dist/http-api.js +148 -0
- package/dist/http-api.js.map +1 -0
- package/dist/logger.d.ts +42 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +147 -0
- package/dist/logger.js.map +1 -0
- package/dist/logging/logger-factory.d.ts +51 -0
- package/dist/logging/logger-factory.d.ts.map +1 -0
- package/dist/logging/logger-factory.js +59 -0
- package/dist/logging/logger-factory.js.map +1 -0
- package/dist/mcp/search-tool.d.ts +65 -0
- package/dist/mcp/search-tool.d.ts.map +1 -0
- package/dist/mcp/search-tool.js +176 -0
- package/dist/mcp/search-tool.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +152 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/process-scanner.d.ts +96 -0
- package/dist/process-scanner.d.ts.map +1 -0
- package/dist/process-scanner.js +194 -0
- package/dist/process-scanner.js.map +1 -0
- package/dist/routes/__tests__/archive-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/archive-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/archive-routes.test.js +158 -0
- package/dist/routes/__tests__/archive-routes.test.js.map +1 -0
- package/dist/routes/__tests__/config-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/config-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/config-routes.test.js +112 -0
- package/dist/routes/__tests__/config-routes.test.js.map +1 -0
- package/dist/routes/__tests__/http-utils.test.d.ts +5 -0
- package/dist/routes/__tests__/http-utils.test.d.ts.map +1 -0
- package/dist/routes/__tests__/http-utils.test.js +102 -0
- package/dist/routes/__tests__/http-utils.test.js.map +1 -0
- package/dist/routes/__tests__/notification-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/notification-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/notification-routes.test.js +91 -0
- package/dist/routes/__tests__/notification-routes.test.js.map +1 -0
- package/dist/routes/__tests__/project-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/project-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/project-routes.test.js +168 -0
- package/dist/routes/__tests__/project-routes.test.js.map +1 -0
- package/dist/routes/__tests__/session-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/session-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/session-routes.test.js +198 -0
- package/dist/routes/__tests__/session-routes.test.js.map +1 -0
- package/dist/routes/__tests__/source-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/source-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/source-routes.test.js +142 -0
- package/dist/routes/__tests__/source-routes.test.js.map +1 -0
- package/dist/routes/__tests__/sync-routes.test.d.ts +5 -0
- package/dist/routes/__tests__/sync-routes.test.d.ts.map +1 -0
- package/dist/routes/__tests__/sync-routes.test.js +77 -0
- package/dist/routes/__tests__/sync-routes.test.js.map +1 -0
- package/dist/routes/__tests__/test-helpers.d.ts +47 -0
- package/dist/routes/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/routes/__tests__/test-helpers.js +97 -0
- package/dist/routes/__tests__/test-helpers.js.map +1 -0
- package/dist/routes/archive-routes.d.ts +15 -0
- package/dist/routes/archive-routes.d.ts.map +1 -0
- package/dist/routes/archive-routes.js +181 -0
- package/dist/routes/archive-routes.js.map +1 -0
- package/dist/routes/claude-routes.d.ts +9 -0
- package/dist/routes/claude-routes.d.ts.map +1 -0
- package/dist/routes/claude-routes.js +47 -0
- package/dist/routes/claude-routes.js.map +1 -0
- package/dist/routes/config-routes.d.ts +9 -0
- package/dist/routes/config-routes.d.ts.map +1 -0
- package/dist/routes/config-routes.js +56 -0
- package/dist/routes/config-routes.js.map +1 -0
- package/dist/routes/config-store.d.ts +41 -0
- package/dist/routes/config-store.d.ts.map +1 -0
- package/dist/routes/config-store.js +52 -0
- package/dist/routes/config-store.js.map +1 -0
- package/dist/routes/http-utils.d.ts +32 -0
- package/dist/routes/http-utils.d.ts.map +1 -0
- package/dist/routes/http-utils.js +123 -0
- package/dist/routes/http-utils.js.map +1 -0
- package/dist/routes/index.d.ts +19 -0
- package/dist/routes/index.d.ts.map +1 -0
- package/dist/routes/index.js +17 -0
- package/dist/routes/index.js.map +1 -0
- package/dist/routes/notification-routes.d.ts +10 -0
- package/dist/routes/notification-routes.d.ts.map +1 -0
- package/dist/routes/notification-routes.js +64 -0
- package/dist/routes/notification-routes.js.map +1 -0
- package/dist/routes/project-routes.d.ts +22 -0
- package/dist/routes/project-routes.d.ts.map +1 -0
- package/dist/routes/project-routes.js +415 -0
- package/dist/routes/project-routes.js.map +1 -0
- package/dist/routes/session-routes.d.ts +18 -0
- package/dist/routes/session-routes.d.ts.map +1 -0
- package/dist/routes/session-routes.js +609 -0
- package/dist/routes/session-routes.js.map +1 -0
- package/dist/routes/source-routes.d.ts +12 -0
- package/dist/routes/source-routes.d.ts.map +1 -0
- package/dist/routes/source-routes.js +119 -0
- package/dist/routes/source-routes.js.map +1 -0
- package/dist/routes/static-routes.d.ts +12 -0
- package/dist/routes/static-routes.d.ts.map +1 -0
- package/dist/routes/static-routes.js +52 -0
- package/dist/routes/static-routes.js.map +1 -0
- package/dist/routes/sync-routes.d.ts +9 -0
- package/dist/routes/sync-routes.d.ts.map +1 -0
- package/dist/routes/sync-routes.js +78 -0
- package/dist/routes/sync-routes.js.map +1 -0
- package/dist/routes/tile-routes.d.ts +10 -0
- package/dist/routes/tile-routes.d.ts.map +1 -0
- package/dist/routes/tile-routes.js +108 -0
- package/dist/routes/tile-routes.js.map +1 -0
- package/dist/routes/types.d.ts +17 -0
- package/dist/routes/types.d.ts.map +1 -0
- package/dist/routes/types.js +5 -0
- package/dist/routes/types.js.map +1 -0
- package/dist/routes/usage-routes.d.ts +8 -0
- package/dist/routes/usage-routes.d.ts.map +1 -0
- package/dist/routes/usage-routes.js +18 -0
- package/dist/routes/usage-routes.js.map +1 -0
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +173 -0
- package/dist/server.js.map +1 -0
- package/dist/services/branch-divergence-service.d.ts +48 -0
- package/dist/services/branch-divergence-service.d.ts.map +1 -0
- package/dist/services/branch-divergence-service.js +156 -0
- package/dist/services/branch-divergence-service.js.map +1 -0
- package/dist/services/broadcast-service.d.ts +68 -0
- package/dist/services/broadcast-service.d.ts.map +1 -0
- package/dist/services/broadcast-service.js +78 -0
- package/dist/services/broadcast-service.js.map +1 -0
- package/dist/services/broadcast-service.test.d.ts +5 -0
- package/dist/services/broadcast-service.test.d.ts.map +1 -0
- package/dist/services/broadcast-service.test.js +130 -0
- package/dist/services/broadcast-service.test.js.map +1 -0
- package/dist/services/chat-service.d.ts +72 -0
- package/dist/services/chat-service.d.ts.map +1 -0
- package/dist/services/chat-service.js +342 -0
- package/dist/services/chat-service.js.map +1 -0
- package/dist/services/chat-system-prompt.d.ts +14 -0
- package/dist/services/chat-system-prompt.d.ts.map +1 -0
- package/dist/services/chat-system-prompt.js +68 -0
- package/dist/services/chat-system-prompt.js.map +1 -0
- package/dist/services/notification-service.d.ts +115 -0
- package/dist/services/notification-service.d.ts.map +1 -0
- package/dist/services/notification-service.js +424 -0
- package/dist/services/notification-service.js.map +1 -0
- package/dist/services/notification-service.test.d.ts +5 -0
- package/dist/services/notification-service.test.d.ts.map +1 -0
- package/dist/services/notification-service.test.js +918 -0
- package/dist/services/notification-service.test.js.map +1 -0
- package/dist/session/cleanup-service.d.ts +51 -0
- package/dist/session/cleanup-service.d.ts.map +1 -0
- package/dist/session/cleanup-service.js +98 -0
- package/dist/session/cleanup-service.js.map +1 -0
- package/dist/session/cleanup-service.test.d.ts +5 -0
- package/dist/session/cleanup-service.test.d.ts.map +1 -0
- package/dist/session/cleanup-service.test.js +121 -0
- package/dist/session/cleanup-service.test.js.map +1 -0
- package/dist/session/process-monitor.d.ts +79 -0
- package/dist/session/process-monitor.d.ts.map +1 -0
- package/dist/session/process-monitor.js +270 -0
- package/dist/session/process-monitor.js.map +1 -0
- package/dist/session/process-monitor.test.d.ts +5 -0
- package/dist/session/process-monitor.test.d.ts.map +1 -0
- package/dist/session/process-monitor.test.js +367 -0
- package/dist/session/process-monitor.test.js.map +1 -0
- package/dist/session/session-factory.d.ts +29 -0
- package/dist/session/session-factory.d.ts.map +1 -0
- package/dist/session/session-factory.js +123 -0
- package/dist/session/session-factory.js.map +1 -0
- package/dist/session/session-factory.test.d.ts +5 -0
- package/dist/session/session-factory.test.d.ts.map +1 -0
- package/dist/session/session-factory.test.js +299 -0
- package/dist/session/session-factory.test.js.map +1 -0
- package/dist/session-registry.d.ts +168 -0
- package/dist/session-registry.d.ts.map +1 -0
- package/dist/session-registry.js +626 -0
- package/dist/session-registry.js.map +1 -0
- package/dist/session-registry.test.d.ts +5 -0
- package/dist/session-registry.test.d.ts.map +1 -0
- package/dist/session-registry.test.js +582 -0
- package/dist/session-registry.test.js.map +1 -0
- package/dist/start-server.d.ts +31 -0
- package/dist/start-server.d.ts.map +1 -0
- package/dist/start-server.js +408 -0
- package/dist/start-server.js.map +1 -0
- package/dist/terminal-activator.d.ts +29 -0
- package/dist/terminal-activator.d.ts.map +1 -0
- package/dist/terminal-activator.js +264 -0
- package/dist/terminal-activator.js.map +1 -0
- package/dist/terminal-activator.test.d.ts +9 -0
- package/dist/terminal-activator.test.d.ts.map +1 -0
- package/dist/terminal-activator.test.js +95 -0
- package/dist/terminal-activator.test.js.map +1 -0
- package/dist/terminal-launcher.d.ts +51 -0
- package/dist/terminal-launcher.d.ts.map +1 -0
- package/dist/terminal-launcher.js +298 -0
- package/dist/terminal-launcher.js.map +1 -0
- package/dist/terminal-launcher.test.d.ts +8 -0
- package/dist/terminal-launcher.test.d.ts.map +1 -0
- package/dist/terminal-launcher.test.js +222 -0
- package/dist/terminal-launcher.test.js.map +1 -0
- package/dist/types.d.ts +796 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +15 -0
- package/dist/types.js.map +1 -0
- package/dist/unix-socket.d.ts +68 -0
- package/dist/unix-socket.d.ts.map +1 -0
- package/dist/unix-socket.js +180 -0
- package/dist/unix-socket.js.map +1 -0
- package/dist/usage-limits.d.ts +13 -0
- package/dist/usage-limits.d.ts.map +1 -0
- package/dist/usage-limits.js +112 -0
- package/dist/usage-limits.js.map +1 -0
- package/dist/watchers/handoff-watcher.d.ts +74 -0
- package/dist/watchers/handoff-watcher.d.ts.map +1 -0
- package/dist/watchers/handoff-watcher.js +124 -0
- package/dist/watchers/handoff-watcher.js.map +1 -0
- package/dist/watchers/handoff-watcher.test.d.ts +8 -0
- package/dist/watchers/handoff-watcher.test.d.ts.map +1 -0
- package/dist/watchers/handoff-watcher.test.js +142 -0
- package/dist/watchers/handoff-watcher.test.js.map +1 -0
- package/dist/websocket.d.ts +107 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +268 -0
- package/dist/websocket.js.map +1 -0
- package/dist/window-manager/index.d.ts +28 -0
- package/dist/window-manager/index.d.ts.map +1 -0
- package/dist/window-manager/index.js +56 -0
- package/dist/window-manager/index.js.map +1 -0
- package/dist/window-manager/layouts.d.ts +42 -0
- package/dist/window-manager/layouts.d.ts.map +1 -0
- package/dist/window-manager/layouts.js +133 -0
- package/dist/window-manager/layouts.js.map +1 -0
- package/dist/window-manager/linux-manager.d.ts +45 -0
- package/dist/window-manager/linux-manager.d.ts.map +1 -0
- package/dist/window-manager/linux-manager.js +299 -0
- package/dist/window-manager/linux-manager.js.map +1 -0
- package/dist/window-manager/macos-manager.d.ts +103 -0
- package/dist/window-manager/macos-manager.d.ts.map +1 -0
- package/dist/window-manager/macos-manager.js +637 -0
- package/dist/window-manager/macos-manager.js.map +1 -0
- package/dist/window-manager/smart-layouts.d.ts +116 -0
- package/dist/window-manager/smart-layouts.d.ts.map +1 -0
- package/dist/window-manager/smart-layouts.js +188 -0
- package/dist/window-manager/smart-layouts.js.map +1 -0
- package/dist/window-manager/smart-layouts.test.d.ts +8 -0
- package/dist/window-manager/smart-layouts.test.d.ts.map +1 -0
- package/dist/window-manager/smart-layouts.test.js +311 -0
- package/dist/window-manager/smart-layouts.test.js.map +1 -0
- package/dist/window-manager/tile-state.d.ts +87 -0
- package/dist/window-manager/tile-state.d.ts.map +1 -0
- package/dist/window-manager/tile-state.js +136 -0
- package/dist/window-manager/tile-state.js.map +1 -0
- package/dist/window-manager/tile-state.test.d.ts +8 -0
- package/dist/window-manager/tile-state.test.d.ts.map +1 -0
- package/dist/window-manager/tile-state.test.js +179 -0
- package/dist/window-manager/tile-state.test.js.map +1 -0
- package/dist/window-manager/types.d.ts +104 -0
- package/dist/window-manager/types.d.ts.map +1 -0
- package/dist/window-manager/types.js +8 -0
- package/dist/window-manager/types.js.map +1 -0
- package/dist/window-manager/windows-manager.d.ts +44 -0
- package/dist/window-manager/windows-manager.d.ts.map +1 -0
- package/dist/window-manager/windows-manager.js +281 -0
- package/dist/window-manager/windows-manager.js.map +1 -0
- package/dist/window-manager/windows-manager.test.d.ts +8 -0
- package/dist/window-manager/windows-manager.test.d.ts.map +1 -0
- package/dist/window-manager/windows-manager.test.js +183 -0
- package/dist/window-manager/windows-manager.test.js.map +1 -0
- package/gui-dist/assets/index-BmYIHRYe.js +142 -0
- package/gui-dist/assets/index-D_N5RH8O.css +1 -0
- package/gui-dist/assets/vendor-icons-ByXNrcwf.js +336 -0
- package/gui-dist/assets/vendor-markdown-DWPYwU1x.js +22 -0
- package/gui-dist/assets/vendor-react-CpILBTDM.js +59 -0
- package/gui-dist/index.html +17 -0
- package/gui-dist/jacsub.png +0 -0
- package/package.json +67 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP Search Tool
|
|
3
|
+
*
|
|
4
|
+
* Implements the search_conversations tool for the MCP server.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { promises as fs } from "fs";
|
|
8
|
+
import * as path from "path";
|
|
9
|
+
import { homedir } from "os";
|
|
10
|
+
// ============================================================
|
|
11
|
+
// Tool Schema
|
|
12
|
+
// ============================================================
|
|
13
|
+
export const searchConversationsSchema = z.object({
|
|
14
|
+
query: z.string().describe("Keywords to search for in archived conversations"),
|
|
15
|
+
project: z.string().optional().describe("Filter by project slug (e.g., 'my-project')"),
|
|
16
|
+
dateFrom: z.string().optional().describe("Filter conversations from this date (ISO format: YYYY-MM-DD)"),
|
|
17
|
+
dateTo: z.string().optional().describe("Filter conversations up to this date (ISO format: YYYY-MM-DD)"),
|
|
18
|
+
technologies: z.array(z.string()).optional().describe("Filter by technologies (e.g., ['react', 'typescript'])"),
|
|
19
|
+
limit: z.number().min(1).max(50).default(10).describe("Maximum number of results (default: 10, max: 50)"),
|
|
20
|
+
offset: z.number().min(0).default(0).describe("Pagination offset (default: 0)"),
|
|
21
|
+
});
|
|
22
|
+
// ============================================================
|
|
23
|
+
// Constants
|
|
24
|
+
// ============================================================
|
|
25
|
+
const GLOBAL_ARCHIVE_PATH = path.join(homedir(), ".jacques", "archive");
|
|
26
|
+
const STOP_WORDS = new Set([
|
|
27
|
+
"a", "an", "and", "are", "as", "at", "be", "been", "by", "for", "from",
|
|
28
|
+
"has", "he", "in", "is", "it", "its", "of", "on", "that", "the", "to",
|
|
29
|
+
"was", "will", "with", "this", "but", "they", "have", "had", "what",
|
|
30
|
+
"when", "where", "who", "which", "why", "how", "all", "would", "there",
|
|
31
|
+
"their", "or", "if", "can", "may", "could", "should", "might", "must",
|
|
32
|
+
"do", "does", "did", "done", "doing", "i", "you", "we", "them", "your",
|
|
33
|
+
"our", "my", "not", "just", "about", "here", "first", "create", "make",
|
|
34
|
+
"let", "me", "see", "also", "so", "then", "now", "new", "get", "use",
|
|
35
|
+
"want", "need", "please", "thanks", "help", "like", "know", "think", "look",
|
|
36
|
+
]);
|
|
37
|
+
// ============================================================
|
|
38
|
+
// Helper Functions
|
|
39
|
+
// ============================================================
|
|
40
|
+
function tokenize(text) {
|
|
41
|
+
return text
|
|
42
|
+
.toLowerCase()
|
|
43
|
+
.split(/\W+/)
|
|
44
|
+
.filter((w) => w.length >= 2 && w.length <= 50)
|
|
45
|
+
.filter((w) => !STOP_WORDS.has(w))
|
|
46
|
+
.filter((w) => !/^\d+$/.test(w));
|
|
47
|
+
}
|
|
48
|
+
async function readIndex() {
|
|
49
|
+
try {
|
|
50
|
+
const indexPath = path.join(GLOBAL_ARCHIVE_PATH, "index.json");
|
|
51
|
+
const content = await fs.readFile(indexPath, "utf-8");
|
|
52
|
+
return JSON.parse(content);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return {
|
|
56
|
+
version: "1.0.0",
|
|
57
|
+
lastUpdated: new Date().toISOString(),
|
|
58
|
+
keywords: {},
|
|
59
|
+
projects: {},
|
|
60
|
+
metadata: { totalConversations: 0, totalKeywords: 0 },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async function readManifest(id) {
|
|
65
|
+
try {
|
|
66
|
+
const manifestPath = path.join(GLOBAL_ARCHIVE_PATH, "manifests", `${id}.json`);
|
|
67
|
+
const content = await fs.readFile(manifestPath, "utf-8");
|
|
68
|
+
return JSON.parse(content);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function searchIndexKeywords(index, query) {
|
|
75
|
+
const queryKeywords = tokenize(query);
|
|
76
|
+
if (queryKeywords.length === 0) {
|
|
77
|
+
return [];
|
|
78
|
+
}
|
|
79
|
+
const scores = new Map();
|
|
80
|
+
for (const keyword of queryKeywords) {
|
|
81
|
+
const refs = index.keywords[keyword];
|
|
82
|
+
if (!refs)
|
|
83
|
+
continue;
|
|
84
|
+
for (const ref of refs) {
|
|
85
|
+
const currentScore = scores.get(ref.id) || 0;
|
|
86
|
+
scores.set(ref.id, currentScore + ref.score);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const results = [];
|
|
90
|
+
for (const [id, score] of scores) {
|
|
91
|
+
results.push({ id, score });
|
|
92
|
+
}
|
|
93
|
+
return results.sort((a, b) => b.score - a.score);
|
|
94
|
+
}
|
|
95
|
+
// ============================================================
|
|
96
|
+
// Main Search Function
|
|
97
|
+
// ============================================================
|
|
98
|
+
export async function searchConversations(input) {
|
|
99
|
+
const index = await readIndex();
|
|
100
|
+
// Get initial results from index
|
|
101
|
+
const indexResults = searchIndexKeywords(index, input.query);
|
|
102
|
+
// Load manifests and apply filters
|
|
103
|
+
const filteredResults = [];
|
|
104
|
+
for (const { id, score } of indexResults) {
|
|
105
|
+
const manifest = await readManifest(id);
|
|
106
|
+
if (!manifest)
|
|
107
|
+
continue;
|
|
108
|
+
// Apply filters (support both projectId and projectSlug for backward compat)
|
|
109
|
+
if (input.project && manifest.projectId !== input.project && manifest.projectSlug !== input.project) {
|
|
110
|
+
continue;
|
|
111
|
+
}
|
|
112
|
+
if (input.dateFrom && manifest.endedAt < input.dateFrom) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (input.dateTo && manifest.endedAt > input.dateTo) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (input.technologies && input.technologies.length > 0) {
|
|
119
|
+
const hasTech = input.technologies.some((t) => manifest.technologies.includes(t.toLowerCase()));
|
|
120
|
+
if (!hasTech)
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
filteredResults.push({ manifest, score });
|
|
124
|
+
}
|
|
125
|
+
// Apply pagination
|
|
126
|
+
const limit = Math.min(input.limit || 10, 50);
|
|
127
|
+
const offset = input.offset || 0;
|
|
128
|
+
const totalMatches = filteredResults.length;
|
|
129
|
+
const paginatedResults = filteredResults.slice(offset, offset + limit);
|
|
130
|
+
// Transform to SearchResult format
|
|
131
|
+
const results = paginatedResults.map(({ manifest, score }, idx) => ({
|
|
132
|
+
rank: offset + idx + 1,
|
|
133
|
+
id: manifest.id,
|
|
134
|
+
score,
|
|
135
|
+
title: manifest.title,
|
|
136
|
+
project: manifest.projectSlug,
|
|
137
|
+
date: manifest.endedAt.split("T")[0],
|
|
138
|
+
preview: manifest.userQuestions[0] || "",
|
|
139
|
+
filesModified: manifest.filesModified.slice(0, 5),
|
|
140
|
+
technologies: manifest.technologies,
|
|
141
|
+
messageCount: manifest.messageCount,
|
|
142
|
+
durationMinutes: manifest.durationMinutes,
|
|
143
|
+
}));
|
|
144
|
+
return {
|
|
145
|
+
query: input.query,
|
|
146
|
+
filters: {
|
|
147
|
+
project: input.project,
|
|
148
|
+
dateFrom: input.dateFrom,
|
|
149
|
+
dateTo: input.dateTo,
|
|
150
|
+
technologies: input.technologies,
|
|
151
|
+
},
|
|
152
|
+
totalMatches,
|
|
153
|
+
showing: {
|
|
154
|
+
from: totalMatches > 0 ? offset + 1 : 0,
|
|
155
|
+
to: Math.min(offset + limit, totalMatches),
|
|
156
|
+
},
|
|
157
|
+
hasMore: offset + limit < totalMatches,
|
|
158
|
+
results,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
// ============================================================
|
|
162
|
+
// Tool Handler
|
|
163
|
+
// ============================================================
|
|
164
|
+
export async function handleSearchConversations(args) {
|
|
165
|
+
// Parse and validate input
|
|
166
|
+
const parsed = searchConversationsSchema.safeParse(args);
|
|
167
|
+
if (!parsed.success) {
|
|
168
|
+
return JSON.stringify({
|
|
169
|
+
error: "Invalid input",
|
|
170
|
+
details: parsed.error.issues,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const result = await searchConversations(parsed.data);
|
|
174
|
+
return JSON.stringify(result, null, 2);
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=search-tool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-tool.js","sourceRoot":"","sources":["../../src/mcp/search-tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Jacques MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Provides cross-project search over archived Claude Code conversations.
|
|
6
|
+
* Communicates via stdio using the Model Context Protocol.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
+
import { searchConversationsSchema, handleSearchConversations, } from "./search-tool.js";
|
|
11
|
+
// ============================================================
|
|
12
|
+
// Server Setup
|
|
13
|
+
// ============================================================
|
|
14
|
+
const server = new McpServer({
|
|
15
|
+
name: "jacques-archive",
|
|
16
|
+
version: "0.1.0",
|
|
17
|
+
});
|
|
18
|
+
// ============================================================
|
|
19
|
+
// Tool Registration
|
|
20
|
+
// ============================================================
|
|
21
|
+
server.tool("search_conversations", "Search across all archived Claude Code conversations. Returns matching sessions with metadata including title, project, date, modified files, and technologies. Claude Code provides semantic analysis on the search results.", searchConversationsSchema.shape, async (args) => {
|
|
22
|
+
const result = await handleSearchConversations(args);
|
|
23
|
+
return {
|
|
24
|
+
content: [
|
|
25
|
+
{
|
|
26
|
+
type: "text",
|
|
27
|
+
text: result,
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
// ============================================================
|
|
33
|
+
// Resource Registration
|
|
34
|
+
// ============================================================
|
|
35
|
+
server.resource("archive-stats", "jacques://archive/stats", async () => {
|
|
36
|
+
const { promises: fs } = await import("fs");
|
|
37
|
+
const { homedir } = await import("os");
|
|
38
|
+
const path = await import("path");
|
|
39
|
+
const archivePath = path.join(homedir(), ".jacques", "archive");
|
|
40
|
+
const indexPath = path.join(archivePath, "index.json");
|
|
41
|
+
try {
|
|
42
|
+
const content = await fs.readFile(indexPath, "utf-8");
|
|
43
|
+
const index = JSON.parse(content);
|
|
44
|
+
return {
|
|
45
|
+
contents: [
|
|
46
|
+
{
|
|
47
|
+
uri: "jacques://archive/stats",
|
|
48
|
+
mimeType: "application/json",
|
|
49
|
+
text: JSON.stringify({
|
|
50
|
+
totalConversations: index.metadata.totalConversations,
|
|
51
|
+
totalKeywords: index.metadata.totalKeywords,
|
|
52
|
+
totalProjects: Object.keys(index.projects).length,
|
|
53
|
+
projects: Object.entries(index.projects).map(([slug, info]) => ({
|
|
54
|
+
slug,
|
|
55
|
+
conversationCount: info.conversationCount,
|
|
56
|
+
lastActivity: info.lastActivity,
|
|
57
|
+
})),
|
|
58
|
+
lastUpdated: index.lastUpdated,
|
|
59
|
+
}, null, 2),
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return {
|
|
66
|
+
contents: [
|
|
67
|
+
{
|
|
68
|
+
uri: "jacques://archive/stats",
|
|
69
|
+
mimeType: "application/json",
|
|
70
|
+
text: JSON.stringify({
|
|
71
|
+
totalConversations: 0,
|
|
72
|
+
totalKeywords: 0,
|
|
73
|
+
totalProjects: 0,
|
|
74
|
+
projects: [],
|
|
75
|
+
lastUpdated: null,
|
|
76
|
+
note: "Archive not initialized. Save a conversation using Jacques dashboard first.",
|
|
77
|
+
}),
|
|
78
|
+
},
|
|
79
|
+
],
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
// ============================================================
|
|
84
|
+
// Prompt Registration
|
|
85
|
+
// ============================================================
|
|
86
|
+
server.prompt("search-guide", "Guide for searching conversation archives effectively", () => {
|
|
87
|
+
return {
|
|
88
|
+
messages: [
|
|
89
|
+
{
|
|
90
|
+
role: "user",
|
|
91
|
+
content: {
|
|
92
|
+
type: "text",
|
|
93
|
+
text: `# Jacques Archive Search Guide
|
|
94
|
+
|
|
95
|
+
## How to Search
|
|
96
|
+
|
|
97
|
+
Use the \`search_conversations\` tool to find past Claude Code conversations across all projects.
|
|
98
|
+
|
|
99
|
+
## Search Tips
|
|
100
|
+
|
|
101
|
+
1. **Keywords**: Search for specific topics, technologies, or concepts
|
|
102
|
+
- "authentication JWT" finds sessions about JWT auth
|
|
103
|
+
- "react hooks" finds sessions about React hooks
|
|
104
|
+
|
|
105
|
+
2. **Filter by Project**: Use the \`project\` parameter to limit to a specific project
|
|
106
|
+
- project: "my-app"
|
|
107
|
+
|
|
108
|
+
3. **Filter by Date**: Use \`dateFrom\` and \`dateTo\` for time ranges
|
|
109
|
+
- dateFrom: "2026-01-01"
|
|
110
|
+
- dateTo: "2026-01-31"
|
|
111
|
+
|
|
112
|
+
4. **Filter by Technology**: Use \`technologies\` array
|
|
113
|
+
- technologies: ["typescript", "react"]
|
|
114
|
+
|
|
115
|
+
## Example Searches
|
|
116
|
+
|
|
117
|
+
- "database migration prisma" - Find sessions about Prisma migrations
|
|
118
|
+
- "bug fix authentication" - Find sessions where auth bugs were fixed
|
|
119
|
+
- "refactor component" - Find refactoring sessions
|
|
120
|
+
|
|
121
|
+
## Understanding Results
|
|
122
|
+
|
|
123
|
+
Each result includes:
|
|
124
|
+
- **title**: Claude's summary of the session
|
|
125
|
+
- **project**: Which project the session was in
|
|
126
|
+
- **date**: When the session ended
|
|
127
|
+
- **preview**: First user question
|
|
128
|
+
- **filesModified**: Key files that were changed
|
|
129
|
+
- **technologies**: Detected tech stack
|
|
130
|
+
- **messageCount**: Conversation length
|
|
131
|
+
- **durationMinutes**: Session duration
|
|
132
|
+
|
|
133
|
+
Use these results to find relevant context for your current work!`,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
// ============================================================
|
|
140
|
+
// Start Server
|
|
141
|
+
// ============================================================
|
|
142
|
+
async function main() {
|
|
143
|
+
const transport = new StdioServerTransport();
|
|
144
|
+
await server.connect(transport);
|
|
145
|
+
// Log to stderr so it doesn't interfere with stdio protocol
|
|
146
|
+
console.error("Jacques MCP server started");
|
|
147
|
+
}
|
|
148
|
+
main().catch((error) => {
|
|
149
|
+
console.error("Failed to start MCP server:", error);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
});
|
|
152
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Scanner
|
|
3
|
+
*
|
|
4
|
+
* Cross-platform scanner for detecting running Claude Code sessions.
|
|
5
|
+
* Supports macOS, Linux, and Windows.
|
|
6
|
+
*
|
|
7
|
+
* ## How It Works
|
|
8
|
+
*
|
|
9
|
+
* 1. Enumerate all running Claude processes with their PIDs and TTYs
|
|
10
|
+
* 2. Get working directory (CWD) for each process
|
|
11
|
+
* 3. Map CWD to Claude's project directory (~/.claude/projects/{encoded-path})
|
|
12
|
+
* 4. Find ALL active JSONL files in that directory (not just most recent)
|
|
13
|
+
* 5. Parse each for sessionId, gitBranch, context metrics
|
|
14
|
+
* 6. Return all detected sessions
|
|
15
|
+
*
|
|
16
|
+
* ## Platform Support
|
|
17
|
+
*
|
|
18
|
+
* - macOS/Linux: Uses pgrep, ps, lsof
|
|
19
|
+
* - Windows: Uses PowerShell (Get-Process, Get-WmiObject)
|
|
20
|
+
*
|
|
21
|
+
* ## Multi-Session Detection
|
|
22
|
+
*
|
|
23
|
+
* Multiple Claude processes can run in the same directory. We detect all of them by:
|
|
24
|
+
* - Finding all JSONL files modified within ACTIVE_SESSION_THRESHOLD_MS
|
|
25
|
+
* - Using TTY to create unique terminal keys for each process
|
|
26
|
+
* - Matching processes to sessions by recency when exact match isn't possible
|
|
27
|
+
*/
|
|
28
|
+
import type { ContextMetrics, SessionMode } from "./types.js";
|
|
29
|
+
export type { DetectedProcess } from "./connection/process-detection.js";
|
|
30
|
+
/**
|
|
31
|
+
* A session detected from a running Claude process
|
|
32
|
+
*/
|
|
33
|
+
export interface DetectedSession {
|
|
34
|
+
/** Session ID from the JSONL file */
|
|
35
|
+
sessionId: string;
|
|
36
|
+
/** Working directory of the Claude process */
|
|
37
|
+
cwd: string;
|
|
38
|
+
/** Path to the session transcript JSONL file */
|
|
39
|
+
transcriptPath: string;
|
|
40
|
+
/** Git branch if detected */
|
|
41
|
+
gitBranch: string | null;
|
|
42
|
+
/** Git worktree name (basename of worktree dir, only set for worktrees) */
|
|
43
|
+
gitWorktree: string | null;
|
|
44
|
+
/** Canonical git repo root path (main worktree root, shared across all worktrees) */
|
|
45
|
+
gitRepoRoot: string | null;
|
|
46
|
+
/** Context metrics from parsing the transcript */
|
|
47
|
+
contextMetrics: ContextMetrics | null;
|
|
48
|
+
/** Last modification time of the transcript */
|
|
49
|
+
lastActivity: number;
|
|
50
|
+
/** Session title extracted from transcript */
|
|
51
|
+
title: string | null;
|
|
52
|
+
/** Process ID */
|
|
53
|
+
pid: number;
|
|
54
|
+
/** TTY of the process */
|
|
55
|
+
tty: string;
|
|
56
|
+
/** Project name derived from CWD */
|
|
57
|
+
project: string;
|
|
58
|
+
/** Terminal type (iTerm2, Windows Terminal, etc.) */
|
|
59
|
+
terminalType?: string;
|
|
60
|
+
/** Terminal session ID for unique identification */
|
|
61
|
+
terminalSessionId?: string;
|
|
62
|
+
/** Session mode: planning if EnterPlanMode was called, execution if started with plan trigger */
|
|
63
|
+
mode?: SessionMode;
|
|
64
|
+
/** Whether the process was launched with --dangerously-skip-permissions */
|
|
65
|
+
isBypass?: boolean;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Scan for active Claude Code sessions
|
|
69
|
+
*
|
|
70
|
+
* Detects running Claude processes, matches them to session files,
|
|
71
|
+
* and extracts metadata for registration.
|
|
72
|
+
*
|
|
73
|
+
* ## Catalog-First Strategy
|
|
74
|
+
*
|
|
75
|
+
* Uses Jacques session index (from @jacques-ai/core/cache) for pre-extracted metadata:
|
|
76
|
+
* - Session titles (from summary or first user message)
|
|
77
|
+
* - Git info (branch, worktree, repo root)
|
|
78
|
+
* - Token usage stats
|
|
79
|
+
*
|
|
80
|
+
* Falls back to JSONL parsing only for sessions not in the catalog.
|
|
81
|
+
*
|
|
82
|
+
* ## Multi-Session Support
|
|
83
|
+
*
|
|
84
|
+
* When multiple Claude processes run in the same directory:
|
|
85
|
+
* - Finds ALL recently modified JSONL files (within 1 minute)
|
|
86
|
+
* - Creates unique terminal keys using TTY + PID
|
|
87
|
+
* - Returns one DetectedSession per active session file
|
|
88
|
+
*
|
|
89
|
+
* ## Platform Support
|
|
90
|
+
*
|
|
91
|
+
* - macOS/Linux: Uses pgrep, ps, lsof
|
|
92
|
+
* - Windows: Uses PowerShell (Get-Process, Get-WmiObject)
|
|
93
|
+
*/
|
|
94
|
+
export declare function scanForActiveSessions(): Promise<DetectedSession[]>;
|
|
95
|
+
export { getPlatformInfo } from "./connection/process-detection.js";
|
|
96
|
+
//# sourceMappingURL=process-scanner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process-scanner.d.ts","sourceRoot":"","sources":["../src/process-scanner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAa9D,YAAY,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,gDAAgD;IAChD,cAAc,EAAE,MAAM,CAAC;IACvB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,2EAA2E;IAC3E,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qFAAqF;IACrF,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kDAAkD;IAClD,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,+CAA+C;IAC/C,YAAY,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,iBAAiB;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,yBAAyB;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,iGAAiG;IACjG,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC,CAkJxE;AAGD,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Process Scanner
|
|
3
|
+
*
|
|
4
|
+
* Cross-platform scanner for detecting running Claude Code sessions.
|
|
5
|
+
* Supports macOS, Linux, and Windows.
|
|
6
|
+
*
|
|
7
|
+
* ## How It Works
|
|
8
|
+
*
|
|
9
|
+
* 1. Enumerate all running Claude processes with their PIDs and TTYs
|
|
10
|
+
* 2. Get working directory (CWD) for each process
|
|
11
|
+
* 3. Map CWD to Claude's project directory (~/.claude/projects/{encoded-path})
|
|
12
|
+
* 4. Find ALL active JSONL files in that directory (not just most recent)
|
|
13
|
+
* 5. Parse each for sessionId, gitBranch, context metrics
|
|
14
|
+
* 6. Return all detected sessions
|
|
15
|
+
*
|
|
16
|
+
* ## Platform Support
|
|
17
|
+
*
|
|
18
|
+
* - macOS/Linux: Uses pgrep, ps, lsof
|
|
19
|
+
* - Windows: Uses PowerShell (Get-Process, Get-WmiObject)
|
|
20
|
+
*
|
|
21
|
+
* ## Multi-Session Detection
|
|
22
|
+
*
|
|
23
|
+
* Multiple Claude processes can run in the same directory. We detect all of them by:
|
|
24
|
+
* - Finding all JSONL files modified within ACTIVE_SESSION_THRESHOLD_MS
|
|
25
|
+
* - Using TTY to create unique terminal keys for each process
|
|
26
|
+
* - Matching processes to sessions by recency when exact match isn't possible
|
|
27
|
+
*/
|
|
28
|
+
import * as path from "path";
|
|
29
|
+
import { getSessionIndex, } from "@jacques-ai/core/cache";
|
|
30
|
+
import { CATALOG_CACHE_MAX_AGE_MS } from "./connection/constants.js";
|
|
31
|
+
import { findActiveSessionFiles, findMostRecentSessionFile, findRecentSessionFiles, } from "./connection/session-discovery.js";
|
|
32
|
+
import { getClaudeProcesses, } from "./connection/process-detection.js";
|
|
33
|
+
// Process detection delegated to connection/process-detection.ts
|
|
34
|
+
// Session discovery delegated to connection/session-discovery.ts
|
|
35
|
+
// ============================================================
|
|
36
|
+
// Main Scanner Function
|
|
37
|
+
// ============================================================
|
|
38
|
+
/**
|
|
39
|
+
* Scan for active Claude Code sessions
|
|
40
|
+
*
|
|
41
|
+
* Detects running Claude processes, matches them to session files,
|
|
42
|
+
* and extracts metadata for registration.
|
|
43
|
+
*
|
|
44
|
+
* ## Catalog-First Strategy
|
|
45
|
+
*
|
|
46
|
+
* Uses Jacques session index (from @jacques-ai/core/cache) for pre-extracted metadata:
|
|
47
|
+
* - Session titles (from summary or first user message)
|
|
48
|
+
* - Git info (branch, worktree, repo root)
|
|
49
|
+
* - Token usage stats
|
|
50
|
+
*
|
|
51
|
+
* Falls back to JSONL parsing only for sessions not in the catalog.
|
|
52
|
+
*
|
|
53
|
+
* ## Multi-Session Support
|
|
54
|
+
*
|
|
55
|
+
* When multiple Claude processes run in the same directory:
|
|
56
|
+
* - Finds ALL recently modified JSONL files (within 1 minute)
|
|
57
|
+
* - Creates unique terminal keys using TTY + PID
|
|
58
|
+
* - Returns one DetectedSession per active session file
|
|
59
|
+
*
|
|
60
|
+
* ## Platform Support
|
|
61
|
+
*
|
|
62
|
+
* - macOS/Linux: Uses pgrep, ps, lsof
|
|
63
|
+
* - Windows: Uses PowerShell (Get-Process, Get-WmiObject)
|
|
64
|
+
*/
|
|
65
|
+
export async function scanForActiveSessions() {
|
|
66
|
+
const processes = await getClaudeProcesses();
|
|
67
|
+
if (processes.length === 0) {
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
// Load existing session metadata from Jacques catalog
|
|
71
|
+
// Use a short maxAge since we want fresh data but can tolerate recent cache
|
|
72
|
+
let catalogMap = new Map();
|
|
73
|
+
try {
|
|
74
|
+
const sessionIndex = await getSessionIndex({ maxAge: CATALOG_CACHE_MAX_AGE_MS });
|
|
75
|
+
catalogMap = new Map(sessionIndex.sessions.map(s => [s.id, s]));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Catalog unavailable, will fall back to JSONL parsing for all sessions
|
|
79
|
+
}
|
|
80
|
+
const sessions = [];
|
|
81
|
+
const processedSessionIds = new Set();
|
|
82
|
+
// Group processes by CWD
|
|
83
|
+
const processesByCwd = new Map();
|
|
84
|
+
for (const proc of processes) {
|
|
85
|
+
const existing = processesByCwd.get(proc.cwd) || [];
|
|
86
|
+
existing.push(proc);
|
|
87
|
+
processesByCwd.set(proc.cwd, existing);
|
|
88
|
+
}
|
|
89
|
+
// Process each unique CWD
|
|
90
|
+
for (const [cwd, cwdProcesses] of processesByCwd) {
|
|
91
|
+
// Find all active session files for this CWD (uses catalog when available)
|
|
92
|
+
let sessionFiles = await findActiveSessionFiles(cwd, catalogMap);
|
|
93
|
+
// If no active sessions found, fall back to most recent
|
|
94
|
+
if (sessionFiles.length === 0) {
|
|
95
|
+
const mostRecent = await findMostRecentSessionFile(cwd, catalogMap);
|
|
96
|
+
if (mostRecent) {
|
|
97
|
+
sessionFiles = [mostRecent];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (sessionFiles.length === 0) {
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
// Match processes to session files
|
|
104
|
+
// Strategy: If N processes and M sessions, pair them by recency
|
|
105
|
+
const numPairs = Math.min(cwdProcesses.length, sessionFiles.length);
|
|
106
|
+
const project = path.basename(cwd) || "Unknown";
|
|
107
|
+
for (let i = 0; i < numPairs; i++) {
|
|
108
|
+
const proc = cwdProcesses[i];
|
|
109
|
+
const sessionFile = sessionFiles[i];
|
|
110
|
+
// Skip if we already registered this session ID
|
|
111
|
+
if (processedSessionIds.has(sessionFile.sessionId)) {
|
|
112
|
+
continue;
|
|
113
|
+
}
|
|
114
|
+
processedSessionIds.add(sessionFile.sessionId);
|
|
115
|
+
sessions.push({
|
|
116
|
+
sessionId: sessionFile.sessionId,
|
|
117
|
+
cwd,
|
|
118
|
+
transcriptPath: sessionFile.filePath,
|
|
119
|
+
gitBranch: sessionFile.gitBranch,
|
|
120
|
+
gitWorktree: sessionFile.gitWorktree,
|
|
121
|
+
gitRepoRoot: sessionFile.gitRepoRoot,
|
|
122
|
+
contextMetrics: sessionFile.contextMetrics,
|
|
123
|
+
lastActivity: sessionFile.modifiedAt.getTime(),
|
|
124
|
+
title: sessionFile.title,
|
|
125
|
+
pid: proc.pid,
|
|
126
|
+
tty: proc.tty,
|
|
127
|
+
project,
|
|
128
|
+
terminalType: proc.terminalType,
|
|
129
|
+
terminalSessionId: proc.terminalSessionId,
|
|
130
|
+
mode: sessionFile.mode,
|
|
131
|
+
isBypass: proc.isBypass,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
// If more session files than processes, register remaining sessions
|
|
135
|
+
// with synthetic process info (they might be from recently closed terminals)
|
|
136
|
+
for (let i = numPairs; i < sessionFiles.length; i++) {
|
|
137
|
+
const sessionFile = sessionFiles[i];
|
|
138
|
+
if (processedSessionIds.has(sessionFile.sessionId)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
processedSessionIds.add(sessionFile.sessionId);
|
|
142
|
+
sessions.push({
|
|
143
|
+
sessionId: sessionFile.sessionId,
|
|
144
|
+
cwd,
|
|
145
|
+
transcriptPath: sessionFile.filePath,
|
|
146
|
+
gitBranch: sessionFile.gitBranch,
|
|
147
|
+
gitWorktree: sessionFile.gitWorktree,
|
|
148
|
+
gitRepoRoot: sessionFile.gitRepoRoot,
|
|
149
|
+
contextMetrics: sessionFile.contextMetrics,
|
|
150
|
+
lastActivity: sessionFile.modifiedAt.getTime(),
|
|
151
|
+
title: sessionFile.title,
|
|
152
|
+
pid: 0, // Unknown PID
|
|
153
|
+
tty: "?",
|
|
154
|
+
project,
|
|
155
|
+
mode: sessionFile.mode,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
// If more processes than session files, look for idle sessions
|
|
159
|
+
// (JSONL files not modified within the active threshold but still belonging to running processes)
|
|
160
|
+
if (cwdProcesses.length > sessionFiles.length) {
|
|
161
|
+
const excessCount = cwdProcesses.length - sessionFiles.length;
|
|
162
|
+
const recentFiles = await findRecentSessionFiles(cwd, catalogMap, excessCount, processedSessionIds);
|
|
163
|
+
for (let i = 0; i < recentFiles.length; i++) {
|
|
164
|
+
const sessionFile = recentFiles[i];
|
|
165
|
+
// Pair with remaining unmatched processes
|
|
166
|
+
const procIndex = sessionFiles.length + i;
|
|
167
|
+
const proc = procIndex < cwdProcesses.length ? cwdProcesses[procIndex] : null;
|
|
168
|
+
processedSessionIds.add(sessionFile.sessionId);
|
|
169
|
+
sessions.push({
|
|
170
|
+
sessionId: sessionFile.sessionId,
|
|
171
|
+
cwd,
|
|
172
|
+
transcriptPath: sessionFile.filePath,
|
|
173
|
+
gitBranch: sessionFile.gitBranch,
|
|
174
|
+
gitWorktree: sessionFile.gitWorktree,
|
|
175
|
+
gitRepoRoot: sessionFile.gitRepoRoot,
|
|
176
|
+
contextMetrics: sessionFile.contextMetrics,
|
|
177
|
+
lastActivity: sessionFile.modifiedAt.getTime(),
|
|
178
|
+
title: sessionFile.title,
|
|
179
|
+
pid: proc?.pid ?? 0,
|
|
180
|
+
tty: proc?.tty ?? "?",
|
|
181
|
+
project,
|
|
182
|
+
terminalType: proc?.terminalType,
|
|
183
|
+
terminalSessionId: proc?.terminalSessionId,
|
|
184
|
+
mode: sessionFile.mode,
|
|
185
|
+
isBypass: proc?.isBypass,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return sessions;
|
|
191
|
+
}
|
|
192
|
+
// getPlatformInfo re-exported from connection/process-detection
|
|
193
|
+
export { getPlatformInfo } from "./connection/process-detection.js";
|
|
194
|
+
//# sourceMappingURL=process-scanner.js.map
|