diff --git a/src/main/hooks.test.ts b/src/main/hooks.test.ts index 3b63b6d8a76..5e9269075a8 100644 --- a/src/main/hooks.test.ts +++ b/src/main/hooks.test.ts @@ -882,7 +882,10 @@ describe('shouldRunSetupForCreate', () => { }) describe('getDefaultTabsLaunch', () => { - const makeRepo = (setupRunPolicy?: 'ask' | 'run-by-default' | 'skip-by-default') => + const makeRepo = ( + setupRunPolicy?: 'ask' | 'run-by-default' | 'skip-by-default', + commandSourcePolicy?: 'local-only' | 'run-both' | 'shared-only' + ) => ({ id: 'test-id', path: '/test/repo', @@ -892,6 +895,7 @@ describe('getDefaultTabsLaunch', () => { hookSettings: { mode: 'auto', setupRunPolicy, + commandSourcePolicy, scripts: { setup: '', archive: '' } } }) as unknown as Repo @@ -923,4 +927,16 @@ describe('getDefaultTabsLaunch', () => { runCommands: false }) }) + + it('does not run shared default tab commands when command source is local-only', () => { + const hooks = { + scripts: {}, + defaultTabs: [{ title: 'Server', command: 'pnpm dev' }] + } + + expect(getDefaultTabsLaunch(hooks, makeRepo('run-by-default', 'local-only'))).toEqual({ + tabs: hooks.defaultTabs, + runCommands: false + }) + }) }) diff --git a/src/main/hooks.ts b/src/main/hooks.ts index 8fcead5cba2..b63c3fc934b 100644 --- a/src/main/hooks.ts +++ b/src/main/hooks.ts @@ -357,7 +357,17 @@ export function getDefaultTabsLaunch( return undefined } const hasCommands = tabs.some((tab) => Boolean(tab.command?.trim())) - const runCommands = hasCommands ? shouldRunSetupForCreate(repo, decision) : false + const sharedCommandPolicy = resolveHookCommandSourcePolicy( + repo.hookSettings?.commandSourcePolicy, + { + hasLocalScript: Boolean(repo.hookSettings?.scripts.setup?.trim()) + } + ) + // Why: default tab commands come from committed `orca.yaml`; a repo set to + // local-only may still use shared titles/colors, but must not execute them. + const canRunSharedCommands = sharedCommandPolicy !== 'local-only' + const runCommands = + hasCommands && canRunSharedCommands ? shouldRunSetupForCreate(repo, decision) : false return { tabs, runCommands } } diff --git a/src/renderer/src/components/NewWorkspaceComposerCard.tsx b/src/renderer/src/components/NewWorkspaceComposerCard.tsx index b7546889ba8..55a25518502 100644 --- a/src/renderer/src/components/NewWorkspaceComposerCard.tsx +++ b/src/renderer/src/components/NewWorkspaceComposerCard.tsx @@ -267,6 +267,31 @@ export default function NewWorkspaceComposerCard({ selectedRepoSshStatus === 'disconnected' || selectedRepoSshStatus === null ? 'Connect' : 'Reconnect' + const setupConfigLabel = + setupConfig?.kind === 'default-tabs' + ? 'Default tab commands' + : setupConfig?.kind === 'setup-and-default-tabs' + ? 'Setup and default tab commands' + : 'Setup script' + const setupRunLabel = + setupConfig?.kind === 'default-tabs' + ? 'Run default tab commands' + : setupConfig?.kind === 'setup-and-default-tabs' + ? 'Run setup and default tab commands' + : 'Run setup command' + const setupAskLabel = + setupConfig?.kind === 'default-tabs' + ? 'Run default tab commands now?' + : setupConfig?.kind === 'setup-and-default-tabs' + ? 'Run setup and default tab commands now?' + : 'Run setup now?' + const setupRunButtonLabel = + setupConfig?.kind === 'default-tabs' + ? 'Run commands now' + : setupConfig?.kind === 'setup-and-default-tabs' + ? 'Run commands now' + : 'Run setup now' + const setupSkipButtonLabel = setupConfig?.kind === 'setup' ? 'Skip for now' : 'Skip commands' const handleSetDefaultAgent = React.useCallback( (next: TuiAgent | 'blank' | null) => { @@ -558,7 +583,7 @@ export default function NewWorkspaceComposerCard({