Files
orca/src/main/hooks-runner.test.ts
T
NeilandOrca 46646d7ff1 chore(lint): upgrade oxlint to 1.71 + enable 7 new rules (autofixed backlog) (#6841)
* chore(lint): upgrade oxlint to 1.71 and enable 7 new rules

Upgrade oxlint 1.67.0 -> 1.71.0 (1.72 was blocked by the repo's 3-day
minimum-release-age supply-chain guard; nothing here needs it). The
bump is a no-op on the existing config.

Enable 3 error rules (backlog autofixed to zero in this commit) and
4 warn rules (surface signal without gating CI):

error (autofixed, behavior-preserving):
- unicorn/prefer-node-protocol        (~1531 sites: bare builtin -> node:)
- typescript/no-import-type-side-effects (~36: all-inline-type -> import type)
- unicorn/no-array-reverse            (19: copy-then-reverse -> toReversed)

warn (real signal, current fires are test-only/correct):
- unicorn/no-array-fill-with-reference-type  (aliasing footgun guard)
- typescript/no-unsafe-function-type         (bans bare Function type)
- unicorn/prefer-array-flat-map              (map().flat() -> flatMap())
- unicorn/prefer-regexp-test                 (.match() in bool ctx -> .test())

mobile/.oxlintrc.json extends root, so it inherits all 7; the autofix
ran from root and covered mobile/ too.

Verification (all green): oxlint 0 errors (root+mobile+aux configs),
oxfmt clean, typecheck (node+cli+web), vitest 22795 passed / 0 failed,
builds (electron-vite + web + cli) succeed. node: rewrites confirmed to
skip embedded SSH/CLI string payloads (AST-only); all toReversed sites
verified to operate on fresh copies or write-once locals.

* chore(lint): bump mobile oxlint to 1.71 so inherited rules parse

mobile/ is a standalone pnpm project pinning its own oxlint@1.67, which
lacks unicorn/no-array-fill-with-reference-type (needs >=1.70). Since
mobile/.oxlintrc.json extends the root config, mobile CI's 'cd mobile &&
oxlint' failed to parse the new rule. Bump mobile to match root (1.71).

Verified in mobile/: oxlint 0 errors, oxfmt --check clean, tsc --noEmit
pass, vitest 978 passed / 0 failed.

Co-authored-by: Orca <help@stably.ai>

---------

Co-authored-by: Orca <help@stably.ai>
2026-06-29 22:38:29 -07:00

260 lines
8.1 KiB
TypeScript

import type { Repo } from '../shared/types'
import { describe, expect, it, vi } from 'vitest'
const { execFileSyncMock } = vi.hoisted(() => ({
execFileSyncMock: vi.fn()
}))
vi.mock('fs', () => ({
readFileSync: vi.fn(),
existsSync: vi.fn(),
mkdirSync: vi.fn(),
writeFileSync: vi.fn(),
chmodSync: vi.fn()
}))
vi.mock('child_process', () => ({
exec: vi.fn(),
execFileSync: execFileSyncMock,
// runner.ts imports these from child_process; stubs prevent
// "missing export" errors when the mock is resolved transitively.
execFile: vi.fn(),
spawn: vi.fn()
}))
describe('createSetupRunnerScript', () => {
const makeRepo = () =>
({
id: 'test-id',
path: '/test/repo',
displayName: 'Test Repo',
badgeColor: '#000',
addedAt: Date.now()
}) as unknown as Repo
it('writes a fail-fast Windows runner that returns after batch commands', async () => {
const fs = await import('node:fs')
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue('C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.cmd')
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'win32'
})
try {
const { createSetupRunnerScript } = await import('./hooks')
const result = createSetupRunnerScript(
makeRepo(),
'C:\\repo\\feature\\',
'pnpm install\npnpm build'
)
expect(result).toEqual({
runnerScriptPath: 'C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.cmd',
envVars: expect.objectContaining({
ORCA_ROOT_PATH: '/test/repo',
ORCA_WORKTREE_PATH: 'C:\\repo\\feature\\',
ORCA_WORKSPACE_NAME: 'feature'
})
})
expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
'C:\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.cmd',
[
'@echo off',
'setlocal EnableExtensions',
'call pnpm install',
'if errorlevel 1 exit /b %errorlevel%',
'call pnpm build',
'if errorlevel 1 exit /b %errorlevel%',
''
].join('\r\n'),
'utf-8'
)
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
it('derives ORCA_WORKSPACE_NAME from a POSIX worktree path', async () => {
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue('/test/repo/.git/worktrees/feature/orca/setup-runner.sh')
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'linux'
})
try {
const { createSetupRunnerScript } = await import('./hooks')
const result = createSetupRunnerScript(makeRepo(), '/test/repo-feature', 'pnpm install')
expect(result.envVars).toEqual(
expect.objectContaining({
ORCA_WORKTREE_PATH: '/test/repo-feature',
ORCA_WORKSPACE_NAME: 'repo-feature'
})
)
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
it('translates WSL runner paths and env vars to Linux form on Windows', async () => {
const fs = await import('node:fs')
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue('/home/jin/.git/worktrees/feature/orca/setup-runner.sh')
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'win32'
})
try {
const { createSetupRunnerScript } = await import('./hooks')
const result = createSetupRunnerScript(
{
...makeRepo(),
path: 'C:\\Users\\jinwo\\git\\orca'
},
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\feature',
'pnpm install'
)
expect(result).toEqual({
runnerScriptPath:
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\.git\\worktrees\\feature\\orca\\setup-runner.sh',
envVars: expect.objectContaining({
ORCA_ROOT_PATH: '/mnt/c/Users/jinwo/git/orca',
ORCA_WORKTREE_PATH: '/home/jin/feature',
ORCA_WORKSPACE_NAME: 'feature',
CONDUCTOR_ROOT_PATH: '/mnt/c/Users/jinwo/git/orca',
GHOSTX_ROOT_PATH: '/mnt/c/Users/jinwo/git/orca'
})
})
expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\.git\\worktrees\\feature\\orca\\setup-runner.sh',
'#!/usr/bin/env bash\nset -e\npnpm install\n',
'utf-8'
)
expect(vi.mocked(fs.chmodSync)).toHaveBeenCalledWith(
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\.git\\worktrees\\feature\\orca\\setup-runner.sh',
0o755
)
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
it('translates WSL env vars to Linux paths when the worktree lives on a WSL UNC path', async () => {
const fs = await import('node:fs')
const originalPlatform = process.platform
execFileSyncMock.mockReturnValue('/home/jin/repo/.git/worktrees/feature/orca/setup-runner.sh')
Object.defineProperty(process, 'platform', {
configurable: true,
value: 'win32'
})
try {
const { createSetupRunnerScript } = await import('./hooks')
const result = createSetupRunnerScript(
makeRepo(),
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\repo\\feature',
'pnpm install'
)
expect(result).toEqual({
runnerScriptPath:
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh',
envVars: expect.objectContaining({
ORCA_ROOT_PATH: '/test/repo',
ORCA_WORKTREE_PATH: '/home/jin/repo/feature',
ORCA_WORKSPACE_NAME: 'feature',
CONDUCTOR_ROOT_PATH: '/test/repo',
GHOSTX_ROOT_PATH: '/test/repo'
})
})
expect(vi.mocked(fs.writeFileSync)).toHaveBeenCalledWith(
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh',
'#!/usr/bin/env bash\nset -e\npnpm install\n',
'utf-8'
)
expect(vi.mocked(fs.chmodSync)).toHaveBeenCalledWith(
'\\\\wsl.localhost\\Ubuntu\\home\\jin\\repo\\.git\\worktrees\\feature\\orca\\setup-runner.sh',
0o755
)
} finally {
Object.defineProperty(process, 'platform', {
configurable: true,
value: originalPlatform
})
}
})
})
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('./hooks')
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
})
}
})
})