Something went wrong. Try again.
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235// Types shared between main, preload and renderer. Keep these plain data —// everything crosses the IPC boundary via structured clone.
export type RepoSource = | { kind: 'local'; path: string } | { kind: 'remote'; url: string }
export interface RepoInfo { id: string /** Display name, e.g. "code-browser" */ name: string source: RepoSource /** Path to the git dir we read from (bare cache for remotes). */ gitDir: string defaultBranch: string | null /** Checked-out branch for local repos: the natural default for "head". */ currentBranch: string | null}
/** A repository opened lately, for the welcome screen. */export interface RecentRepo { source: RepoSource name: string /** When it was last opened (ISO). */ at: string}
export interface GitRef { name: string // e.g. "refs/heads/main" short: string // e.g. "main" or "origin/main" sha: string kind: 'branch' | 'remote' | 'tag' | 'head'}
/** A branch against the default branch: commits ahead, and files changed since their merge-base. */export interface BranchStat { ahead: number files: number}
/** What a window looks at, and what a review is about (REVIEW-FORMAT.md §2). */export interface Subject { repoId: string /** Resolved commit SHAs */ base: string head: string /** What the user typed, for display */ baseLabel: string headLabel: string}
export type ChangeStatus = 'A' | 'M' | 'D' | 'R' | 'C' | 'T'
export interface ChangedFile { path: string /** Set for renames/copies */ oldPath?: string status: ChangeStatus /** Blob ids at head and at base (absent where the file doesn't exist). */ blob?: string baseBlob?: string /** Changed lines; absent for binary files. */ adds?: number dels?: number}
export interface TreeEntry { path: string type: 'blob' | 'tree' | 'commit' // commit = submodule}
/** A hunk in -U0 form: old range replaced by new range. Lines are 1-based. */export interface Hunk { oldStart: number oldLines: number newStart: number newLines: number}
export interface FileView { path: string /** Content at head, or null if the file was deleted / is binary */ content: string | null /** Blob id at head (null if the file isn't there): what review anchors and coverage name. */ blob?: string | null /** Blob id at base, for anchors on removed lines. */ baseBlob?: string | null /** Content at base, or null if added / binary. Only included on request. */ baseContent?: string | null binary: boolean hunks: Hunk[] change: ChangedFile | null /** A dependency's file read from the sandbox (not in the repository): read-only, no code intel. */ external?: ExternalFile}
/** One top-level Markdown block, as the VM rendered it (untrusted HTML: see safe.ts). */export interface MarkdownBlock { /** 1-based source lines, inclusive. */ start: number end: number /** markdown-it's token type for the block, e.g. "paragraph_open", "html_block". */ kind: string html: string}
/** A remote image in rendered Markdown, fetched in the VM through the egress proxy. */export type RemoteImage = { ok: true; url: string } | { ok: false; blocked: boolean; reason: string }
/** A file outside the repository that a language server pointed at (node_modules, module caches, std). */export interface ExternalFile { sandboxId: string where: 'vm' | 'devcontainer' | 'container' /** The language container (for where = 'container'). */ container?: string /** Absolute path in the VM or the devcontainer. */ path: string /** Short display name, e.g. "github.com/google/uuid@v1.6.0/version4.go". */ label: string}
export interface SandboxInfo { id: string provider: string readyMs: number warm: boolean snapshotMs: number}
export type ExecTarget = 'vm' | 'devcontainer'
export type SandboxEvent = | { execId: string; type: 'stdout' | 'stderr'; data: string } | { execId: string; type: 'exit'; code: number } /** Every egress attempt from the sandbox, allowed or not. */ | { sandboxId: string; type: 'net'; host: string; port: number; allowed: boolean; reason?: string; wouldBlock?: string } /** The shared, digest-verified registry cache served (hit) or stored (miss) an object. */ | { sandboxId: string; type: 'cache'; host: string; kind: 'blob' | 'manifest'; digest: string; hit: boolean; bytes: number } /** SCIP indexing finished for a commit (indexes are cached on the host per commit). */ | { sandboxId: string; type: 'intel'; commit: string; indexes: IndexInfo[]; error?: string } /** Progress of one project during indexing (dependencies, then its index). */ | { sandboxId: string; type: 'project'; projectId: string; phase: ProjectPhase; detail?: string } | { sandboxId: string type: 'devcontainer' ok: boolean containerId?: string remoteWorkspaceFolder?: string error?: string }
export interface IndexInfo { name: string // e.g. "python-services-billing" documents: number /** The project it covers (ProjectInfo.id), when known. */ project?: string}
export type ProjectPhase = 'queued' | 'deps' | 'index' | 'done' | 'failed' | 'warn'
export interface IntelLocation { /** Repo-relative path, or the external file's label. */ path: string line: number character: number endLine: number endCharacter: number external?: ExternalFile}
export interface IntelQuery { subject: Subject path: string line: number // 0-based character: number // 0-based, UTF-16 sandboxId?: string}
export type IntelKind = 'definition' | 'references' | 'hover'
export interface IntelResult { source: 'scip' | 'lsp' | 'none' locations?: IntelLocation[] hover?: string note?: string}
/** enforce: allow-list only. monitor: allow all, report what enforce would block. open: allow all. */export type EgressMode = 'enforce' | 'monitor' | 'open'
export interface EgressSettingsInfo { mode: EgressMode /** Built into the app. */ defaults: string[] /** Added by the user (hostnames or `*.domain` patterns). */ user: string[]}
export type Ecosystem = 'python' | 'node' | 'go' | 'rust'
/** A project in the repository: one toolchain version, one dependency set, one language server. */export interface ProjectInfo { /** `${ecosystem}:${root || '.'}` */ id: string ecosystem: Ecosystem /** Repo-relative directory ('' = repository root). */ root: string /** Package name when the manifest has one, else the directory name. */ name: string /** Manifests that define it, repo-relative. */ manifests: string[] /** Workspace members folded into this project (Cargo/go.work/npm/pnpm/uv workspaces). */ members: string[] /** Projects (ids) this one depends on through local path/workspace dependencies in its manifests. */ dependsOn: string[] version: ProjectVersion /** Environment key, e.g. "python@3.8": projects with the same key share a toolchain. */ environment: string /** Contains files changed in the review (indexed first). */ changed: boolean}
export interface ProjectVersion { /** Resolved version, e.g. "3.8", "20", "1.22.3", "stable". */ value: string /** How it was decided: a pin (.python-version, rust-toolchain.toml, go.mod…), the newest version satisfying a range, the default, or the user's override. */ kind: 'pinned' | 'range' | 'default' | 'override' /** File it came from, repo-relative. */ source: string | null /** The range as written, for kind 'range'. */ spec?: string /** Set when a range matched no known version (the default was used). */ warning?: string}