mirror of
https://github.com/stablyai/orca.git
synced 2026-10-19 16:03:26 +00:00
* 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>
260 lines
8.1 KiB
TypeScript
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
|
|
})
|
|
}
|
|
})
|
|
})
|