chore(ipc): remove unreachable hooks:createIssueCommandRunner IPC (#32953)

Co-authored-by: OrcaWin <293788423+OrcaWin@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
OrcaWin
2026-10-23 17:50:37 -07:00
committed by GitHub
co-authored by OrcaWin Claude
parent 019dc054b7
commit f5f7f172a8
13 changed files with 2 additions and 331 deletions
-90
View File
@@ -3,7 +3,6 @@ import type * as GitRunner from './git/runner'
import { join } from 'node:path'
import { describe, expect, it, vi } from 'vitest'
import {
makeHookTestRepo,
TEST_GITIGNORE_PATH,
TEST_ISSUE_COMMAND_PATH,
TEST_REPO_ORCA_YAML_PATH,
@@ -143,92 +142,3 @@ describe('writeIssueCommand', () => {
})
})
})
describe('createIssueCommandRunnerScript', () => {
const makeRepo = () => makeHookTestRepo({ mode: 'auto', scripts: { setup: '', archive: '' } })
it('writes a POSIX issue-command runner when a shebang declares bash and setup resolves to Git Bash', async () => {
gitExecFileSyncMock.mockReset()
gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.sh\n')
const fs = await import('node:fs')
const writeFileSyncMock = vi.mocked(fs.writeFileSync)
writeFileSyncMock.mockClear()
const originalPlatform = process.platform
Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' })
try {
const { createIssueCommandRunnerScript } = await import('./worktree-runner-script')
const result = createIssueCommandRunnerScript(
makeRepo(),
'C:\\repo-worktree',
'#!/usr/bin/env bash\ngh issue view 42',
undefined,
{ family: 'posix' }
)
expect(gitExecFileSyncMock).toHaveBeenCalledWith(
['rev-parse', '--git-path', 'orca/issue-command-runner.sh'],
{ cwd: 'C:\\repo-worktree' }
)
expect(writeFileSyncMock).toHaveBeenCalledWith(
'C:\\repo\\.git\\orca\\issue-command-runner.sh',
'#!/usr/bin/env bash\nset -e\ngh issue view 42\n',
'utf-8'
)
expect(result.shell).toEqual({ family: 'posix' })
} finally {
Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform })
}
})
it('keeps a plain issue command on the cmd runner under a Git Bash terminal', async () => {
gitExecFileSyncMock.mockReset()
gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.cmd\n')
const originalPlatform = process.platform
Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' })
try {
const { createIssueCommandRunnerScript } = await import('./worktree-runner-script')
const result = createIssueCommandRunnerScript(
makeRepo(),
'C:\\repo-worktree',
'gh issue view 42',
undefined,
{ family: 'posix' }
)
expect(gitExecFileSyncMock).toHaveBeenCalledWith(
['rev-parse', '--git-path', 'orca/issue-command-runner.cmd'],
{ cwd: 'C:\\repo-worktree' }
)
// The pane remains Git Bash even when it launches a batch runner.
expect(result.shell).toEqual({ family: 'posix' })
} finally {
Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform })
}
})
it('keeps the cmd issue-command runner when no setup shell is resolved', async () => {
gitExecFileSyncMock.mockReset()
gitExecFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.cmd\n')
const originalPlatform = process.platform
Object.defineProperty(process, 'platform', { configurable: true, value: 'win32' })
try {
const { createIssueCommandRunnerScript } = await import('./worktree-runner-script')
const result = createIssueCommandRunnerScript(
makeRepo(),
'C:\\repo-worktree',
'gh issue view 42'
)
expect(gitExecFileSyncMock).toHaveBeenCalledWith(
['rev-parse', '--git-path', 'orca/issue-command-runner.cmd'],
{ cwd: 'C:\\repo-worktree' }
)
expect(result.shell).toEqual({ family: 'cmd' })
} finally {
Object.defineProperty(process, 'platform', { configurable: true, value: originalPlatform })
}
})
})
-106
View File
@@ -354,109 +354,3 @@ describe('createSetupRunnerScript', () => {
}
})
})
describe('createIssueCommandRunnerScript', () => {
const makeRepo = () =>
({
id: 'test-id',
path: '/test/repo',
displayName: 'Test Repo',
badgeColor: '#000',
addedAt: Date.now()
}) as unknown as Repo
it('writes a POSIX runner under the worktree git dir for long issue commands', async () => {
const fs = await import('node:fs')
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue(
'/test/repo/.git/worktrees/feature/orca/issue-command-runner.sh'
)
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'linux'
})
try {
const { createIssueCommandRunnerScript } = await import('./worktree-runner-script')
const result = createIssueCommandRunnerScript(
makeRepo(),
'/test/repo-feature',
'codex exec "long command"\nclaude -p "review it"'
)
expect(result).toEqual({
runnerScriptPath: '/test/repo/.git/worktrees/feature/orca/issue-command-runner.sh',
envVars: expect.objectContaining({
ORCA_ROOT_PATH: '/test/repo',
ORCA_WORKTREE_PATH: '/test/repo-feature'
})
})
expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
'/test/repo/.git/worktrees/feature/orca/issue-command-runner.sh',
'#!/usr/bin/env bash\nset -e\ncodex exec "long command"\nclaude -p "review it"\n',
'utf-8'
)
expect(vi.mocked(fs.chmodSync)).toHaveBeenCalledWith(
'/test/repo/.git/worktrees/feature/orca/issue-command-runner.sh',
0o755
)
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
it('carries the WSL launch shell for a Windows-drive worktree routed through WSL', async () => {
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue('/mnt/c/repo/.git/orca/issue-command-runner.sh')
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'win32'
})
try {
const { createIssueCommandRunnerScript } = await import('./worktree-runner-script')
const result = createIssueCommandRunnerScript(
makeRepo(),
'C:\\repo\\feature',
'codex exec "long command"',
{ wslDistro: 'Ubuntu' }
)
// Runner paths are stored in Windows form and need /mnt translation again at launch.
expect(result.runnerScriptPath).toBe('C:\\repo\\.git\\orca\\issue-command-runner.sh')
expect(result.shell).toEqual({ family: 'posix', executable: 'wsl.exe' })
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
it('keeps native Windows issue runners on the cmd launch shell', async () => {
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue('C:\\repo\\.git\\orca\\issue-command-runner.cmd')
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'win32'
})
try {
const { createIssueCommandRunnerScript } = await import('./worktree-runner-script')
const result = createIssueCommandRunnerScript(makeRepo(), 'C:\\repo\\feature', 'pnpm install')
expect(result.shell).toEqual({ family: 'cmd' })
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
})
@@ -1,29 +0,0 @@
import { ipcMain } from 'electron'
import {
createIssueCommandRunnerScript,
resolveSetupRunnerShell
} from '../../worktree-runner-script'
import { getLocalProjectWorktreeGitOptions } from '../../project-runtime-git-options'
import type { WorktreeIpcContext } from '../worktrees/worktree-ipc-context'
export function registerWorktreeHookRunnerHandler(context: WorktreeIpcContext): void {
const { store } = context
ipcMain.handle(
'hooks:createIssueCommandRunner',
(_event, args: { repoId: string; worktreePath: string; command: string }) => {
const repo = store.getRepo(args.repoId)
if (!repo) {
throw new Error(`Repo not found: ${args.repoId}`)
}
return createIssueCommandRunnerScript(
repo,
args.worktreePath,
args.command,
getLocalProjectWorktreeGitOptions(store, repo),
resolveSetupRunnerShell(store.getSettings())
)
}
)
}
@@ -47,7 +47,6 @@ const WORKTREE_HANDLER_CHANNELS = [
'worktrees:getBranchRenameFailureOutput',
'hooks:check',
'hooks:inspectSetupScriptImports',
'hooks:createIssueCommandRunner',
'hooks:readIssueCommand',
'hooks:writeIssueCommand'
] as const
@@ -4,11 +4,7 @@ import { join } from 'node:path'
import * as issueCommandFile from '../issue-command-file'
import * as projectGitOptions from '../project-runtime-git-options'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import {
createIssueCommandRunnerScriptMock,
addWorktreeMock,
listWorktreesMock
} from './worktrees-test-module-mocks'
import { addWorktreeMock, listWorktreesMock } from './worktrees-test-module-mocks'
import { handlers, setupWorktreeHandlers, store } from './worktrees-test-harness'
import { SshHostNotServedError } from '../providers/ssh-host-not-served-error'
@@ -173,30 +169,6 @@ describe('registerWorktreeHandlers', () => {
}
})
it('creates an issue-command runner for an existing repo/worktree pair', async () => {
const result = await handlers['hooks:createIssueCommandRunner'](null, {
repoId: 'repo-1',
worktreePath: '/workspace/improve-dashboard',
command: 'codex exec "long command"'
})
expect(createIssueCommandRunnerScriptMock).toHaveBeenCalledWith(
expect.objectContaining({ id: 'repo-1' }),
'/workspace/improve-dashboard',
'codex exec "long command"',
{},
// Why: issue runners take the resolved setup shell; it is undefined off Windows.
undefined
)
expect(result).toMatchObject({
runnerScriptPath: '/workspace/repo/.git/orca/issue-command-runner.sh',
envVars: {
ORCA_ROOT_PATH: '/workspace/repo',
ORCA_WORKTREE_PATH: '/workspace/improve-dashboard'
}
})
})
it('rejects SSH issue-command writes, which this process does not serve', async () => {
const repo = {
id: 'repo-ssh',
-9
View File
@@ -36,7 +36,6 @@ import {
getWorkItemMock,
getPullRequestPushTargetMock,
getEffectiveHooksMock,
createIssueCommandRunnerScriptMock,
createSetupRunnerScriptMock,
getEffectiveHooksFromConfigMock,
getDefaultTabsLaunchMock,
@@ -114,7 +113,6 @@ export function setupWorktreeHandlers(): WorktreeRuntimeStub {
getEffectiveHooksFromConfigMock,
getDefaultTabsLaunchMock,
parseOrcaYamlMock,
createIssueCommandRunnerScriptMock,
createSetupRunnerScriptMock,
buildPosixRunnerScriptMock,
buildWindowsRunnerScriptMock,
@@ -265,13 +263,6 @@ export function setupWorktreeHandlers(): WorktreeRuntimeStub {
ORCA_WORKTREE_PATH: '/workspace/improve-dashboard'
}
})
createIssueCommandRunnerScriptMock.mockReturnValue({
runnerScriptPath: '/workspace/repo/.git/orca/issue-command-runner.sh',
envVars: {
ORCA_ROOT_PATH: '/workspace/repo',
ORCA_WORKTREE_PATH: '/workspace/improve-dashboard'
}
})
computeWorktreePathMock.mockImplementation(
(
sanitizedName: string,
@@ -64,7 +64,6 @@ export const getWorkItemMock: ModuleMock = vi.fn()
export const getPullRequestPushTargetMock: ModuleMock = vi.fn()
export const getEffectiveHooksMock: Mock<(repo?: unknown, worktreePath?: string) => unknown> =
vi.fn()
export const createIssueCommandRunnerScriptMock: ModuleMock = vi.fn()
export const createSetupRunnerScriptMock: ModuleMock = vi.fn()
export const getEffectiveHooksFromConfigMock: ModuleMock = vi.fn()
export const getDefaultTabsLaunchMock: ModuleMock = vi.fn()
@@ -184,7 +183,6 @@ export const setupRunnerScriptTextModuleMock = (actual: Record<string, unknown>)
export const worktreeRunnerScriptModuleMock = (actual: Record<string, unknown>) => ({
...actual,
createIssueCommandRunnerScript: createIssueCommandRunnerScriptMock,
createSetupRunnerScript: createSetupRunnerScriptMock,
resolveSetupRunnerShell: resolveSetupRunnerShellMock
})
-29
View File
@@ -18,7 +18,6 @@ const {
getEffectiveHooksMock,
getEffectiveHooksFromConfigMock,
getDefaultTabsLaunchMock,
createIssueCommandRunnerScriptMock,
createSetupRunnerScriptMock,
resolveSetupRunnerShellMock,
shouldRunSetupForCreateMock,
@@ -48,7 +47,6 @@ const {
getEffectiveHooksMock: vi.fn(),
getEffectiveHooksFromConfigMock: vi.fn(),
getDefaultTabsLaunchMock: vi.fn(),
createIssueCommandRunnerScriptMock: vi.fn(),
createSetupRunnerScriptMock: vi.fn(),
resolveSetupRunnerShellMock: vi.fn(),
shouldRunSetupForCreateMock: vi.fn(),
@@ -114,7 +112,6 @@ vi.mock('../hooks', () => ({
}))
vi.mock('../worktree-runner-script', () => ({
createIssueCommandRunnerScript: createIssueCommandRunnerScriptMock,
createSetupRunnerScript: createSetupRunnerScriptMock,
resolveSetupRunnerShell: resolveSetupRunnerShellMock
}))
@@ -195,7 +192,6 @@ describe('registerWorktreeHandlers – Windows path handling', () => {
getEffectiveHooksMock.mockReset()
getEffectiveHooksFromConfigMock.mockReset()
getDefaultTabsLaunchMock.mockReset()
createIssueCommandRunnerScriptMock.mockReset()
createSetupRunnerScriptMock.mockReset()
resolveSetupRunnerShellMock.mockReset()
shouldRunSetupForCreateMock.mockReset()
@@ -609,29 +605,4 @@ describe('registerWorktreeHandlers – Windows path handling', () => {
repoId: 'repo-1'
})
})
it('gives the issue-command runner the same setup shell as the setup runner', () => {
// Regression (C4): native Windows issue runners stayed .cmd even when setup
// resolved to Git Bash, so same-session bash issue templates broke.
resolveSetupRunnerShellMock.mockReturnValue({ family: 'posix' })
createIssueCommandRunnerScriptMock.mockReturnValue({
runnerScriptPath: 'C:\\repo\\.git\\orca\\issue-command-runner.sh',
envVars: {},
shell: { family: 'posix' }
})
handlers['hooks:createIssueCommandRunner'](null, {
repoId: 'repo-1',
worktreePath: 'C:\\workspaces\\improve-dashboard',
command: 'gh issue view 42'
})
expect(resolveSetupRunnerShellMock).toHaveBeenCalledWith(store.getSettings())
expect(createIssueCommandRunnerScriptMock).toHaveBeenCalledWith(
expect.objectContaining({ id: 'repo-1' }),
'C:\\workspaces\\improve-dashboard',
'gh issue view 42',
expect.anything(),
{ family: 'posix' }
)
})
})
-3
View File
@@ -9,7 +9,6 @@ import { registerReviewBaseHandlers } from './worktrees/create/register-review-b
import { registerWorktreeHookCheckHandler } from './hooks/register-worktree-hook-check-handler'
import { registerWorktreeHookFileHandlers } from './hooks/register-worktree-hook-file-handlers'
import { registerWorktreeHookInspectionHandler } from './hooks/register-worktree-hook-inspection-handler'
import { registerWorktreeHookRunnerHandler } from './hooks/register-worktree-hook-runner-handler'
import { registerDetectedWorktreeHandlers } from './worktrees/listing/register-detected-worktree-handlers'
import { registerHostCatalogHandlers } from './worktrees/listing/register-host-catalog-handlers'
import { registerWorktreeCatalogHandlers } from './worktrees/listing/register-worktree-catalog-handlers'
@@ -54,7 +53,6 @@ const WORKTREE_HANDLER_CHANNELS = [
'worktrees:getBranchRenameFailureOutput',
'hooks:check',
'hooks:inspectSetupScriptImports',
'hooks:createIssueCommandRunner',
'hooks:readIssueCommand',
'hooks:writeIssueCommand'
] as const
@@ -96,7 +94,6 @@ export function registerWorktreeHandlers(
registerWorktreeForgetHandlers(context)
registerWorktreeMetadataHandlers(context)
registerWorktreeHookCheckHandler(context)
registerWorktreeHookRunnerHandler(context)
registerWorktreeHookInspectionHandler(context)
registerWorktreeHookFileHandlers(context)
}
+1 -19
View File
@@ -48,29 +48,11 @@ export function createSetupRunnerScript(
})
}
export function createIssueCommandRunnerScript(
repo: Repo,
worktreePath: string,
command: string,
projectRuntime?: ProjectExecutionRuntimeResolution | HookRuntimeTarget,
setupShell?: SetupRunnerShell
): WorktreeSetupLaunch {
// Runner files avoid PTY line-editor wrapping or truncation of long commands.
return createWorktreeRunnerScript({
repo,
worktreePath,
script: command,
runnerBaseName: 'issue-command-runner',
runtimeTarget: getHookRuntimeTarget(projectRuntime),
setupShell
})
}
function createWorktreeRunnerScript(args: {
repo: Repo
worktreePath: string
script: string
runnerBaseName: 'setup-runner' | 'issue-command-runner'
runnerBaseName: 'setup-runner'
runtimeTarget?: HookRuntimeTarget
waitForAgentStartup?: boolean
setupShell?: SetupRunnerShell
-6
View File
@@ -1,5 +1,4 @@
import type { OrcaHooks } from '../../shared/orca-yaml-hook-types'
import type { WorktreeSetupLaunch } from '../../shared/worktree/launch-types'
import type { ExecutionHostId } from '../../shared/execution-host'
import type { SetupScriptImportCandidate } from '../../shared/setup-script-imports'
@@ -14,11 +13,6 @@ export type HooksApi = {
repoId: string
hostId?: ExecutionHostId
}) => Promise<SetupScriptImportCandidate[]>
createIssueCommandRunner: (args: {
repoId: string
worktreePath: string
command: string
}) => Promise<WorktreeSetupLaunch>
readIssueCommand: (args: { repoId: string; hostId?: ExecutionHostId }) => Promise<{
status?: 'ok' | 'error'
localContent: string | null
-7
View File
@@ -1,5 +1,4 @@
import { ipcRenderer } from 'electron'
import type { WorktreeSetupLaunch } from '../../shared/worktree/launch-types'
import type { ExecutionHostId } from '../../shared/execution-host'
import type { PreloadApi } from '../api-types'
@@ -10,12 +9,6 @@ export const hooksApi = {
inspectSetupScriptImports: (args: { repoId: string; hostId?: ExecutionHostId }) =>
ipcRenderer.invoke('hooks:inspectSetupScriptImports', args),
createIssueCommandRunner: (args: {
repoId: string
worktreePath: string
command: string
}): Promise<WorktreeSetupLaunch> => ipcRenderer.invoke('hooks:createIssueCommandRunner', args),
readIssueCommand: (args: {
repoId: string
hostId?: ExecutionHostId
@@ -15,7 +15,6 @@ export function createHooksApi(): NonNullable<Partial<PreloadApi>['hooks']> {
check: async ({ repoId }) => callRuntimeResult('repo.hooksCheck', { repo: repoId }),
inspectSetupScriptImports: async ({ repoId }) =>
callRuntimeResult('repo.setupScriptImports', { repo: repoId }),
createIssueCommandRunner: async () => ({ launched: false }) as never,
readIssueCommand: async ({ repoId }) =>
callRuntimeResult('repo.issueCommandRead', { repo: repoId }),
writeIssueCommand: async ({ repoId, content }) => {