mirror of
https://github.com/stablyai/orca.git
synced 2026-10-01 16:02:03 +00:00
fix: avoid repeated macOS privacy prompts (#1524)
* fix: avoid repeated macos privacy prompts * fix: reduce background worktree permission probes * chore: pin oxlint for ci * fix: preserve optional rpc params with zod 4.4 * fix: preserve optional inline rpc params with zod 4.4
This commit is contained in:
@@ -294,13 +294,36 @@ describe('getStatus', () => {
|
||||
// wrapped in double quotes) and the parser would store that literal
|
||||
// string as entry.path, breaking sidebar display + downstream blob reads.
|
||||
expect(gitExecFileAsyncMock).toHaveBeenCalledWith(
|
||||
['-c', 'core.quotePath=false', 'status', '--porcelain=v2', '--untracked-files=all'],
|
||||
[
|
||||
'-c',
|
||||
'core.quotePath=false',
|
||||
'status',
|
||||
'--porcelain=v2',
|
||||
'--branch',
|
||||
'--untracked-files=all'
|
||||
],
|
||||
{ cwd: '/repo' }
|
||||
)
|
||||
expect(result.entries).toEqual([
|
||||
{ path: 'docs/日本語/sample.md', status: 'modified', area: 'unstaged' }
|
||||
])
|
||||
})
|
||||
|
||||
it('parses branch identity from porcelain v2 branch headers', async () => {
|
||||
readFileMock.mockResolvedValue('gitdir: /repo/.git/worktrees/feature\n')
|
||||
existsSyncMock.mockReturnValue(false)
|
||||
gitExecFileAsyncMock.mockResolvedValueOnce({
|
||||
stdout:
|
||||
'# branch.oid abcdef1234567890\n# branch.head feature/prompts\n1 .M N... 100644 100644 100644 ce013625030ba8dba906f756967f9e9ca394464a ce013625030ba8dba906f756967f9e9ca394464a src/app.ts\n'
|
||||
})
|
||||
|
||||
const result = await getStatus('/repo')
|
||||
|
||||
expect(result).toMatchObject({
|
||||
head: 'abcdef1234567890',
|
||||
branch: 'refs/heads/feature/prompts'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('detectConflictOperation', () => {
|
||||
|
||||
+15
-2
@@ -23,6 +23,8 @@ const MAX_GIT_SHOW_BYTES = 10 * 1024 * 1024
|
||||
*/
|
||||
export async function getStatus(worktreePath: string): Promise<GitStatusResult> {
|
||||
const entries: GitStatusEntry[] = []
|
||||
let head: string | undefined
|
||||
let branch: string | undefined
|
||||
|
||||
// Why: detectConflictOperation (4 existsSync + readFile) and git status are
|
||||
// independent. Running them concurrently saves one round-trip of I/O latency.
|
||||
@@ -32,7 +34,7 @@ export async function getStatus(worktreePath: string): Promise<GitStatusResult>
|
||||
// in double quotes. Without it, the parsed entry.path is unreadable in the
|
||||
// sidebar and downstream `git show :"docs/\346..."` lookups silently miss.
|
||||
const statusPromise = gitExecFileAsync(
|
||||
['-c', 'core.quotePath=false', 'status', '--porcelain=v2', '--untracked-files=all'],
|
||||
['-c', 'core.quotePath=false', 'status', '--porcelain=v2', '--branch', '--untracked-files=all'],
|
||||
{ cwd: worktreePath }
|
||||
)
|
||||
const conflictOperation = await conflictPromise
|
||||
@@ -47,6 +49,17 @@ export async function getStatus(worktreePath: string): Promise<GitStatusResult>
|
||||
continue
|
||||
}
|
||||
|
||||
if (line.startsWith('# branch.oid ')) {
|
||||
head = line.slice('# branch.oid '.length).trim()
|
||||
continue
|
||||
}
|
||||
|
||||
if (line.startsWith('# branch.head ')) {
|
||||
const branchHead = line.slice('# branch.head '.length).trim()
|
||||
branch = branchHead && branchHead !== '(detached)' ? `refs/heads/${branchHead}` : ''
|
||||
continue
|
||||
}
|
||||
|
||||
if (line.startsWith('1 ') || line.startsWith('2 ')) {
|
||||
// Changed entries: "1 XY sub mH mI mW hH path" or "2 XY sub mH mI mW hH X\tscore\tpath\torigPath"
|
||||
const parts = line.split(' ')
|
||||
@@ -95,7 +108,7 @@ export async function getStatus(worktreePath: string): Promise<GitStatusResult>
|
||||
// Not a git repo or git not available
|
||||
}
|
||||
|
||||
return { entries, conflictOperation }
|
||||
return { entries, conflictOperation, head, branch }
|
||||
}
|
||||
|
||||
function parseStatusChar(char: string): GitFileStatus {
|
||||
|
||||
Reference in New Issue
Block a user