Files
automaker/libs/platform/tests/rc-generator.test.ts
Dhanush Santosh 88864ad6bc feature/custom terminal configs (#717)
* feat(terminal): Add core infrastructure for custom terminal configurations

- Add TerminalConfig types to settings schema (global & project-specific)
- Create RC generator with hex-to-xterm-256 color mapping
- Create RC file manager for .automaker/terminal/ directory
- Add terminal theme color data (40 themes) to platform package
- Integrate terminal config injection into TerminalService
- Support bash, zsh, and sh with proper env var injection (BASH_ENV, ZDOTDIR, ENV)
- Add onThemeChange hook for theme synchronization

Part of custom terminal configurations feature implementation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(terminal): Wire terminal service with settings service

- Pass SettingsService to TerminalService constructor
- Initialize terminal service with settings service dependency
- Enable terminal config injection to work with actual settings

This completes Steps 1-4 of the terminal configuration plan:
- RC Generator (color mapping, prompt formats)
- RC File Manager (file I/O, atomic writes)
- Settings Schema (GlobalSettings + ProjectSettings)
- Terminal Service Integration (env var injection)

Next steps: Settings UI and theme change hooks.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* feat(terminal): Add Settings UI and theme change synchronization

Complete Steps 5 & 6 of terminal configuration implementation:

Settings UI Components:
- Add PromptPreview component with live theme-aware rendering
- Add TerminalConfigSection with comprehensive controls:
  * Enable/disable toggle with confirmation dialog
  * Custom prompt toggle
  * Prompt format selector (4 formats)
  * Git branch/status toggles
  * Custom aliases textarea
  * Custom env vars key-value editor with validation
  * Info box explaining behavior
- Integrate into existing TerminalSection

Theme Change Hook:
- Add theme detection in update-global settings route
- Regenerate RC files for all projects when theme changes
- Skip projects with terminal config disabled
- Error handling with per-project logging
- Inject terminal service with settings service dependency

This completes the full terminal configuration feature:
✓ RC Generator (color mapping, prompts)
✓ RC File Manager (file I/O, versioning)
✓ Settings Schema (types, defaults)
✓ Terminal Service Integration (env vars, PTY spawn)
✓ Settings UI (comprehensive controls, preview)
✓ Theme Synchronization (automatic RC regeneration)

New terminals will use custom prompts matching app theme.
Existing terminals unaffected. User RC files preserved.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(terminal): Add error handling and explicit field mapping for terminal config

- Add try-catch block to handleToggleEnabled
- Explicitly set all required terminalConfig fields
- Add console logging for debugging
- Show error toast if update fails
- Include rcFileVersion: 1 in config object

This should fix the issue where the toggle doesn't enable after
clicking OK in the confirmation dialog.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(terminal): Use React Query mutation hook for settings updates

The issue was that `updateGlobalSettings` doesn't exist in the app store.
The correct pattern is to use the `useUpdateGlobalSettings` hook from
use-settings-mutations.ts, which is a React Query mutation.

Changes:
- Import useUpdateGlobalSettings from mutations hook
- Use mutation.mutate() instead of direct function call
- Add proper onSuccess/onError callbacks
- Remove async/await pattern (React Query handles this)

This fixes the toggle not enabling after clicking OK in the confirmation dialog.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* fix(terminal): Use React Query hook for globalSettings instead of store

The root cause: Component was reading globalSettings from the app store,
which doesn't update reactively when the mutation completes.

Solution: Use useGlobalSettings() React Query hook which:
- Automatically refetches when the mutation invalidates the cache
- Triggers re-render with updated data
- Makes the toggle reflect the new state

Now the flow is:
1. User clicks toggle → confirmation dialog
2. Click OK → mutation.mutate() called
3. Mutation succeeds → invalidates queryKeys.settings.global()
4. Query refetches → component re-renders with new globalSettings
5. Toggle shows enabled state ✓

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* debug(terminal): Add detailed logging for terminal config application

Add logging to track:
- When terminal config check happens
- CWD being used
- Global and project enabled states
- Effective enabled state

This will help diagnose why RC files aren't being generated
when opening terminals in Automaker.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

* Fix terminal rc updates and bash rcfile loading

* feat(terminal): add banner on shell start

* feat(terminal): colorize banner per theme

* chore(terminal): bump rc version for banner colors

* feat(terminal): match banner colors to launcher

* feat(terminal): add prompt customization controls

* feat: integrate oh-my-posh prompt themes

* fix: resolve oh-my-posh theme path

* fix: correct oh-my-posh config invocation

* docs: add terminal theme screenshot

* fix: address review feedback and stabilize e2e test

* ui: split terminal config into separate card

* fix: enable cross-platform Warp terminal detection

- Remove macOS-only platform restriction for Warp
- Add Linux CLI alias 'warp-terminal' (primary on Linux)
- Add CLI launch handler using --cwd flag
- Fixes issue where Warp was not detected on Linux systems

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-02-03 20:34:33 +05:30

56 lines
2.1 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import { generateCommonFunctions, generateThemeColors } from '../src/rc-generator';
import { terminalThemeColors } from '../src/terminal-theme-colors';
import type { TerminalConfig } from '../src/rc-generator';
import type { ThemeMode } from '@automaker/types';
describe('rc-generator.ts', () => {
const THEME_DARK = 'dark' as ThemeMode;
const PROMPT_FORMAT_STANDARD: TerminalConfig['promptFormat'] = 'standard';
const EMPTY_ALIASES = '';
const EMPTY_ENV_VARS = {};
const PATH_STYLE_FULL: TerminalConfig['pathStyle'] = 'full';
const PATH_DEPTH_DEFAULT = 0;
const EXPECTED_BANNER_FUNCTION = 'automaker_show_banner_once';
const RAW_COLOR_PREFIX = 'export COLOR_USER_RAW=';
const RAW_COLOR_ESCAPE_START = '\\\\[';
const RAW_COLOR_ESCAPE_END = '\\\\]';
const STARTUP_PRIMARY_COLOR = '38;5;51m';
const STARTUP_SECONDARY_COLOR = '38;5;39m';
const STARTUP_ACCENT_COLOR = '38;5;33m';
const baseConfig: TerminalConfig = {
enabled: true,
customPrompt: true,
promptFormat: PROMPT_FORMAT_STANDARD,
showGitBranch: true,
showGitStatus: true,
showUserHost: true,
showPath: true,
pathStyle: PATH_STYLE_FULL,
pathDepth: PATH_DEPTH_DEFAULT,
showTime: false,
showExitStatus: false,
customAliases: EMPTY_ALIASES,
customEnvVars: EMPTY_ENV_VARS,
};
it('includes banner functions in common shell script', () => {
const output = generateCommonFunctions(baseConfig);
expect(output).toContain(EXPECTED_BANNER_FUNCTION);
expect(output).toContain(STARTUP_PRIMARY_COLOR);
expect(output).toContain(STARTUP_SECONDARY_COLOR);
expect(output).toContain(STARTUP_ACCENT_COLOR);
});
it('exports raw banner colors without prompt escape wrappers', () => {
const output = generateThemeColors(terminalThemeColors[THEME_DARK]);
const rawLine = output.split('\n').find((line) => line.startsWith(RAW_COLOR_PREFIX));
expect(rawLine).toBeDefined();
expect(rawLine).not.toContain(RAW_COLOR_ESCAPE_START);
expect(rawLine).not.toContain(RAW_COLOR_ESCAPE_END);
});
});