mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 08:53:36 +00:00
* feat(platform): add cross-platform openInTerminal utility
Add utility function to open a terminal in a specified directory:
- macOS: Uses Terminal.app via AppleScript
- Windows: Tries Windows Terminal, falls back to cmd
- Linux: Tries common terminal emulators (gnome-terminal,
konsole, xfce4-terminal, xterm, x-terminal-emulator)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat(server): add open-in-terminal endpoint
Add POST /open-in-terminal endpoint to open a system terminal in the
worktree directory using the cross-platform openInTerminal utility.
The endpoint validates that worktreePath is provided and is an
absolute path for security.
Extracted from PR #558.
* feat(ui): add Open in Terminal action to worktree dropdown
Add "Open in Terminal" option to the worktree actions dropdown menu.
This opens the system terminal in the worktree directory.
Changes:
- Add openInTerminal method to http-api-client
- Add Terminal icon and menu item to worktree-actions-dropdown
- Add onOpenInTerminal prop to WorktreeTab component
- Add handleOpenInTerminal handler to use-worktree-actions hook
- Wire up handler in worktree-panel for both mobile and desktop views
Extracted from PR #558.
* fix(ui): open in terminal navigates to Automaker terminal view
Instead of opening the system terminal, the "Open in Terminal" action
now opens Automaker's built-in terminal with the worktree directory:
- Add pendingTerminalCwd state to app store
- Update use-worktree-actions to set pending cwd and navigate to /terminal
- Add effect in terminal-view to create session with pending cwd
This matches the original PR #558 behavior.
* feat(ui): add terminal open mode setting (new tab vs split)
Add a setting to choose how "Open in Terminal" behaves:
- New Tab: Creates a new tab named after the branch (default)
- Split: Adds to current tab as a split view
Changes:
- Add openTerminalMode setting to terminal state ('newTab' | 'split')
- Update terminal-view to respect the setting
- Add UI in Terminal Settings to toggle the behavior
- Rename pendingTerminalCwd to pendingTerminal with branch name
The new tab mode names tabs after the branch for easy identification.
The split mode is useful for comparing terminals side by side.
* feat(ui): display branch name in terminal header with git icon
- Move branch name display from tab name to terminal header
- Show full branch name (no truncation) with GitBranch icon
- Display branch name for both 'new tab' and 'split' modes
- Persist openTerminalMode setting to server and include in import/export
- Update settings dropdown to simplified "New Tab" label
* feat: add external terminal support with cross-platform detection
Add support for opening worktree directories in external terminals
(iTerm2, Warp, Ghostty, System Terminal, etc.) while retaining the
integrated terminal as the default option.
Changes:
- Add terminal detection for macOS, Windows, and Linux
- Add "Open in Terminal" split-button in worktree dropdown
- Add external terminal selection in Settings > Terminal
- Add default open mode setting (new tab vs split)
- Display branch name in terminal panel header
- Support 20+ terminals across platforms
Part of #558, Closes #550
* fix: address PR review comments
- Add nonce parameter to terminal navigation to allow reopening same
worktree multiple times
- Fix shell path escaping in editor.ts using single-quote wrapper
- Add validatePathParams middleware to open-in-external-terminal route
- Remove redundant validation block from createOpenInExternalTerminalHandler
- Remove unused pendingTerminal state and setPendingTerminal action
- Remove unused getTerminalInfo function from editor.ts
* fix: address PR review security and validation issues
- Add runtime type check for worktreePath in open-in-terminal handler
- Fix Windows Terminal detection using commandExists before spawn
- Fix xterm shell injection by using sh -c with escapeShellArg
- Use loose equality for null/undefined in useEffectiveDefaultTerminal
- Consolidate duplicate imports from open-in-terminal.js
* chore: update package-lock.json
* fix: use response.json() to prevent disposal race condition in E2E test
Replace response.body() with response.json() in open-existing-project.spec.ts
to fix the "Response has been disposed" error. This matches the pattern used
in other test files.
* Revert "fix: use response.json() to prevent disposal race condition in E2E test"
This reverts commit 36bdf8c24a.
* fix: address PR review feedback for terminal feature
- Add explicit validation for worktreePath in createOpenInExternalTerminalHandler
- Add aria-label to refresh button in terminal settings for accessibility
- Only show "no terminals" message when not refreshing
- Reset initialCwdHandledRef on failure to allow retries
- Use z.coerce.number() for nonce URL param to handle string coercion
- Preserve branchName when creating layout for empty tab
- Update getDefaultTerminal return type to allow null result
---------
Co-authored-by: Kacper <kacperlachowiczwp.pl@wp.pl>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
189 lines
4.1 KiB
TypeScript
189 lines
4.1 KiB
TypeScript
/**
|
|
* @automaker/platform
|
|
* Platform-specific utilities for AutoMaker
|
|
*/
|
|
|
|
// Path utilities
|
|
export {
|
|
getAutomakerDir,
|
|
getFeaturesDir,
|
|
getFeatureDir,
|
|
getFeatureImagesDir,
|
|
getBoardDir,
|
|
getImagesDir,
|
|
getContextDir,
|
|
getWorktreesDir,
|
|
getValidationsDir,
|
|
getValidationDir,
|
|
getValidationPath,
|
|
getAppSpecPath,
|
|
getBranchTrackingPath,
|
|
getExecutionStatePath,
|
|
getNotificationsPath,
|
|
// Event history paths
|
|
getEventHistoryDir,
|
|
getEventHistoryIndexPath,
|
|
getEventPath,
|
|
ensureEventHistoryDir,
|
|
ensureAutomakerDir,
|
|
getGlobalSettingsPath,
|
|
getCredentialsPath,
|
|
getProjectSettingsPath,
|
|
ensureDataDir,
|
|
// Ideation paths
|
|
getIdeationDir,
|
|
getIdeasDir,
|
|
getIdeaDir,
|
|
getIdeaPath,
|
|
getIdeaAttachmentsDir,
|
|
getIdeationSessionsDir,
|
|
getIdeationSessionPath,
|
|
getIdeationDraftsDir,
|
|
getIdeationAnalysisPath,
|
|
ensureIdeationDir,
|
|
} from './paths.js';
|
|
|
|
// Subprocess management
|
|
export {
|
|
spawnJSONLProcess,
|
|
spawnProcess,
|
|
type SubprocessOptions,
|
|
type SubprocessResult,
|
|
} from './subprocess.js';
|
|
|
|
// Security
|
|
export {
|
|
PathNotAllowedError,
|
|
initAllowedPaths,
|
|
isPathAllowed,
|
|
validatePath,
|
|
isPathWithinDirectory,
|
|
getAllowedRootDirectory,
|
|
getDataDirectory,
|
|
getAllowedPaths,
|
|
} from './security.js';
|
|
|
|
// Secure file system (validates paths before I/O operations)
|
|
export * as secureFs from './secure-fs.js';
|
|
|
|
// Node.js executable finder (cross-platform)
|
|
export {
|
|
findNodeExecutable,
|
|
buildEnhancedPath,
|
|
type NodeFinderResult,
|
|
type NodeFinderOptions,
|
|
} from './node-finder.js';
|
|
|
|
// WSL (Windows Subsystem for Linux) utilities
|
|
export {
|
|
isWslAvailable,
|
|
clearWslCache,
|
|
getDefaultWslDistribution,
|
|
getWslDistributions,
|
|
findCliInWsl,
|
|
execInWsl,
|
|
createWslCommand,
|
|
windowsToWslPath,
|
|
wslToWindowsPath,
|
|
type WslCliResult,
|
|
type WslOptions,
|
|
} from './wsl.js';
|
|
|
|
// System paths for tool detection (GitHub CLI, Claude CLI, Node.js, etc.)
|
|
export * as systemPaths from './system-paths.js';
|
|
export {
|
|
// CLI tool paths
|
|
getGitHubCliPaths,
|
|
getClaudeCliPaths,
|
|
getClaudeConfigDir,
|
|
getClaudeCredentialPaths,
|
|
getClaudeSettingsPath,
|
|
getClaudeStatsCachePath,
|
|
getClaudeProjectsDir,
|
|
getCodexCliPaths,
|
|
getCodexConfigDir,
|
|
getCodexAuthPath,
|
|
getGitBashPaths,
|
|
getOpenCodeCliPaths,
|
|
getOpenCodeConfigDir,
|
|
getOpenCodeAuthPath,
|
|
getShellPaths,
|
|
getExtendedPath,
|
|
// Node.js paths
|
|
getNvmPaths,
|
|
getFnmPaths,
|
|
getNodeSystemPaths,
|
|
getScoopNodePath,
|
|
getChocolateyNodePath,
|
|
getWslVersionPath,
|
|
// System path operations
|
|
systemPathExists,
|
|
systemPathAccess,
|
|
systemPathIsExecutable,
|
|
systemPathReadFile,
|
|
systemPathReadFileSync,
|
|
systemPathWriteFileSync,
|
|
systemPathReaddir,
|
|
systemPathReaddirSync,
|
|
systemPathStatSync,
|
|
systemPathStat,
|
|
isAllowedSystemPath,
|
|
// High-level methods
|
|
findFirstExistingPath,
|
|
findGitHubCliPath,
|
|
findClaudeCliPath,
|
|
getClaudeAuthIndicators,
|
|
type ClaudeAuthIndicators,
|
|
findCodexCliPath,
|
|
getCodexAuthIndicators,
|
|
type CodexAuthIndicators,
|
|
findGitBashPath,
|
|
findOpenCodeCliPath,
|
|
getOpenCodeAuthIndicators,
|
|
type OpenCodeAuthIndicators,
|
|
// Electron userData operations
|
|
setElectronUserDataPath,
|
|
getElectronUserDataPath,
|
|
isElectronUserDataPath,
|
|
electronUserDataReadFileSync,
|
|
electronUserDataWriteFileSync,
|
|
electronUserDataExists,
|
|
// Script directory operations
|
|
setScriptBaseDir,
|
|
getScriptBaseDir,
|
|
scriptDirExists,
|
|
scriptDirMkdirSync,
|
|
scriptDirCreateWriteStream,
|
|
// Electron app bundle operations
|
|
setElectronAppPaths,
|
|
electronAppExists,
|
|
electronAppReadFileSync,
|
|
electronAppStatSync,
|
|
electronAppStat,
|
|
electronAppReadFile,
|
|
} from './system-paths.js';
|
|
|
|
// Port configuration
|
|
export { STATIC_PORT, SERVER_PORT, RESERVED_PORTS } from './config/ports.js';
|
|
|
|
// Editor detection and launching (cross-platform)
|
|
export {
|
|
commandExists,
|
|
clearEditorCache,
|
|
detectAllEditors,
|
|
detectDefaultEditor,
|
|
findEditorByCommand,
|
|
openInEditor,
|
|
openInFileManager,
|
|
openInTerminal,
|
|
} from './editor.js';
|
|
|
|
// External terminal detection and launching
|
|
export {
|
|
clearTerminalCache,
|
|
detectAllTerminals,
|
|
detectDefaultTerminal,
|
|
findTerminalById,
|
|
openInExternalTerminal,
|
|
} from './terminal.js';
|