mirror of
https://github.com/stablyai/orca.git
synced 2026-11-01 01:27:35 +00:00
* fix(wsl): keep background git and GitHub reads from booting a stopped distro Git history, diff and status-follower reads, GitHub issue/work-item/check polls, chat link existence checks, the composer's create-base prefetch, the worktree-root fan-out and the Settings/Automations orca.yaml previews now refuse or skip a stopped WSL distro instead of starting it (E9). * fix(wsl): explicit opens may start a stopped distro; more polls gated (E9) Folds the parallel G1-G6 work into this branch and splits background reads from user acts: - An explicit open runs as a user act for its distro and may boot it: showing a diff tab or its Retry, showing Commits or its Refresh, opening the checks panel or entering its tab, checks Refresh, a check action, and linking or creating a PR. Main takes a wakeWslDistro flag on git:diff, git:branchDiff, git:commitDiff, git:history and gh:prChecks and runs those reads under runAsWslUserAct. - Polls, timers, refreshes after Git actions, prefetches and fan-outs stay background and are refused while the distro is stopped. - Also gated: the hosted-review card poll for every provider, the GitLab checks-panel poll (background flag), and the composer's open-time orca.yaml check (Create re-checks in the foreground). - Pollers keep the data they already show on a refusal: the issue on a card, the checks list, an open diff and loaded submodule children, and stop logging it. * docs(wsl): note that a hosted-review poll's stopped-distro refusal is still logged (E9) * fix(wsl): Settings re-asks orca.yaml once a stopped distro runs; drop link-check gating (E9) - Link existence checks (shell:pathsExist / pathExists) are no longer gated here: answering "missing" cached chat and terminal links as absent and toasted "File not found" on markdown link clicks. The pathsExist refusal lives in its own PR, which throws instead. - Settings no longer sits on "checking" forever: a repo whose distro refused the background check is re-asked on window focus, on visibility, and after 10 s, until it answers. An unverifiable distro is now marked (wsl-distro-unverifiable) and treated as unread too, instead of being stored as "no orca.yaml". - The sidebar issue poll and the Tasks list and count refuse with "Open a terminal in it to start it", since their Retry is itself a background read; the checks panel keeps "Retry", whose Refresh is a user act. * fix(wsl): Tasks Refresh, interactive review refresh and manual PR lookups may start a stopped distro (E9) - Tasks: a Refresh, Retry or search, or Tasks opened on a single repo, passes wakeWslDistro through gh:listWorkItems and gh:countWorkItems (IPC only; the RPC twins and web routes drop it). A multi-repo open stays background. Their refusal says "Retry" again; only the sidebar issue poll says "Open a terminal". - hostedReview:forBranch wakes for an interactive request (the checks panel's manual Refresh), so GitLab, Bitbucket, Azure DevOps and Gitea reviews with nothing cached can load. - gh:prForBranch, the renderer's fallback when refreshPRNow is missing, is gated like the other card polls; a manual lookup wakes, matching refreshPRNow's manual-only rule. The fallback call moves into its own module, built from the refresh candidate. * fix(wsl): only an explicit Refresh starts a stopped distro for review status (E9) hostedReview:forBranch woke on admissionTier 'interactive', but the visible-review scheduler sends 'interactive' for the selected card on a timer, so that poll restarted a stopped distro every interval. The wake is now an explicit wakeWslDistro flag (desktop IPC only). The card refresh helper sets it, since every caller follows a user act (the checks panel's manual Refresh, or a review created, linked or edited), and the manual Refresh also wakes its pre-refresh git status. admissionTier is back to priority only. * fix(wsl): an explicit review Refresh never joins a refused poll (E9) fetchHostedReviewForBranch let a forced card Refresh join an in-flight forced scheduler poll, since the join only compared force. On a stopped WSL distro that poll is refused, so the click got the refusal. The in-flight entry now records the wake, and a waking request joins only a waking flight; a poll may still join an explicit Refresh.
166 lines
4.7 KiB
TypeScript
166 lines
4.7 KiB
TypeScript
import { ipcRenderer } from 'electron'
|
|
import type { TaskSourceContext } from '../shared/task-source-context'
|
|
|
|
type GitLabRepoSelectorArgs = {
|
|
repoPath: string
|
|
repoId?: string | null
|
|
sourceContext?: TaskSourceContext | null
|
|
}
|
|
|
|
export const glApi = {
|
|
viewer: () => ipcRenderer.invoke('gitlab:viewer'),
|
|
diagnoseAuth: () => ipcRenderer.invoke('gitlab:diagnoseAuth'),
|
|
rateLimit: (args?: { force?: boolean; host?: string | null }) =>
|
|
ipcRenderer.invoke('gitlab:rateLimit', args),
|
|
|
|
projectSlug: (args: GitLabRepoSelectorArgs) => ipcRenderer.invoke('gitlab:projectSlug', args),
|
|
|
|
mrForBranch: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
branch: string
|
|
linkedMRIid?: number | null
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:mrForBranch', args),
|
|
|
|
mr: (args: GitLabRepoSelectorArgs & { iid: number }) => ipcRenderer.invoke('gitlab:mr', args),
|
|
|
|
listMRs: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
state?: 'opened' | 'merged' | 'closed' | 'all'
|
|
page?: number
|
|
perPage?: number
|
|
query?: string
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:listMRs', args),
|
|
|
|
listWorkItems: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
state?: 'opened' | 'merged' | 'closed' | 'all'
|
|
page?: number
|
|
perPage?: number
|
|
query?: string
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:listWorkItems', args),
|
|
|
|
issue: (args: GitLabRepoSelectorArgs & { number: number }) =>
|
|
ipcRenderer.invoke('gitlab:issue', args),
|
|
|
|
listIssues: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
state?: 'opened' | 'closed' | 'all'
|
|
assignee?: string
|
|
limit?: number
|
|
page?: number
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:listIssues', args),
|
|
|
|
createIssue: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
title: string
|
|
body: string
|
|
}
|
|
): Promise<{ ok: true; number: number; url: string } | { ok: false; error: string }> =>
|
|
ipcRenderer.invoke('gitlab:createIssue', args),
|
|
|
|
updateIssue: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
number: number
|
|
updates: unknown
|
|
}
|
|
): Promise<{ ok: true } | { ok: false; error: string }> =>
|
|
ipcRenderer.invoke('gitlab:updateIssue', args),
|
|
|
|
addIssueComment: (args: GitLabRepoSelectorArgs & { number: number; body: string }) =>
|
|
ipcRenderer.invoke('gitlab:addIssueComment', args),
|
|
|
|
listLabels: (args: GitLabRepoSelectorArgs): Promise<string[]> =>
|
|
ipcRenderer.invoke('gitlab:listLabels', args),
|
|
|
|
listAssignableUsers: (args: GitLabRepoSelectorArgs) =>
|
|
ipcRenderer.invoke('gitlab:listAssignableUsers', args),
|
|
|
|
todos: (args: GitLabRepoSelectorArgs) => ipcRenderer.invoke('gitlab:todos', args),
|
|
|
|
workItemDetails: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
type: 'issue' | 'mr'
|
|
includeReviewDetails?: boolean
|
|
background?: boolean
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:workItemDetails', args),
|
|
|
|
closeMR: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
}
|
|
): Promise<{ ok: true } | { ok: false; error: string }> =>
|
|
ipcRenderer.invoke('gitlab:closeMR', args),
|
|
|
|
reopenMR: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
}
|
|
): Promise<{ ok: true } | { ok: false; error: string }> =>
|
|
ipcRenderer.invoke('gitlab:reopenMR', args),
|
|
|
|
mergeMR: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
method?: 'merge' | 'squash' | 'rebase'
|
|
}
|
|
): Promise<{ ok: true } | { ok: false; error: string }> =>
|
|
ipcRenderer.invoke('gitlab:mergeMR', args),
|
|
|
|
updateMR: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
updates: unknown
|
|
}
|
|
): Promise<{ ok: true } | { ok: false; error: string }> =>
|
|
ipcRenderer.invoke('gitlab:updateMR', args),
|
|
|
|
updateMRReviewers: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
reviewerIds: number[]
|
|
projectRef?: unknown
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:updateMRReviewers', args),
|
|
|
|
addMRComment: (args: GitLabRepoSelectorArgs & { iid: number; body: string }) =>
|
|
ipcRenderer.invoke('gitlab:addMRComment', args),
|
|
|
|
addMRInlineComment: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
input: unknown
|
|
projectRef?: unknown
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:addMRInlineComment', args),
|
|
|
|
resolveMRDiscussion: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
iid: number
|
|
discussionId: string
|
|
resolved: boolean
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:resolveMRDiscussion', args),
|
|
|
|
jobTrace: (
|
|
args: GitLabRepoSelectorArgs & { jobId: number; projectRef?: unknown; logExcerpt?: boolean }
|
|
) => ipcRenderer.invoke('gitlab:jobTrace', args),
|
|
|
|
retryJob: (args: GitLabRepoSelectorArgs & { jobId: number; projectRef?: unknown }) =>
|
|
ipcRenderer.invoke('gitlab:retryJob', args),
|
|
|
|
workItemByPath: (
|
|
args: GitLabRepoSelectorArgs & {
|
|
host: string
|
|
path: string
|
|
iid: number
|
|
type: 'issue' | 'mr'
|
|
}
|
|
) => ipcRenderer.invoke('gitlab:workItemByPath', args)
|
|
}
|