Added windowsShell parameter to buildAgentDraftLaunchPlan so the post-exit clear-var uses Remove-Item Env: on PowerShell/pwsh and set "FOO=" on cmd.exe; threaded settings.terminalWindowsShell through both call sites.
### Findings addressed
- ✅ **[high]** `src/renderer/src/lib/tui-agent-startup.ts:160-163` — Windows clear-var command only works in cmd.exe, breaks in PowerShell
Rebased onto current main; added settings?.terminalWindowsShell to the useCallback dep array in useComposerState to satisfy react-hooks/exhaustive-deps.
Co-authored-by: orca-bot <bot@stably.ai>
This commit is contained in:
parent
337ae272b8
commit
e6e45dc22a
|
|
@ -1496,7 +1496,8 @@ export function useComposerState(options: UseComposerStateOptions): UseComposerS
|
|||
agent,
|
||||
draft: quickDraftPrompt,
|
||||
cmdOverrides: settings?.agentCmdOverrides ?? {},
|
||||
platform: CLIENT_PLATFORM
|
||||
platform: CLIENT_PLATFORM,
|
||||
windowsShell: settings?.terminalWindowsShell
|
||||
})
|
||||
|
||||
let startupPlan: ReturnType<typeof buildAgentStartupPlan> = null
|
||||
|
|
@ -1589,6 +1590,7 @@ export function useComposerState(options: UseComposerStateOptions): UseComposerS
|
|||
resolvedSetupDecision,
|
||||
selectedRepo,
|
||||
settings?.agentCmdOverrides,
|
||||
settings?.terminalWindowsShell,
|
||||
settings?.rightSidebarOpenByDefault,
|
||||
setRightSidebarOpen,
|
||||
setRightSidebarTab,
|
||||
|
|
|
|||
|
|
@ -286,7 +286,8 @@ export async function launchWorkItemDirect(args: LaunchWorkItemDirectArgs): Prom
|
|||
agent: effectiveAgent,
|
||||
draft: draftContent,
|
||||
cmdOverrides: settings?.agentCmdOverrides ?? {},
|
||||
platform: CLIENT_PLATFORM
|
||||
platform: CLIENT_PLATFORM,
|
||||
windowsShell: settings?.terminalWindowsShell
|
||||
})
|
||||
if (draftLaunchPlan) {
|
||||
startupPlan = {
|
||||
|
|
|
|||
|
|
@ -194,6 +194,60 @@ describe('buildAgentDraftLaunchPlan', () => {
|
|||
})
|
||||
})
|
||||
|
||||
it('uses cmd.exe syntax to clear the pi prefill var when Windows shell is cmd', () => {
|
||||
expect(
|
||||
buildAgentDraftLaunchPlan({
|
||||
agent: 'pi',
|
||||
draft: 'https://github.com/acme/repo/issues/42',
|
||||
cmdOverrides: {},
|
||||
platform: 'win32',
|
||||
windowsShell: 'cmd.exe'
|
||||
})
|
||||
).toEqual({
|
||||
agent: 'pi',
|
||||
launchCommand: 'pi; set "ORCA_PI_PREFILL="',
|
||||
expectedProcess: 'pi',
|
||||
env: { ORCA_PI_PREFILL: 'https://github.com/acme/repo/issues/42' }
|
||||
})
|
||||
})
|
||||
|
||||
it('uses Remove-Item Env: to clear the pi prefill var on PowerShell', () => {
|
||||
// Why: `set "FOO="` is cmd-only; PowerShell parses it as the Set-Variable
|
||||
// alias and never clears the env var, so re-running pi re-prefills with
|
||||
// the stale URL. Use the portable PowerShell form instead.
|
||||
expect(
|
||||
buildAgentDraftLaunchPlan({
|
||||
agent: 'pi',
|
||||
draft: 'https://github.com/acme/repo/issues/42',
|
||||
cmdOverrides: {},
|
||||
platform: 'win32',
|
||||
windowsShell: 'powershell.exe'
|
||||
})
|
||||
).toEqual({
|
||||
agent: 'pi',
|
||||
launchCommand: 'pi; Remove-Item Env:ORCA_PI_PREFILL -ErrorAction SilentlyContinue',
|
||||
expectedProcess: 'pi',
|
||||
env: { ORCA_PI_PREFILL: 'https://github.com/acme/repo/issues/42' }
|
||||
})
|
||||
})
|
||||
|
||||
it('treats pwsh.exe as PowerShell for the prefill clear-var', () => {
|
||||
expect(
|
||||
buildAgentDraftLaunchPlan({
|
||||
agent: 'pi',
|
||||
draft: 'https://github.com/acme/repo/issues/42',
|
||||
cmdOverrides: {},
|
||||
platform: 'win32',
|
||||
windowsShell: 'pwsh.exe'
|
||||
})
|
||||
).toEqual({
|
||||
agent: 'pi',
|
||||
launchCommand: 'pi; Remove-Item Env:ORCA_PI_PREFILL -ErrorAction SilentlyContinue',
|
||||
expectedProcess: 'pi',
|
||||
env: { ORCA_PI_PREFILL: 'https://github.com/acme/repo/issues/42' }
|
||||
})
|
||||
})
|
||||
|
||||
it('returns null for an empty draft so callers fall back cleanly', () => {
|
||||
expect(
|
||||
buildAgentDraftLaunchPlan({
|
||||
|
|
|
|||
|
|
@ -23,6 +23,14 @@ export type AgentStartupPlan = {
|
|||
env?: Record<string, string>
|
||||
}
|
||||
|
||||
function isPowerShellLike(shell: string | undefined): boolean {
|
||||
if (!shell) {
|
||||
return false
|
||||
}
|
||||
const normalized = shell.toLowerCase().replace(/\\/g, '/').split('/').pop() ?? ''
|
||||
return normalized === 'powershell.exe' || normalized === 'pwsh.exe' || normalized === 'pwsh'
|
||||
}
|
||||
|
||||
function quoteStartupArg(value: string, platform: NodeJS.Platform): string {
|
||||
if (platform === 'win32') {
|
||||
return `"${value.replace(/"/g, '""')}"`
|
||||
|
|
@ -133,8 +141,15 @@ export function buildAgentDraftLaunchPlan(args: {
|
|||
draft: string
|
||||
cmdOverrides: Partial<Record<TuiAgent, string>>
|
||||
platform: NodeJS.Platform
|
||||
/** Why: the post-exit clear-var command differs per Windows shell. cmd.exe
|
||||
* uses `set "FOO="`, but PowerShell parses that as the `Set-Variable`
|
||||
* alias and never clears the env var — so re-running the agent re-prefills
|
||||
* with the stale URL. Callers on Windows pass the configured shell
|
||||
* (`terminalWindowsShell`) so we can emit `Remove-Item Env:FOO` for
|
||||
* PowerShell/pwsh. POSIX platforms ignore this. */
|
||||
windowsShell?: string
|
||||
}): AgentDraftLaunchPlan | null {
|
||||
const { agent, draft, cmdOverrides, platform } = args
|
||||
const { agent, draft, cmdOverrides, platform, windowsShell } = args
|
||||
const config = TUI_AGENT_CONFIG[agent]
|
||||
const trimmed = draft.trim()
|
||||
if (!trimmed) {
|
||||
|
|
@ -158,7 +173,9 @@ export function buildAgentDraftLaunchPlan(args: {
|
|||
// terminal would inherit the stale value and re-prefill with the old URL.
|
||||
const clearVar =
|
||||
platform === 'win32'
|
||||
? `set "${config.draftPromptEnvVar}="`
|
||||
? isPowerShellLike(windowsShell)
|
||||
? `Remove-Item Env:${config.draftPromptEnvVar} -ErrorAction SilentlyContinue`
|
||||
: `set "${config.draftPromptEnvVar}="`
|
||||
: `unset ${config.draftPromptEnvVar}`
|
||||
return {
|
||||
agent,
|
||||
|
|
|
|||
Loading…
Reference in New Issue