Files
automaker/libs/types
Stefan de Vogelaere a52c0461e5 feat: add external terminal support with cross-platform detection (#565)
* 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>
2026-01-19 10:22:26 +01:00
..

@automaker/types

Shared TypeScript type definitions for AutoMaker.

Overview

This package contains all core type definitions used across AutoMaker's server and UI components. It has no dependencies and serves as the foundation for other packages.

Installation

npm install @automaker/types

Exports

Provider Types

Types for AI provider integration and Claude SDK.

import type {
  ProviderConfig,
  ConversationMessage,
  ExecuteOptions,
  ContentBlock,
  ProviderMessage,
  InstallationStatus,
  ValidationResult,
  ModelDefinition,
} from '@automaker/types';

Feature Types

Feature management and workflow types.

import type { Feature, FeatureStatus, PlanningMode, PlanSpec } from '@automaker/types';

Feature Interface:

  • id - Unique feature identifier
  • category - Feature category/type
  • description - Feature description
  • dependencies - Array of feature IDs this depends on
  • status - Current status (pending/running/completed/failed/verified)
  • planningMode - Planning approach (skip/lite/spec/full)
  • planSpec - Plan specification and approval status

Session Types

Agent session management.

import type {
  AgentSession,
  SessionListItem,
  CreateSessionParams,
  UpdateSessionParams,
} from '@automaker/types';

Error Types

Error classification and handling.

import type { ErrorType, ErrorInfo } from '@automaker/types';

Image Types

Image handling for prompts.

import type { ImageData, ImageContentBlock } from '@automaker/types';

Model Types

Claude model definitions and mappings.

import { CLAUDE_MODEL_MAP, DEFAULT_MODELS, type ModelAlias } from '@automaker/types';

Usage Example

import type { Feature, ExecuteOptions } from '@automaker/types';

const feature: Feature = {
  id: 'auth-feature',
  category: 'backend',
  description: 'Implement user authentication',
  dependencies: ['database-setup'],
  status: 'pending',
  planningMode: 'spec',
};

const options: ExecuteOptions = {
  model: 'claude-sonnet-4-20250514',
  temperature: 0.7,
};

Dependencies

None - this is a pure types package.

IMPORTANT: This package must NEVER depend on other @automaker/* packages to prevent circular dependencies. All other packages depend on this one, making it the foundation of the dependency tree.

Used By

  • @automaker/utils
  • @automaker/platform
  • @automaker/model-resolver
  • @automaker/dependency-resolver
  • @automaker/git-utils
  • @automaker/server
  • @automaker/ui

Circular Dependency Prevention

To maintain the package dependency hierarchy and prevent circular dependencies:

  1. Never add dependencies to other @automaker/* packages in package.json
  2. Keep result types here - For example, DependencyResolutionResult should stay in @automaker/dependency-resolver, not be moved here
  3. Import only base types - Other packages can import from here, but this package cannot import from them
  4. Document the rule - When adding new functionality, ensure it follows this constraint

This constraint ensures a clean one-way dependency flow:

@automaker/types (foundation - no dependencies)
    ↓
@automaker/utils, @automaker/platform, etc.
    ↓
@automaker/server, @automaker/ui