@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,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Launcher
|
|
3
|
+
*
|
|
4
|
+
* Launches a new terminal window in a given directory and runs `claude` in it.
|
|
5
|
+
* Supports iTerm2, Terminal.app, Kitty, WezTerm, Windows Terminal, PowerShell,
|
|
6
|
+
* and GNOME Terminal. Auto-detects the best available terminal per platform.
|
|
7
|
+
*
|
|
8
|
+
* Once claude starts, the existing hook infrastructure (SessionStart) handles
|
|
9
|
+
* auto-registration — the new session appears in Jacques automatically.
|
|
10
|
+
*/
|
|
11
|
+
import { spawn, exec as execCb } from 'child_process';
|
|
12
|
+
import { promisify } from 'util';
|
|
13
|
+
import { existsSync } from 'fs';
|
|
14
|
+
import { runAppleScript, isAppleScriptAvailable } from './connection/index.js';
|
|
15
|
+
const execAsync = promisify(execCb);
|
|
16
|
+
/**
|
|
17
|
+
* Launch a new terminal session running `claude` in the given directory.
|
|
18
|
+
*
|
|
19
|
+
* Terminal detection priority:
|
|
20
|
+
* - macOS: iTerm2 → Kitty → WezTerm → Terminal.app
|
|
21
|
+
* - Windows: Windows Terminal → PowerShell
|
|
22
|
+
* - Linux: Kitty → WezTerm → GNOME Terminal
|
|
23
|
+
*/
|
|
24
|
+
export async function launchTerminalSession(options) {
|
|
25
|
+
const { cwd, preferredTerminal, targetBounds, dangerouslySkipPermissions } = options;
|
|
26
|
+
if (!cwd) {
|
|
27
|
+
return { success: false, method: 'unsupported', error: 'Missing cwd' };
|
|
28
|
+
}
|
|
29
|
+
if (!existsSync(cwd)) {
|
|
30
|
+
return { success: false, method: 'unsupported', error: `Directory does not exist: ${cwd}` };
|
|
31
|
+
}
|
|
32
|
+
const claudeCmd = dangerouslySkipPermissions ? 'claude --dangerously-skip-permissions' : 'claude';
|
|
33
|
+
// Use preferred terminal if specified
|
|
34
|
+
if (preferredTerminal) {
|
|
35
|
+
return launchWithMethod(preferredTerminal, cwd, claudeCmd, targetBounds);
|
|
36
|
+
}
|
|
37
|
+
// Auto-detect best available terminal
|
|
38
|
+
const method = await detectAvailableTerminal();
|
|
39
|
+
if (method === 'unsupported') {
|
|
40
|
+
return { success: false, method: 'unsupported', error: 'No supported terminal emulator found' };
|
|
41
|
+
}
|
|
42
|
+
return launchWithMethod(method, cwd, claudeCmd, targetBounds);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Detect the best available terminal emulator for the current platform.
|
|
46
|
+
*/
|
|
47
|
+
export async function detectAvailableTerminal() {
|
|
48
|
+
if (process.platform === 'darwin') {
|
|
49
|
+
if (existsSync('/Applications/iTerm.app'))
|
|
50
|
+
return 'iterm';
|
|
51
|
+
if (await isCommandOnPath('kitty'))
|
|
52
|
+
return 'kitty';
|
|
53
|
+
if (await isCommandOnPath('wezterm'))
|
|
54
|
+
return 'wezterm';
|
|
55
|
+
return 'terminal_app'; // Always available on macOS
|
|
56
|
+
}
|
|
57
|
+
if (process.platform === 'win32') {
|
|
58
|
+
if (await isCommandOnPath('wt'))
|
|
59
|
+
return 'windows_terminal';
|
|
60
|
+
return 'powershell'; // Always available on Windows
|
|
61
|
+
}
|
|
62
|
+
// Linux
|
|
63
|
+
if (await isCommandOnPath('kitty'))
|
|
64
|
+
return 'kitty';
|
|
65
|
+
if (await isCommandOnPath('wezterm'))
|
|
66
|
+
return 'wezterm';
|
|
67
|
+
if (await isCommandOnPath('gnome-terminal'))
|
|
68
|
+
return 'gnome_terminal';
|
|
69
|
+
return 'unsupported';
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Check if a command is available on the system PATH.
|
|
73
|
+
*/
|
|
74
|
+
export async function isCommandOnPath(cmd) {
|
|
75
|
+
try {
|
|
76
|
+
const which = process.platform === 'win32' ? 'where' : 'which';
|
|
77
|
+
await execAsync(`${which} ${cmd}`);
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
async function launchWithMethod(method, cwd, claudeCmd, targetBounds) {
|
|
85
|
+
switch (method) {
|
|
86
|
+
case 'iterm':
|
|
87
|
+
return launchITerm(cwd, claudeCmd, targetBounds);
|
|
88
|
+
case 'terminal_app':
|
|
89
|
+
return launchTerminalApp(cwd, claudeCmd, targetBounds);
|
|
90
|
+
case 'kitty':
|
|
91
|
+
return launchKitty(cwd, claudeCmd);
|
|
92
|
+
case 'wezterm':
|
|
93
|
+
return launchWezTerm(cwd, claudeCmd);
|
|
94
|
+
case 'windows_terminal':
|
|
95
|
+
return launchWindowsTerminal(cwd, claudeCmd);
|
|
96
|
+
case 'powershell':
|
|
97
|
+
return launchPowerShell(cwd, claudeCmd);
|
|
98
|
+
case 'gnome_terminal':
|
|
99
|
+
return launchGnomeTerminal(cwd, claudeCmd);
|
|
100
|
+
default:
|
|
101
|
+
return { success: false, method: 'unsupported', error: `Unknown launch method: ${method}` };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Launch iTerm2 with a new window running claude.
|
|
106
|
+
* Uses AppleScript via the existing runAppleScript() infrastructure.
|
|
107
|
+
*
|
|
108
|
+
* We create a window with default profile (login shell), then write text
|
|
109
|
+
* to the session. This ensures the user's PATH is loaded (e.g. ~/.zshrc)
|
|
110
|
+
* so `claude` is found even if it's in ~/.local/bin.
|
|
111
|
+
*/
|
|
112
|
+
async function launchITerm(cwd, claudeCmd, targetBounds) {
|
|
113
|
+
if (!isAppleScriptAvailable()) {
|
|
114
|
+
return { success: false, method: 'iterm', error: 'AppleScript not available (macOS only)' };
|
|
115
|
+
}
|
|
116
|
+
const escapedCwd = escapeForAppleScript(cwd);
|
|
117
|
+
// If targetBounds provided, position window on that display instead of cascading
|
|
118
|
+
const positionBlock = targetBounds
|
|
119
|
+
? `set bounds of newWindow to {${targetBounds.x}, ${targetBounds.y}, ${targetBounds.x + targetBounds.width}, ${targetBounds.y + targetBounds.height}}`
|
|
120
|
+
: `-- Cascade position from existing window
|
|
121
|
+
if hasExisting then
|
|
122
|
+
-- Wrap if cascade would push off screen edge
|
|
123
|
+
if (cascadeX + winW) > 2400 then set cascadeX to 100
|
|
124
|
+
if (cascadeY + winH) > 1500 then set cascadeY to 100
|
|
125
|
+
set bounds of newWindow to {cascadeX, cascadeY, cascadeX + winW, cascadeY + winH}
|
|
126
|
+
end if`;
|
|
127
|
+
const script = `
|
|
128
|
+
tell application "iTerm2" to activate
|
|
129
|
+
delay 0.6
|
|
130
|
+
|
|
131
|
+
tell application "iTerm2"
|
|
132
|
+
-- Capture existing front window bounds for cascade
|
|
133
|
+
set hasExisting to false
|
|
134
|
+
set cascadeX to 100
|
|
135
|
+
set cascadeY to 100
|
|
136
|
+
set winW to 800
|
|
137
|
+
set winH to 600
|
|
138
|
+
|
|
139
|
+
if (count of windows) > 0 then
|
|
140
|
+
set hasExisting to true
|
|
141
|
+
set {x1, y1, x2, y2} to bounds of front window
|
|
142
|
+
set winW to x2 - x1
|
|
143
|
+
set winH to y2 - y1
|
|
144
|
+
set cascadeX to x1 + 30
|
|
145
|
+
set cascadeY to y1 + 30
|
|
146
|
+
end if
|
|
147
|
+
|
|
148
|
+
set newWindow to (create window with default profile)
|
|
149
|
+
tell current session of newWindow
|
|
150
|
+
write text "cd '${escapedCwd}' && ${claudeCmd}"
|
|
151
|
+
end tell
|
|
152
|
+
|
|
153
|
+
${positionBlock}
|
|
154
|
+
end tell
|
|
155
|
+
`;
|
|
156
|
+
try {
|
|
157
|
+
await runAppleScript(script);
|
|
158
|
+
return { success: true, method: 'iterm' };
|
|
159
|
+
}
|
|
160
|
+
catch (err) {
|
|
161
|
+
return { success: false, method: 'iterm', error: formatError(err) };
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Launch Terminal.app with a new window running claude.
|
|
166
|
+
* Uses `do script` which opens a login shell with full PATH.
|
|
167
|
+
*/
|
|
168
|
+
async function launchTerminalApp(cwd, claudeCmd, targetBounds) {
|
|
169
|
+
if (!isAppleScriptAvailable()) {
|
|
170
|
+
return { success: false, method: 'terminal_app', error: 'AppleScript not available (macOS only)' };
|
|
171
|
+
}
|
|
172
|
+
const escapedCwd = escapeForAppleScript(cwd);
|
|
173
|
+
const positionBlock = targetBounds
|
|
174
|
+
? `set bounds of front window to {${targetBounds.x}, ${targetBounds.y}, ${targetBounds.x + targetBounds.width}, ${targetBounds.y + targetBounds.height}}`
|
|
175
|
+
: `-- Cascade position
|
|
176
|
+
if hasExisting then
|
|
177
|
+
if (cascadeX + winW) > 2400 then set cascadeX to 100
|
|
178
|
+
if (cascadeY + winH) > 1500 then set cascadeY to 100
|
|
179
|
+
set bounds of front window to {cascadeX, cascadeY, cascadeX + winW, cascadeY + winH}
|
|
180
|
+
end if`;
|
|
181
|
+
const script = `
|
|
182
|
+
tell application "Terminal"
|
|
183
|
+
-- Capture existing window bounds for cascade
|
|
184
|
+
set hasExisting to false
|
|
185
|
+
set cascadeX to 100
|
|
186
|
+
set cascadeY to 100
|
|
187
|
+
set winW to 800
|
|
188
|
+
set winH to 600
|
|
189
|
+
|
|
190
|
+
if (count of windows) > 0 then
|
|
191
|
+
set hasExisting to true
|
|
192
|
+
set {x1, y1, x2, y2} to bounds of front window
|
|
193
|
+
set winW to x2 - x1
|
|
194
|
+
set winH to y2 - y1
|
|
195
|
+
set cascadeX to x1 + 30
|
|
196
|
+
set cascadeY to y1 + 30
|
|
197
|
+
end if
|
|
198
|
+
|
|
199
|
+
do script "cd '${escapedCwd}' && ${claudeCmd}"
|
|
200
|
+
activate
|
|
201
|
+
|
|
202
|
+
${positionBlock}
|
|
203
|
+
end tell
|
|
204
|
+
`;
|
|
205
|
+
try {
|
|
206
|
+
await runAppleScript(script);
|
|
207
|
+
return { success: true, method: 'terminal_app' };
|
|
208
|
+
}
|
|
209
|
+
catch (err) {
|
|
210
|
+
return { success: false, method: 'terminal_app', error: formatError(err) };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Launch Kitty terminal with claude.
|
|
215
|
+
* Works on macOS and Linux.
|
|
216
|
+
*/
|
|
217
|
+
async function launchKitty(cwd, claudeCmd) {
|
|
218
|
+
return spawnDetached('kitty', ['--directory', cwd, ...claudeCmd.split(' ')], 'kitty');
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Launch WezTerm with claude.
|
|
222
|
+
* Uses `wezterm start` for new window (not `wezterm cli spawn` which targets existing).
|
|
223
|
+
* Works on macOS, Linux, and Windows.
|
|
224
|
+
*/
|
|
225
|
+
async function launchWezTerm(cwd, claudeCmd) {
|
|
226
|
+
return spawnDetached('wezterm', ['start', '--cwd', cwd, '--', ...claudeCmd.split(' ')], 'wezterm');
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Launch Windows Terminal with claude.
|
|
230
|
+
*/
|
|
231
|
+
async function launchWindowsTerminal(cwd, claudeCmd) {
|
|
232
|
+
return spawnDetached('wt', ['-d', cwd, ...claudeCmd.split(' ')], 'windows_terminal', { shell: true });
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Launch PowerShell with claude (Windows fallback).
|
|
236
|
+
*/
|
|
237
|
+
async function launchPowerShell(cwd, claudeCmd) {
|
|
238
|
+
const escapedCwd = cwd.replace(/"/g, '`"');
|
|
239
|
+
return spawnDetached('powershell', [
|
|
240
|
+
'-NoProfile',
|
|
241
|
+
'-Command',
|
|
242
|
+
`Start-Process powershell -ArgumentList '-NoExit', '-Command', 'cd "${escapedCwd}"; ${claudeCmd}'`,
|
|
243
|
+
], 'powershell');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Launch GNOME Terminal with claude (Linux).
|
|
247
|
+
*/
|
|
248
|
+
async function launchGnomeTerminal(cwd, claudeCmd) {
|
|
249
|
+
return spawnDetached('gnome-terminal', ['--working-directory=' + cwd, '--', ...claudeCmd.split(' ')], 'gnome_terminal');
|
|
250
|
+
}
|
|
251
|
+
// ─── Helpers ──────────────────────────────────────────────────
|
|
252
|
+
/**
|
|
253
|
+
* Spawn a detached process and handle ENOENT/errors gracefully.
|
|
254
|
+
* The spawn() call emits 'error' asynchronously for ENOENT, so we
|
|
255
|
+
* wait briefly for the error event before declaring success.
|
|
256
|
+
*/
|
|
257
|
+
function spawnDetached(cmd, args, method, extraOpts) {
|
|
258
|
+
return new Promise((resolve) => {
|
|
259
|
+
try {
|
|
260
|
+
const proc = spawn(cmd, args, {
|
|
261
|
+
detached: true,
|
|
262
|
+
stdio: 'ignore',
|
|
263
|
+
...extraOpts,
|
|
264
|
+
});
|
|
265
|
+
let resolved = false;
|
|
266
|
+
proc.on('error', (err) => {
|
|
267
|
+
if (!resolved) {
|
|
268
|
+
resolved = true;
|
|
269
|
+
resolve({ success: false, method, error: formatError(err) });
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
proc.unref();
|
|
273
|
+
// Give a brief window for ENOENT to fire before declaring success
|
|
274
|
+
setTimeout(() => {
|
|
275
|
+
if (!resolved) {
|
|
276
|
+
resolved = true;
|
|
277
|
+
resolve({ success: true, method, pid: proc.pid });
|
|
278
|
+
}
|
|
279
|
+
}, 100);
|
|
280
|
+
}
|
|
281
|
+
catch (err) {
|
|
282
|
+
resolve({ success: false, method, error: formatError(err) });
|
|
283
|
+
}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Escape a string for use inside single-quoted AppleScript strings.
|
|
288
|
+
*/
|
|
289
|
+
function escapeForAppleScript(str) {
|
|
290
|
+
return str.replace(/'/g, "'\\''");
|
|
291
|
+
}
|
|
292
|
+
function formatError(err) {
|
|
293
|
+
if (err instanceof Error) {
|
|
294
|
+
return err.message;
|
|
295
|
+
}
|
|
296
|
+
return String(err);
|
|
297
|
+
}
|
|
298
|
+
//# sourceMappingURL=terminal-launcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-launcher.js","sourceRoot":"","sources":["../src/terminal-launcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,IAAI,IAAI,MAAM,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAE/E,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;AA+BpC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAsB;IAChE,MAAM,EAAE,GAAG,EAAE,iBAAiB,EAAE,YAAY,EAAE,0BAA0B,EAAE,GAAG,OAAO,CAAC;IAErF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC;IACzE,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,6BAA6B,GAAG,EAAE,EAAE,CAAC;IAC9F,CAAC;IAED,MAAM,SAAS,GAAG,0BAA0B,CAAC,CAAC,CAAC,uCAAuC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAElG,sCAAsC;IACtC,IAAI,iBAAiB,EAAE,CAAC;QACtB,OAAO,gBAAgB,CAAC,iBAAiC,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;IAC3F,CAAC;IAED,sCAAsC;IACtC,MAAM,MAAM,GAAG,MAAM,uBAAuB,EAAE,CAAC;IAC/C,IAAI,MAAM,KAAK,aAAa,EAAE,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,sCAAsC,EAAE,CAAC;IAClG,CAAC;IAED,OAAO,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;AAChE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,UAAU,CAAC,yBAAyB,CAAC;YAAE,OAAO,OAAO,CAAC;QAC1D,IAAI,MAAM,eAAe,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QACnD,IAAI,MAAM,eAAe,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAC;QACvD,OAAO,cAAc,CAAC,CAAC,4BAA4B;IACrD,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,IAAI,MAAM,eAAe,CAAC,IAAI,CAAC;YAAE,OAAO,kBAAkB,CAAC;QAC3D,OAAO,YAAY,CAAC,CAAC,8BAA8B;IACrD,CAAC;IAED,QAAQ;IACR,IAAI,MAAM,eAAe,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACnD,IAAI,MAAM,eAAe,CAAC,SAAS,CAAC;QAAE,OAAO,SAAS,CAAC;IACvD,IAAI,MAAM,eAAe,CAAC,gBAAgB,CAAC;QAAE,OAAO,gBAAgB,CAAC;IAErE,OAAO,aAAa,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,GAAW;IAC/C,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;QAC/D,MAAM,SAAS,CAAC,GAAG,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAMD,KAAK,UAAU,gBAAgB,CAAC,MAAoB,EAAE,GAAW,EAAE,SAAiB,EAAE,YAAqB;IACzG,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;QACnD,KAAK,cAAc;YACjB,OAAO,iBAAiB,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;QACzD,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACrC,KAAK,SAAS;YACZ,OAAO,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QACvC,KAAK,kBAAkB;YACrB,OAAO,qBAAqB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC/C,KAAK,YAAY;YACf,OAAO,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC1C,KAAK,gBAAgB;YACnB,OAAO,mBAAmB,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAC7C;YACE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,0BAA0B,MAAM,EAAE,EAAE,CAAC;IAChG,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,SAAiB,EAAE,YAAqB;IAC9E,IAAI,CAAC,sBAAsB,EAAE,EAAE,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC;IAC9F,CAAC;IAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAE7C,iFAAiF;IACjF,MAAM,aAAa,GAAG,YAAY;QAChC,CAAC,CAAC,+BAA+B,YAAY,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,GAAG;QACtJ,CAAC,CAAC;;;;;;aAMO,CAAC;IAEZ,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;0BAuBS,UAAU,QAAQ,SAAS;;;QAG7C,aAAa;;GAElB,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;IAC5C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IACtE,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,iBAAiB,CAAC,GAAW,EAAE,SAAiB,EAAE,YAAqB;IACpF,IAAI,CAAC,sBAAsB,EAAE,EAAE,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,wCAAwC,EAAE,CAAC;IACrG,CAAC;IAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAE7C,MAAM,aAAa,GAAG,YAAY;QAChC,CAAC,CAAC,kCAAkC,YAAY,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,GAAG,YAAY,CAAC,MAAM,GAAG;QACzJ,CAAC,CAAC;;;;;aAKO,CAAC;IAEZ,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;uBAkBM,UAAU,QAAQ,SAAS;;;QAG1C,aAAa;;GAElB,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;QAC7B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IACnD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;IAC7E,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,WAAW,CAAC,GAAW,EAAE,SAAiB;IACvD,OAAO,aAAa,CAAC,OAAO,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACxF,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,SAAiB;IACzD,OAAO,aAAa,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;AACrG,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,qBAAqB,CAAC,GAAW,EAAE,SAAiB;IACjE,OAAO,aAAa,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,kBAAkB,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACxG,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,gBAAgB,CAAC,GAAW,EAAE,SAAiB;IAC5D,MAAM,UAAU,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC3C,OAAO,aAAa,CAAC,YAAY,EAAE;QACjC,YAAY;QACZ,UAAU;QACV,sEAAsE,UAAU,MAAM,SAAS,GAAG;KACnG,EAAE,YAAY,CAAC,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,mBAAmB,CAAC,GAAW,EAAE,SAAiB;IAC/D,OAAO,aAAa,CAAC,gBAAgB,EAAE,CAAC,sBAAsB,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;AAC1H,CAAC;AAED,iEAAiE;AAEjE;;;;GAIG;AACH,SAAS,aAAa,CACpB,GAAW,EACX,IAAc,EACd,MAAoB,EACpB,SAAmC;IAEnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;gBAC5B,QAAQ,EAAE,IAAI;gBACd,KAAK,EAAE,QAAQ;gBACf,GAAG,SAAS;aACb,CAAC,CAAC;YAEH,IAAI,QAAQ,GAAG,KAAK,CAAC;YAErB,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;gBACvB,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAC/D,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,KAAK,EAAE,CAAC;YAEb,kEAAkE;YAClE,UAAU,CAAC,GAAG,EAAE;gBACd,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACd,QAAQ,GAAG,IAAI,CAAC;oBAChB,OAAO,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBACpD,CAAC;YACH,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB,CAAC,GAAW;IACvC,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,WAAW,CAAC,GAAY;IAC/B,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-launcher.test.d.ts","sourceRoot":"","sources":["../src/terminal-launcher.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal Launcher Tests
|
|
3
|
+
*
|
|
4
|
+
* Tests input validation, terminal detection logic, and method dispatch.
|
|
5
|
+
* Terminal spawning is mocked to prevent opening real windows during tests.
|
|
6
|
+
*/
|
|
7
|
+
import { jest } from '@jest/globals';
|
|
8
|
+
// ─── MOCKS (must be before module-under-test import) ──────────
|
|
9
|
+
// Get real exec before mocking (needed for isCommandOnPath/detectAvailableTerminal)
|
|
10
|
+
const { exec: realExec } = await import('child_process');
|
|
11
|
+
const mockSpawn = jest.fn();
|
|
12
|
+
jest.unstable_mockModule('child_process', () => ({
|
|
13
|
+
spawn: mockSpawn,
|
|
14
|
+
exec: realExec,
|
|
15
|
+
}));
|
|
16
|
+
const mockRunAppleScript = jest.fn();
|
|
17
|
+
const mockIsAppleScriptAvailable = jest.fn();
|
|
18
|
+
jest.unstable_mockModule('./connection/index.js', () => ({
|
|
19
|
+
runAppleScript: mockRunAppleScript,
|
|
20
|
+
isAppleScriptAvailable: mockIsAppleScriptAvailable,
|
|
21
|
+
}));
|
|
22
|
+
// ─── IMPORTS (after mocks) ────────────────────────────────────
|
|
23
|
+
const { launchTerminalSession, detectAvailableTerminal, isCommandOnPath } = await import('./terminal-launcher.js');
|
|
24
|
+
// ─── HELPERS ──────────────────────────────────────────────────
|
|
25
|
+
/** Create a fake child process that spawn() can return */
|
|
26
|
+
function createFakeProcess(pid = 12345) {
|
|
27
|
+
return {
|
|
28
|
+
pid,
|
|
29
|
+
on: jest.fn(),
|
|
30
|
+
unref: jest.fn(),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// ─── TESTS ────────────────────────────────────────────────────
|
|
34
|
+
describe('launchTerminalSession', () => {
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
jest.clearAllMocks();
|
|
37
|
+
// Default: spawn returns a successful fake process
|
|
38
|
+
mockSpawn.mockImplementation(() => createFakeProcess());
|
|
39
|
+
// Default: AppleScript available and succeeds
|
|
40
|
+
mockIsAppleScriptAvailable.mockReturnValue(true);
|
|
41
|
+
mockRunAppleScript.mockResolvedValue('');
|
|
42
|
+
});
|
|
43
|
+
describe('input validation', () => {
|
|
44
|
+
it('should reject empty cwd', async () => {
|
|
45
|
+
const result = await launchTerminalSession({ cwd: '' });
|
|
46
|
+
expect(result.success).toBe(false);
|
|
47
|
+
expect(result.method).toBe('unsupported');
|
|
48
|
+
expect(result.error).toContain('Missing cwd');
|
|
49
|
+
});
|
|
50
|
+
it('should reject non-existent directory', async () => {
|
|
51
|
+
const result = await launchTerminalSession({ cwd: '/tmp/jacques-nonexistent-dir-12345' });
|
|
52
|
+
expect(result.success).toBe(false);
|
|
53
|
+
expect(result.method).toBe('unsupported');
|
|
54
|
+
expect(result.error).toContain('does not exist');
|
|
55
|
+
});
|
|
56
|
+
it('should reject unknown preferred terminal', async () => {
|
|
57
|
+
const result = await launchTerminalSession({
|
|
58
|
+
cwd: '/tmp',
|
|
59
|
+
preferredTerminal: 'unsupported',
|
|
60
|
+
});
|
|
61
|
+
expect(result.success).toBe(false);
|
|
62
|
+
expect(result.method).toBe('unsupported');
|
|
63
|
+
expect(result.error).toContain('Unknown launch method');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('detectAvailableTerminal', () => {
|
|
67
|
+
it('should return a valid launch method', async () => {
|
|
68
|
+
const method = await detectAvailableTerminal();
|
|
69
|
+
const validMethods = [
|
|
70
|
+
'iterm', 'terminal_app', 'kitty', 'wezterm',
|
|
71
|
+
'gnome_terminal', 'windows_terminal', 'powershell', 'unsupported',
|
|
72
|
+
];
|
|
73
|
+
expect(validMethods).toContain(method);
|
|
74
|
+
});
|
|
75
|
+
// On macOS, should always find at least Terminal.app
|
|
76
|
+
if (process.platform === 'darwin') {
|
|
77
|
+
it('should find Terminal.app on macOS at minimum', async () => {
|
|
78
|
+
const method = await detectAvailableTerminal();
|
|
79
|
+
expect(method).not.toBe('unsupported');
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// On Windows, should always find at least PowerShell
|
|
83
|
+
if (process.platform === 'win32') {
|
|
84
|
+
it('should find PowerShell on Windows at minimum', async () => {
|
|
85
|
+
const method = await detectAvailableTerminal();
|
|
86
|
+
expect(method).not.toBe('unsupported');
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
describe('isCommandOnPath', () => {
|
|
91
|
+
it('should find common commands', async () => {
|
|
92
|
+
// These should exist on any system running tests
|
|
93
|
+
const cmd = process.platform === 'win32' ? 'cmd' : 'ls';
|
|
94
|
+
const result = await isCommandOnPath(cmd);
|
|
95
|
+
expect(result).toBe(true);
|
|
96
|
+
});
|
|
97
|
+
it('should return false for nonexistent command', async () => {
|
|
98
|
+
const result = await isCommandOnPath('jacques-nonexistent-command-12345');
|
|
99
|
+
expect(result).toBe(false);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
// Method dispatch tests - mocked so no real terminals open
|
|
103
|
+
describe('method dispatch', () => {
|
|
104
|
+
it('should dispatch to iterm and run AppleScript', async () => {
|
|
105
|
+
const result = await launchTerminalSession({
|
|
106
|
+
cwd: '/tmp',
|
|
107
|
+
preferredTerminal: 'iterm',
|
|
108
|
+
});
|
|
109
|
+
expect(result.method).toBe('iterm');
|
|
110
|
+
expect(result.success).toBe(true);
|
|
111
|
+
expect(mockRunAppleScript).toHaveBeenCalledTimes(1);
|
|
112
|
+
const script = mockRunAppleScript.mock.calls[0][0];
|
|
113
|
+
expect(script).toContain('tell application "iTerm2"');
|
|
114
|
+
expect(script).toContain("cd '/tmp' && claude");
|
|
115
|
+
});
|
|
116
|
+
it('should dispatch to terminal_app and run AppleScript', async () => {
|
|
117
|
+
const result = await launchTerminalSession({
|
|
118
|
+
cwd: '/tmp',
|
|
119
|
+
preferredTerminal: 'terminal_app',
|
|
120
|
+
});
|
|
121
|
+
expect(result.method).toBe('terminal_app');
|
|
122
|
+
expect(result.success).toBe(true);
|
|
123
|
+
expect(mockRunAppleScript).toHaveBeenCalledTimes(1);
|
|
124
|
+
const script = mockRunAppleScript.mock.calls[0][0];
|
|
125
|
+
expect(script).toContain('tell application "Terminal"');
|
|
126
|
+
expect(script).toContain("cd '/tmp' && claude");
|
|
127
|
+
});
|
|
128
|
+
it('should dispatch to kitty and spawn correct command', async () => {
|
|
129
|
+
const result = await launchTerminalSession({
|
|
130
|
+
cwd: '/tmp',
|
|
131
|
+
preferredTerminal: 'kitty',
|
|
132
|
+
});
|
|
133
|
+
expect(result.method).toBe('kitty');
|
|
134
|
+
expect(result.success).toBe(true);
|
|
135
|
+
expect(mockSpawn).toHaveBeenCalledWith('kitty', ['--directory', '/tmp', 'claude'], expect.objectContaining({ detached: true, stdio: 'ignore' }));
|
|
136
|
+
});
|
|
137
|
+
it('should dispatch to wezterm and spawn correct command', async () => {
|
|
138
|
+
const result = await launchTerminalSession({
|
|
139
|
+
cwd: '/tmp',
|
|
140
|
+
preferredTerminal: 'wezterm',
|
|
141
|
+
});
|
|
142
|
+
expect(result.method).toBe('wezterm');
|
|
143
|
+
expect(result.success).toBe(true);
|
|
144
|
+
expect(mockSpawn).toHaveBeenCalledWith('wezterm', ['start', '--cwd', '/tmp', '--', 'claude'], expect.objectContaining({ detached: true, stdio: 'ignore' }));
|
|
145
|
+
});
|
|
146
|
+
it('should dispatch to gnome_terminal and spawn correct command', async () => {
|
|
147
|
+
const result = await launchTerminalSession({
|
|
148
|
+
cwd: '/tmp',
|
|
149
|
+
preferredTerminal: 'gnome_terminal',
|
|
150
|
+
});
|
|
151
|
+
expect(result.method).toBe('gnome_terminal');
|
|
152
|
+
expect(mockSpawn).toHaveBeenCalledWith('gnome-terminal', ['--working-directory=/tmp', '--', 'claude'], expect.objectContaining({ detached: true, stdio: 'ignore' }));
|
|
153
|
+
});
|
|
154
|
+
it('should dispatch to windows_terminal with shell option', async () => {
|
|
155
|
+
const result = await launchTerminalSession({
|
|
156
|
+
cwd: '/tmp',
|
|
157
|
+
preferredTerminal: 'windows_terminal',
|
|
158
|
+
});
|
|
159
|
+
expect(result.method).toBe('windows_terminal');
|
|
160
|
+
expect(mockSpawn).toHaveBeenCalledWith('wt', ['-d', '/tmp', 'claude'], expect.objectContaining({ detached: true, stdio: 'ignore', shell: true }));
|
|
161
|
+
});
|
|
162
|
+
});
|
|
163
|
+
describe('error handling', () => {
|
|
164
|
+
it('should handle spawn ENOENT gracefully', async () => {
|
|
165
|
+
mockSpawn.mockImplementation(() => {
|
|
166
|
+
const proc = createFakeProcess(undefined);
|
|
167
|
+
// Simulate ENOENT firing before the 100ms success timeout
|
|
168
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
169
|
+
proc.on.mockImplementation((event, cb) => {
|
|
170
|
+
if (event === 'error') {
|
|
171
|
+
setTimeout(() => cb(new Error('spawn kitty ENOENT')), 10);
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
return proc;
|
|
175
|
+
});
|
|
176
|
+
const result = await launchTerminalSession({
|
|
177
|
+
cwd: '/tmp',
|
|
178
|
+
preferredTerminal: 'kitty',
|
|
179
|
+
});
|
|
180
|
+
expect(result.method).toBe('kitty');
|
|
181
|
+
expect(result.success).toBe(false);
|
|
182
|
+
expect(result.error).toContain('ENOENT');
|
|
183
|
+
});
|
|
184
|
+
it('should handle AppleScript rejection gracefully', async () => {
|
|
185
|
+
mockRunAppleScript.mockRejectedValue(new Error('execution error: iTerm2 got an error'));
|
|
186
|
+
const result = await launchTerminalSession({
|
|
187
|
+
cwd: '/tmp',
|
|
188
|
+
preferredTerminal: 'iterm',
|
|
189
|
+
});
|
|
190
|
+
expect(result.method).toBe('iterm');
|
|
191
|
+
expect(result.success).toBe(false);
|
|
192
|
+
expect(result.error).toContain('execution error');
|
|
193
|
+
});
|
|
194
|
+
it('should return error when AppleScript not available', async () => {
|
|
195
|
+
mockIsAppleScriptAvailable.mockReturnValue(false);
|
|
196
|
+
const result = await launchTerminalSession({
|
|
197
|
+
cwd: '/tmp',
|
|
198
|
+
preferredTerminal: 'iterm',
|
|
199
|
+
});
|
|
200
|
+
expect(result.method).toBe('iterm');
|
|
201
|
+
expect(result.success).toBe(false);
|
|
202
|
+
expect(result.error).toContain('AppleScript not available');
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
// Auto-detection uses real detection logic, but launch is mocked
|
|
206
|
+
describe('auto-detection', () => {
|
|
207
|
+
it('should auto-detect a terminal and attempt launch', async () => {
|
|
208
|
+
if (process.platform === 'linux') {
|
|
209
|
+
// CI runners may not have any supported terminal emulator installed
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const result = await launchTerminalSession({ cwd: '/tmp' });
|
|
213
|
+
expect(result.method).not.toBe('unsupported');
|
|
214
|
+
expect(typeof result.success).toBe('boolean');
|
|
215
|
+
// Verify that either runAppleScript or spawn was called (not nothing)
|
|
216
|
+
const applescriptCalled = mockRunAppleScript.mock.calls.length > 0;
|
|
217
|
+
const spawnCalled = mockSpawn.mock.calls.length > 0;
|
|
218
|
+
expect(applescriptCalled || spawnCalled).toBe(true);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
//# sourceMappingURL=terminal-launcher.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal-launcher.test.js","sourceRoot":"","sources":["../src/terminal-launcher.test.ts"],"names":[],"mappings":"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"}
|