From 75fdf8941cd071f85a3ca3b64b0d714e6cee0a9d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 25 Jun 2026 22:36:23 +0000 Subject: [PATCH] chore: format with prettier [skip ci] --- README.md | 74 +- package.json | 40 +- packages/desktop/src/api/schema.ts | 5238 +++++++++-------- .../desktop/src/renderer/routeTree.gen.ts | 311 +- packages/shared/jest.config.js | 56 +- packages/shared/jest.setup.cjs | 2 +- packages/shared/package.json | 60 +- packages/shared/src/api/client.ts | 140 +- packages/shared/src/api/paths.ts | 4 +- packages/shared/src/api/types.ts | 8 +- packages/shared/src/hooks/useDaemonStatus.ts | 54 +- .../src/hooks/useWorkspaceQuery.test.tsx | 88 +- .../shared/src/hooks/useWorkspaceQuery.ts | 54 +- packages/shared/src/index.ts | 16 +- packages/shared/src/lib/bridge.ts | 28 +- .../shared/src/lib/event-transport.test.ts | 50 +- packages/shared/src/lib/event-transport.ts | 138 +- packages/shared/src/lib/events-connection.ts | 20 +- packages/shared/tsconfig.json | 34 +- 19 files changed, 3220 insertions(+), 3195 deletions(-) diff --git a/README.md b/README.md index de751b3a5..e583ad177 100644 --- a/README.md +++ b/README.md @@ -49,17 +49,17 @@ An Agentic IDE that supervises parallel AI coding agents in isolated workspaces, ## Features -| Feature | Description | -| :--- | :--- | -| **Agent-Agnostic Platform** | 23+ agent adapters including [Claude Code](https://code.claude.com/docs/en/overview), [OpenAI Codex](https://openai.com/), [Cursor](https://cursor.com/), [OpenCode](https://opencode.ai/), [Aider](https://aider.chat/), [Amp](https://ampcode.com/manual), [Goose](https://goose-docs.ai/), [GitHub Copilot](https://github.com/features/copilot), [Grok](https://x.ai/grok), [Qwen Code](https://github.com/QwenLM/qwen-code), [Kimi Code](https://www.kimi.com/code), [Cline](https://cline.bot/), [Continue](https://www.continue.dev/), [Kiro](https://kiro.dev/), and more | -| **Isolated Workspaces** | Each session spawns into its own git worktree with dedicated runtime | -| **Platform-Native Runtimes** | tmux on Darwin/Linux, conpty on Windows for optimal performance | -| **Live PR Observation** | Provider-neutral SCM observer with automatic feedback routing | -| **Automatic Feedback Routing** | CI failures, review comments, and merge conflicts routed to the owning agent | -| **Durable Facts Storage** | SQLite persists immutable facts with display status derived at read time | -| **CDC Broadcasting** | DB triggers append changes to change_log, broadcasted via SSE | -| **Desktop Experience** | Native Electron app with React UI and live terminal streaming | -| **Loopback-Only Daemon** | HTTP control over 127.0.0.1 with no auth, CORS, or TLS by design | +| Feature | Description | +| :----------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **Agent-Agnostic Platform** | 23+ agent adapters including [Claude Code](https://code.claude.com/docs/en/overview), [OpenAI Codex](https://openai.com/), [Cursor](https://cursor.com/), [OpenCode](https://opencode.ai/), [Aider](https://aider.chat/), [Amp](https://ampcode.com/manual), [Goose](https://goose-docs.ai/), [GitHub Copilot](https://github.com/features/copilot), [Grok](https://x.ai/grok), [Qwen Code](https://github.com/QwenLM/qwen-code), [Kimi Code](https://www.kimi.com/code), [Cline](https://cline.bot/), [Continue](https://www.continue.dev/), [Kiro](https://kiro.dev/), and more | +| **Isolated Workspaces** | Each session spawns into its own git worktree with dedicated runtime | +| **Platform-Native Runtimes** | tmux on Darwin/Linux, conpty on Windows for optimal performance | +| **Live PR Observation** | Provider-neutral SCM observer with automatic feedback routing | +| **Automatic Feedback Routing** | CI failures, review comments, and merge conflicts routed to the owning agent | +| **Durable Facts Storage** | SQLite persists immutable facts with display status derived at read time | +| **CDC Broadcasting** | DB triggers append changes to change_log, broadcasted via SSE | +| **Desktop Experience** | Native Electron app with React UI and live terminal streaming | +| **Loopback-Only Daemon** | HTTP control over 127.0.0.1 with no auth, CORS, or TLS by design | ### Supported Agents @@ -74,13 +74,14 @@ Works with 23+ CLI-based coding agents including Claude Code, OpenAI Codex, Curs ### Prerequisites | Requirement | Minimum | Recommended | -|-------------|---------|-------------| -| Go | 1.25+ | Latest | -| Node.js | 20+ | Latest LTS | -| Git | Any | Latest | -| pnpm | Any | Latest | +| ----------- | ------- | ----------- | +| Go | 1.25+ | Latest | +| Node.js | 20+ | Latest LTS | +| Git | Any | Latest | +| pnpm | Any | Latest | **Optional:** + - `tmux` (Darwin/Linux) - For Unix runtime - `gh` (GitHub CLI) - For authenticated GitHub API calls @@ -88,11 +89,11 @@ Works with 23+ CLI-based coding agents including Claude Code, OpenAI Codex, Curs Download the latest release for your platform: -| Platform | Download | -|----------|----------| -| **Windows** | [Setup.exe](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) | -| **macOS** | [Agent Orchestrator.dmg](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) | -| **Linux** | [Agent Orchestrator.AppImage](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) | +| Platform | Download | +| ----------- | ------------------------------------------------------------------------------------------------- | +| **Windows** | [Setup.exe](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) | +| **macOS** | [Agent Orchestrator.dmg](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) | +| **Linux** | [Agent Orchestrator.AppImage](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) | **Direct Download:** [Latest Release](https://github.com/AgentWrapper/agent-orchestrator/releases/latest) @@ -105,6 +106,7 @@ Agent Orchestrator is a long-running Go daemon built around **inbound/outbound p **Core mental model:** OBSERVE external facts → UPDATE durable facts → DERIVE display status / ACT **Key components:** + - **Frontend** - Electron + React UI with TanStack Router/Query and shadcn/ui - **Backend Daemon** - Go-based HTTP server with controllers, services, and adapters - **Runtime** - Platform-specific: `tmux` on Darwin/Linux, `conpty` on Windows @@ -117,12 +119,12 @@ For detailed architecture diagrams, data flows, and load-bearing rules, see [arc ## Documentation -| Document | Description | -|----------|-------------| -| [Architecture](docs/architecture.md) | System architecture, data flows, and load-bearing rules | -| [Backend Code Structure](docs/backend-code-structure.md) | Package-by-package ownership and dependency rules | -| [AGENTS.md](AGENTS.md) | Contributor and worker-agent contract | -| [Agent Adapter Contract](docs/agent/README.md) | Agent adapter interface and hook behavior | +| Document | Description | +| -------------------------------------------------------- | ------------------------------------------------------- | +| [Architecture](docs/architecture.md) | System architecture, data flows, and load-bearing rules | +| [Backend Code Structure](docs/backend-code-structure.md) | Package-by-package ownership and dependency rules | +| [AGENTS.md](AGENTS.md) | Contributor and worker-agent contract | +| [Agent Adapter Contract](docs/agent/README.md) | Agent adapter interface and hook behavior | --- @@ -147,15 +149,15 @@ npx @redwoodjs/agent-ci run --all All configuration is environment-driven. The daemon takes no config file. -| Variable | Default | Purpose | -|----------|---------|---------| -| `AO_PORT` | `3001` | HTTP bind port | -| `AO_REQUEST_TIMEOUT` | `60s` | Per-request timeout | -| `AO_SHUTDOWN_TIMEOUT` | `10s` | Graceful shutdown cap | -| `AO_RUN_FILE` | `~/.ao/running.json` | PID/port handshake | -| `AO_DATA_DIR` | `~/.ao/data` | SQLite data directory | -| `AO_AGENT` | `claude-code` | Compatibility agent adapter | -| `GITHUB_TOKEN` | - | GitHub auth token | +| Variable | Default | Purpose | +| --------------------- | -------------------- | --------------------------- | +| `AO_PORT` | `3001` | HTTP bind port | +| `AO_REQUEST_TIMEOUT` | `60s` | Per-request timeout | +| `AO_SHUTDOWN_TIMEOUT` | `10s` | Graceful shutdown cap | +| `AO_RUN_FILE` | `~/.ao/running.json` | PID/port handshake | +| `AO_DATA_DIR` | `~/.ao/data` | SQLite data directory | +| `AO_AGENT` | `claude-code` | Compatibility agent adapter | +| `GITHUB_TOKEN` | - | GitHub auth token | ### Health Checks diff --git a/package.json b/package.json index f4ab94df7..4cfab1cc4 100644 --- a/package.json +++ b/package.json @@ -1,22 +1,22 @@ { - "name": "agent-orchestrator", - "version": "0.0.0", - "private": true, - "workspaces": [ - "packages/*" - ], - "scripts": { - "api": "run-s api:spec api:ts", - "api:spec": "cd backend && go generate ./internal/httpd/apispec/...", - "api:ts": "npx openapi-typescript@7.4.4 backend/internal/httpd/apispec/openapi.yaml -o packages/shared/src/api/schema.ts", - "lint": "npm run lint:backend && npm run lint:frontend", - "lint:backend": "cd backend && go test ./... && golangci-lint run", - "lint:frontend": "cd packages/desktop && npm run typecheck", - "build:shared": "cd packages/shared && npm run build", - "build:desktop": "cd packages/desktop && npm run build", - "build:mobile": "cd packages/mobile && npm run build" - }, - "devDependencies": { - "npm-run-all": "^4.1.5" - } + "name": "agent-orchestrator", + "version": "0.0.0", + "private": true, + "workspaces": [ + "packages/*" + ], + "scripts": { + "api": "run-s api:spec api:ts", + "api:spec": "cd backend && go generate ./internal/httpd/apispec/...", + "api:ts": "npx openapi-typescript@7.4.4 backend/internal/httpd/apispec/openapi.yaml -o packages/shared/src/api/schema.ts", + "lint": "npm run lint:backend && npm run lint:frontend", + "lint:backend": "cd backend && go test ./... && golangci-lint run", + "lint:frontend": "cd packages/desktop && npm run typecheck", + "build:shared": "cd packages/shared && npm run build", + "build:desktop": "cd packages/desktop && npm run build", + "build:mobile": "cd packages/mobile && npm run build" + }, + "devDependencies": { + "npm-run-all": "^4.1.5" + } } diff --git a/packages/desktop/src/api/schema.ts b/packages/desktop/src/api/schema.ts index a7f68302d..e2dc8703f 100644 --- a/packages/desktop/src/api/schema.ts +++ b/packages/desktop/src/api/schema.ts @@ -4,2611 +4,2647 @@ */ export interface paths { - "/api/v1/events": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Stream CDC events with durable replay */ - get: operations["streamEvents"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/notifications": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List unread notifications */ - get: operations["listNotifications"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/notifications/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - /** Mark a notification read */ - patch: operations["markNotificationRead"]; - trace?: never; - }; - "/api/v1/notifications/read-all": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Mark all unread notifications read */ - post: operations["markAllNotificationsRead"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/notifications/stream": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Stream created notifications */ - get: operations["streamNotifications"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/orchestrators": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List orchestrator sessions across projects */ - get: operations["listOrchestrators"]; - put?: never; - /** Spawn an orchestrator session */ - post: operations["spawnOrchestrator"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/orchestrators/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Fetch one orchestrator session */ - get: operations["getOrchestrator"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/projects": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List all registered projects (active + degraded) */ - get: operations["listProjects"]; - put?: never; - /** Register a new project from a git repository path */ - post: operations["addProject"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/projects/{id}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Fetch one project; discriminates ok vs degraded */ - get: operations["getProject"]; - put?: never; - post?: never; - /** Remove a project; stops sessions, cleans workspaces, unregisters */ - delete: operations["removeProject"]; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/projects/{id}/config": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - /** Replace a project's per-project config */ - put: operations["setProjectConfig"]; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/prs/{id}/merge": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Squash-merge a pull request */ - post: operations["mergePR"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/prs/{id}/resolve-comments": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Resolve review threads on a pull request */ - post: operations["resolveComments"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List sessions */ - get: operations["listSessions"]; - put?: never; - /** Spawn a new agent session */ - post: operations["spawnSession"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Fetch one session */ - get: operations["getSession"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - /** Rename a session display name */ - patch: operations["renameSession"]; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/activity": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Report an agent activity-state signal for a session */ - post: operations["setSessionActivity"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/kill": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Mark a session terminated and tear down runtime/workspace resources */ - post: operations["killSession"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/pr": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List pull requests owned by a session */ - get: operations["listSessionPRs"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/pr/claim": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Claim an existing pull request for a session */ - post: operations["claimSessionPR"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/preview": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Discover a browser preview URL for a session workspace */ - get: operations["getSessionPreview"]; - put?: never; - /** Set (or autodetect) the browser preview URL for a session */ - post: operations["setSessionPreview"]; - /** Clear the browser preview URL for a session */ - delete: operations["clearSessionPreview"]; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/preview/files/*": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** Serve a static browser preview file from a session workspace */ - get: operations["getSessionPreviewFile"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/restore": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Restore a terminated session */ - post: operations["restoreSession"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/reviews": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - /** List a worker's code-review runs */ - get: operations["listReviews"]; - put?: never; - post?: never; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/reviews/submit": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Record a reviewer's result for a worker's PR */ - post: operations["submitReview"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/reviews/trigger": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Trigger a code review of a worker's PR */ - post: operations["triggerReview"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/rollback": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Undo a partially-completed spawn (delete seed row, or kill if spawn output exists) */ - post: operations["rollbackSession"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/{sessionId}/send": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Send a message to a running session's agent */ - post: operations["sendSessionMessage"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; - "/api/v1/sessions/cleanup": { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - get?: never; - put?: never; - /** Clean up terminated session workspaces */ - post: operations["cleanupSessions"]; - delete?: never; - options?: never; - head?: never; - patch?: never; - trace?: never; - }; + "/api/v1/events": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Stream CDC events with durable replay */ + get: operations["streamEvents"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/notifications": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List unread notifications */ + get: operations["listNotifications"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/notifications/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** Mark a notification read */ + patch: operations["markNotificationRead"]; + trace?: never; + }; + "/api/v1/notifications/read-all": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Mark all unread notifications read */ + post: operations["markAllNotificationsRead"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/notifications/stream": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Stream created notifications */ + get: operations["streamNotifications"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/orchestrators": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List orchestrator sessions across projects */ + get: operations["listOrchestrators"]; + put?: never; + /** Spawn an orchestrator session */ + post: operations["spawnOrchestrator"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/orchestrators/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Fetch one orchestrator session */ + get: operations["getOrchestrator"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/projects": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List all registered projects (active + degraded) */ + get: operations["listProjects"]; + put?: never; + /** Register a new project from a git repository path */ + post: operations["addProject"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/projects/{id}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Fetch one project; discriminates ok vs degraded */ + get: operations["getProject"]; + put?: never; + post?: never; + /** Remove a project; stops sessions, cleans workspaces, unregisters */ + delete: operations["removeProject"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/projects/{id}/config": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + /** Replace a project's per-project config */ + put: operations["setProjectConfig"]; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/prs/{id}/merge": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Squash-merge a pull request */ + post: operations["mergePR"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/prs/{id}/resolve-comments": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Resolve review threads on a pull request */ + post: operations["resolveComments"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List sessions */ + get: operations["listSessions"]; + put?: never; + /** Spawn a new agent session */ + post: operations["spawnSession"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Fetch one session */ + get: operations["getSession"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + /** Rename a session display name */ + patch: operations["renameSession"]; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/activity": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Report an agent activity-state signal for a session */ + post: operations["setSessionActivity"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/kill": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Mark a session terminated and tear down runtime/workspace resources */ + post: operations["killSession"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/pr": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List pull requests owned by a session */ + get: operations["listSessionPRs"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/pr/claim": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Claim an existing pull request for a session */ + post: operations["claimSessionPR"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/preview": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Discover a browser preview URL for a session workspace */ + get: operations["getSessionPreview"]; + put?: never; + /** Set (or autodetect) the browser preview URL for a session */ + post: operations["setSessionPreview"]; + /** Clear the browser preview URL for a session */ + delete: operations["clearSessionPreview"]; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/preview/files/*": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** Serve a static browser preview file from a session workspace */ + get: operations["getSessionPreviewFile"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/restore": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Restore a terminated session */ + post: operations["restoreSession"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/reviews": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + /** List a worker's code-review runs */ + get: operations["listReviews"]; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/reviews/submit": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Record a reviewer's result for a worker's PR */ + post: operations["submitReview"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/reviews/trigger": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Trigger a code review of a worker's PR */ + post: operations["triggerReview"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/rollback": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Undo a partially-completed spawn (delete seed row, or kill if spawn output exists) */ + post: operations["rollbackSession"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/{sessionId}/send": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Send a message to a running session's agent */ + post: operations["sendSessionMessage"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; + "/api/v1/sessions/cleanup": { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get?: never; + put?: never; + /** Clean up terminated session workspaces */ + post: operations["cleanupSessions"]; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; + }; } export type webhooks = Record; export interface components { - schemas: { - APIError: { - code: string; - details?: { - [key: string]: unknown; - }; - error: string; - message: string; - requestId?: string; - }; - AddProjectInput: { - asWorkspace?: boolean; - config?: components["schemas"]["ProjectConfig"]; - name?: null | string; - path: string; - projectId?: null | string; - }; - AgentConfig: { - model?: string; - permissions?: string; - }; - ClaimPRRequest: { - allowTakeover?: null | boolean; - pr: string; - }; - ClaimPRResponse: { - branchChanged: boolean; - ok: boolean; - prs: components["schemas"]["SessionPRFacts"][]; - sessionId: string; - takenOverFrom: string[]; - }; - CleanupSessionsResponse: { - cleaned: string[]; - ok: boolean; - skipped: components["schemas"]["CleanupSkippedSession"][]; - }; - CleanupSkippedSession: { - reason: string; - sessionId: string; - }; - ControllersSessionView: { - activity: components["schemas"]["DomainActivity"]; - branch?: string; - /** Format: date-time */ - createdAt: string; - displayName?: string; - harness?: string; - id: string; - isTerminated: boolean; - issueId?: string; - kind: string; - /** Format: int64 */ - previewRevision?: number; - previewUrl?: string; - projectId: string; - prs: components["schemas"]["SessionPRFacts"][]; - /** @enum {string} */ - status: "working" | "pr_open" | "draft" | "ci_failed" | "review_pending" | "changes_requested" | "approved" | "mergeable" | "merged" | "needs_input" | "idle" | "terminated" | "no_signal"; - terminalHandleId?: string; - /** Format: date-time */ - updatedAt: string; - }; - DegradedProject: { - id: string; - kind: string; - name: string; - path: string; - resolveError: string; - }; - DomainActivity: { - /** Format: date-time */ - lastActivityAt: string; - state: string; - }; - DomainReviewerConfig: { - harness: string; - }; - KillSessionResponse: { - freed?: boolean; - ok: boolean; - sessionId: string; - }; - ListNotificationsResponse: { - notifications: components["schemas"]["NotificationResponse"][]; - }; - ListProjectsResponse: { - projects: components["schemas"]["ProjectSummary"][]; - }; - ListReviewsResponse: { - reviewerHandleId: string; - reviews: components["schemas"]["ReviewRun"][]; - }; - ListSessionPRsResponse: { - prs: components["schemas"]["SessionPRSummary"][]; - sessionId: string; - }; - ListSessionsResponse: { - sessions: components["schemas"]["ControllersSessionView"][]; - }; - MarkAllNotificationsReadResponse: { - notifications: components["schemas"]["NotificationResponse"][]; - }; - MarkNotificationReadRequest: { - /** - * @description V1 supports only marking an unread notification read. - * @enum {string} - */ - status: "read"; - }; - MergePRResponse: { - method: string; - ok: boolean; - prNumber: number; - }; - NotificationEnvelope: { - notification: components["schemas"]["NotificationResponse"]; - }; - NotificationResponse: { - body: string; - /** Format: date-time */ - createdAt: string; - id: string; - prUrl: string; - projectId: string; - sessionId: string; - /** @enum {string} */ - status: "unread" | "read"; - target: components["schemas"]["NotificationTarget"]; - title: string; - /** @enum {string} */ - type: "needs_input" | "ready_to_merge" | "pr_merged" | "pr_closed_unmerged"; - }; - NotificationTarget: { - /** @enum {string} */ - kind: "session" | "pr"; - prUrl?: string; - sessionId: string; - }; - OrchestratorResponse: { - id: string; - projectId: string; - projectName?: string; - }; - Project: { - agent?: string; - config?: components["schemas"]["ProjectConfig"]; - defaultBranch: string; - id: string; - kind: string; - name: string; - path: string; - repo: string; - workspaceRepos?: components["schemas"]["WorkspaceRepo"][]; - }; - ProjectConfig: { - agentConfig?: components["schemas"]["AgentConfig"]; - defaultBranch?: string; - env?: { - [key: string]: string; - }; - orchestrator?: components["schemas"]["RoleOverride"]; - postCreate?: string[]; - reviewers?: components["schemas"]["DomainReviewerConfig"][]; - sessionPrefix?: string; - symlinks?: string[]; - worker?: components["schemas"]["RoleOverride"]; - }; - ProjectGetResponse: { - project: components["schemas"]["ProjectOrDegraded"]; - /** @enum {string} */ - status: "ok" | "degraded"; - }; - ProjectOrDegraded: components["schemas"]["Project"] | components["schemas"]["DegradedProject"]; - ProjectResponse: { - project: components["schemas"]["Project"]; - }; - ProjectSummary: { - id: string; - kind: string; - name: string; - path: string; - resolveError?: string; - sessionPrefix: string; - }; - RemoveProjectResult: { - projectId: string; - removedStorageDir: boolean; - }; - RenameSessionRequest: { - displayName: string; - }; - RenameSessionResponse: { - displayName: string; - ok: boolean; - sessionId: string; - }; - ResolveCommentsResponse: { - ok: boolean; - resolved: number; - }; - RestoreSessionResponse: { - ok: boolean; - session: components["schemas"]["ControllersSessionView"]; - sessionId: string; - }; - ReviewRun: { - body: string; - /** Format: date-time */ - createdAt: string; - /** Format: date-time */ - deliveredAt?: null | string; - githubReviewId: string; - harness: string; - id: string; - prUrl: string; - reviewId: string; - sessionId: string; - status: string; - targetSha: string; - verdict: string; - }; - ReviewRunResponse: { - review: components["schemas"]["ReviewRun"]; - reviewerHandleId: string; - }; - RoleOverride: { - agent?: string; - agentConfig?: components["schemas"]["AgentConfig"]; - }; - RollbackSessionResponse: { - deleted?: boolean; - killed?: boolean; - ok: boolean; - sessionId: string; - }; - SendSessionMessageRequest: { - message: string; - }; - SendSessionMessageResponse: { - message: string; - ok: boolean; - sessionId: string; - }; - SessionPRCISummary: { - failingChecks: components["schemas"]["SessionPRFailingCheck"][]; - /** @enum {string} */ - state: "unknown" | "pending" | "passing" | "failing"; - }; - SessionPRConflictFile: { - path: string; - url?: string; - }; - SessionPRFacts: { - /** @enum {string} */ - ci: "unknown" | "pending" | "passing" | "failing"; - /** @enum {string} */ - mergeability: "unknown" | "mergeable" | "conflicting" | "blocked" | "unstable"; - number: number; - /** @enum {string} */ - review: "none" | "approved" | "changes_requested" | "review_required"; - reviewComments: boolean; - /** @enum {string} */ - state: "draft" | "open" | "merged" | "closed"; - /** Format: date-time */ - updatedAt: string; - url: string; - }; - SessionPRFailingCheck: { - conclusion: string; - name: string; - /** @enum {string} */ - status: "failed" | "cancelled"; - url?: string; - }; - SessionPRMergeabilitySummary: { - conflictFiles?: components["schemas"]["SessionPRConflictFile"][]; - prUrl: string; - reasons: string[]; - /** @enum {string} */ - state: "unknown" | "mergeable" | "conflicting" | "blocked" | "unstable"; - }; - SessionPRReviewCommentLink: { - file?: string; - line?: number; - url?: string; - }; - SessionPRReviewSummary: { - /** @enum {string} */ - decision: "none" | "approved" | "changes_requested" | "review_required"; - hasUnresolvedHumanComments: boolean; - unresolvedBy: components["schemas"]["SessionPRUnresolvedReviewer"][]; - }; - SessionPRSummary: { - additions: number; - author: string; - changedFiles: number; - ci: components["schemas"]["SessionPRCISummary"]; - /** Format: date-time */ - ciObservedAt?: string; - deletions: number; - headSha: string; - htmlUrl?: string; - mergeability: components["schemas"]["SessionPRMergeabilitySummary"]; - number: number; - /** Format: date-time */ - observedAt?: string; - /** @enum {string} */ - provider: "github"; - repo: string; - review: components["schemas"]["SessionPRReviewSummary"]; - /** Format: date-time */ - reviewObservedAt?: string; - sourceBranch: string; - /** @enum {string} */ - state: "draft" | "open" | "merged" | "closed"; - targetBranch: string; - title: string; - /** Format: date-time */ - updatedAt: string; - url: string; - }; - SessionPRUnresolvedReviewer: { - count: number; - links: components["schemas"]["SessionPRReviewCommentLink"][]; - reviewerId: string; - }; - SessionPreviewResponse: { - entry?: string; - previewUrl?: string; - sessionId: string; - }; - SessionResponse: { - session: components["schemas"]["ControllersSessionView"]; - }; - SetActivityRequest: { - /** - * @description Agent activity state reported by an agent hook. - * @enum {string} - */ - state: "active" | "idle" | "waiting_input" | "exited"; - }; - SetActivityResponse: { - ok: boolean; - sessionId: string; - state: string; - }; - SetProjectConfigInput: { - config: components["schemas"]["ProjectConfig"]; - }; - SetSessionPreviewRequest: { - /** @description Preview target URL. When empty, the daemon autodetects a static entry point in the session workspace. */ - url?: string; - }; - SpawnOrchestratorRequest: { - clean?: boolean; - projectId: string; - }; - SpawnOrchestratorResponse: { - orchestrator: components["schemas"]["OrchestratorResponse"]; - }; - SpawnSessionRequest: { - branch?: string; - /** @enum {string} */ - harness?: "claude-code" | "codex" | "aider" | "opencode" | "grok" | "droid" | "amp" | "agy" | "crush" | "cursor" | "qwen" | "copilot" | "goose" | "auggie" | "continue" | "devin" | "cline" | "kimi" | "kiro" | "kilocode" | "vibe" | "pi" | "autohand"; - issueId?: string; - /** @enum {string} */ - kind?: "worker" | "orchestrator"; - projectId: string; - prompt?: string; - }; - SubmitReviewInput: { - /** @description Review body recorded by AO. Required for changes_requested. */ - body: string; - /** @description Id of the GitHub PR review the reviewer posted, if any. */ - githubReviewId: string; - /** @description Review run id being completed. */ - runId: string; - /** @description Review verdict: approved or changes_requested. */ - verdict: string; - }; - WorkspaceRepo: { - name: string; - relativePath: string; - repo: string; - }; - }; - responses: never; - parameters: never; - requestBodies: never; - headers: never; - pathItems: never; + schemas: { + APIError: { + code: string; + details?: { + [key: string]: unknown; + }; + error: string; + message: string; + requestId?: string; + }; + AddProjectInput: { + asWorkspace?: boolean; + config?: components["schemas"]["ProjectConfig"]; + name?: null | string; + path: string; + projectId?: null | string; + }; + AgentConfig: { + model?: string; + permissions?: string; + }; + ClaimPRRequest: { + allowTakeover?: null | boolean; + pr: string; + }; + ClaimPRResponse: { + branchChanged: boolean; + ok: boolean; + prs: components["schemas"]["SessionPRFacts"][]; + sessionId: string; + takenOverFrom: string[]; + }; + CleanupSessionsResponse: { + cleaned: string[]; + ok: boolean; + skipped: components["schemas"]["CleanupSkippedSession"][]; + }; + CleanupSkippedSession: { + reason: string; + sessionId: string; + }; + ControllersSessionView: { + activity: components["schemas"]["DomainActivity"]; + branch?: string; + /** Format: date-time */ + createdAt: string; + displayName?: string; + harness?: string; + id: string; + isTerminated: boolean; + issueId?: string; + kind: string; + /** Format: int64 */ + previewRevision?: number; + previewUrl?: string; + projectId: string; + prs: components["schemas"]["SessionPRFacts"][]; + /** @enum {string} */ + status: + | "working" + | "pr_open" + | "draft" + | "ci_failed" + | "review_pending" + | "changes_requested" + | "approved" + | "mergeable" + | "merged" + | "needs_input" + | "idle" + | "terminated" + | "no_signal"; + terminalHandleId?: string; + /** Format: date-time */ + updatedAt: string; + }; + DegradedProject: { + id: string; + kind: string; + name: string; + path: string; + resolveError: string; + }; + DomainActivity: { + /** Format: date-time */ + lastActivityAt: string; + state: string; + }; + DomainReviewerConfig: { + harness: string; + }; + KillSessionResponse: { + freed?: boolean; + ok: boolean; + sessionId: string; + }; + ListNotificationsResponse: { + notifications: components["schemas"]["NotificationResponse"][]; + }; + ListProjectsResponse: { + projects: components["schemas"]["ProjectSummary"][]; + }; + ListReviewsResponse: { + reviewerHandleId: string; + reviews: components["schemas"]["ReviewRun"][]; + }; + ListSessionPRsResponse: { + prs: components["schemas"]["SessionPRSummary"][]; + sessionId: string; + }; + ListSessionsResponse: { + sessions: components["schemas"]["ControllersSessionView"][]; + }; + MarkAllNotificationsReadResponse: { + notifications: components["schemas"]["NotificationResponse"][]; + }; + MarkNotificationReadRequest: { + /** + * @description V1 supports only marking an unread notification read. + * @enum {string} + */ + status: "read"; + }; + MergePRResponse: { + method: string; + ok: boolean; + prNumber: number; + }; + NotificationEnvelope: { + notification: components["schemas"]["NotificationResponse"]; + }; + NotificationResponse: { + body: string; + /** Format: date-time */ + createdAt: string; + id: string; + prUrl: string; + projectId: string; + sessionId: string; + /** @enum {string} */ + status: "unread" | "read"; + target: components["schemas"]["NotificationTarget"]; + title: string; + /** @enum {string} */ + type: "needs_input" | "ready_to_merge" | "pr_merged" | "pr_closed_unmerged"; + }; + NotificationTarget: { + /** @enum {string} */ + kind: "session" | "pr"; + prUrl?: string; + sessionId: string; + }; + OrchestratorResponse: { + id: string; + projectId: string; + projectName?: string; + }; + Project: { + agent?: string; + config?: components["schemas"]["ProjectConfig"]; + defaultBranch: string; + id: string; + kind: string; + name: string; + path: string; + repo: string; + workspaceRepos?: components["schemas"]["WorkspaceRepo"][]; + }; + ProjectConfig: { + agentConfig?: components["schemas"]["AgentConfig"]; + defaultBranch?: string; + env?: { + [key: string]: string; + }; + orchestrator?: components["schemas"]["RoleOverride"]; + postCreate?: string[]; + reviewers?: components["schemas"]["DomainReviewerConfig"][]; + sessionPrefix?: string; + symlinks?: string[]; + worker?: components["schemas"]["RoleOverride"]; + }; + ProjectGetResponse: { + project: components["schemas"]["ProjectOrDegraded"]; + /** @enum {string} */ + status: "ok" | "degraded"; + }; + ProjectOrDegraded: components["schemas"]["Project"] | components["schemas"]["DegradedProject"]; + ProjectResponse: { + project: components["schemas"]["Project"]; + }; + ProjectSummary: { + id: string; + kind: string; + name: string; + path: string; + resolveError?: string; + sessionPrefix: string; + }; + RemoveProjectResult: { + projectId: string; + removedStorageDir: boolean; + }; + RenameSessionRequest: { + displayName: string; + }; + RenameSessionResponse: { + displayName: string; + ok: boolean; + sessionId: string; + }; + ResolveCommentsResponse: { + ok: boolean; + resolved: number; + }; + RestoreSessionResponse: { + ok: boolean; + session: components["schemas"]["ControllersSessionView"]; + sessionId: string; + }; + ReviewRun: { + body: string; + /** Format: date-time */ + createdAt: string; + /** Format: date-time */ + deliveredAt?: null | string; + githubReviewId: string; + harness: string; + id: string; + prUrl: string; + reviewId: string; + sessionId: string; + status: string; + targetSha: string; + verdict: string; + }; + ReviewRunResponse: { + review: components["schemas"]["ReviewRun"]; + reviewerHandleId: string; + }; + RoleOverride: { + agent?: string; + agentConfig?: components["schemas"]["AgentConfig"]; + }; + RollbackSessionResponse: { + deleted?: boolean; + killed?: boolean; + ok: boolean; + sessionId: string; + }; + SendSessionMessageRequest: { + message: string; + }; + SendSessionMessageResponse: { + message: string; + ok: boolean; + sessionId: string; + }; + SessionPRCISummary: { + failingChecks: components["schemas"]["SessionPRFailingCheck"][]; + /** @enum {string} */ + state: "unknown" | "pending" | "passing" | "failing"; + }; + SessionPRConflictFile: { + path: string; + url?: string; + }; + SessionPRFacts: { + /** @enum {string} */ + ci: "unknown" | "pending" | "passing" | "failing"; + /** @enum {string} */ + mergeability: "unknown" | "mergeable" | "conflicting" | "blocked" | "unstable"; + number: number; + /** @enum {string} */ + review: "none" | "approved" | "changes_requested" | "review_required"; + reviewComments: boolean; + /** @enum {string} */ + state: "draft" | "open" | "merged" | "closed"; + /** Format: date-time */ + updatedAt: string; + url: string; + }; + SessionPRFailingCheck: { + conclusion: string; + name: string; + /** @enum {string} */ + status: "failed" | "cancelled"; + url?: string; + }; + SessionPRMergeabilitySummary: { + conflictFiles?: components["schemas"]["SessionPRConflictFile"][]; + prUrl: string; + reasons: string[]; + /** @enum {string} */ + state: "unknown" | "mergeable" | "conflicting" | "blocked" | "unstable"; + }; + SessionPRReviewCommentLink: { + file?: string; + line?: number; + url?: string; + }; + SessionPRReviewSummary: { + /** @enum {string} */ + decision: "none" | "approved" | "changes_requested" | "review_required"; + hasUnresolvedHumanComments: boolean; + unresolvedBy: components["schemas"]["SessionPRUnresolvedReviewer"][]; + }; + SessionPRSummary: { + additions: number; + author: string; + changedFiles: number; + ci: components["schemas"]["SessionPRCISummary"]; + /** Format: date-time */ + ciObservedAt?: string; + deletions: number; + headSha: string; + htmlUrl?: string; + mergeability: components["schemas"]["SessionPRMergeabilitySummary"]; + number: number; + /** Format: date-time */ + observedAt?: string; + /** @enum {string} */ + provider: "github"; + repo: string; + review: components["schemas"]["SessionPRReviewSummary"]; + /** Format: date-time */ + reviewObservedAt?: string; + sourceBranch: string; + /** @enum {string} */ + state: "draft" | "open" | "merged" | "closed"; + targetBranch: string; + title: string; + /** Format: date-time */ + updatedAt: string; + url: string; + }; + SessionPRUnresolvedReviewer: { + count: number; + links: components["schemas"]["SessionPRReviewCommentLink"][]; + reviewerId: string; + }; + SessionPreviewResponse: { + entry?: string; + previewUrl?: string; + sessionId: string; + }; + SessionResponse: { + session: components["schemas"]["ControllersSessionView"]; + }; + SetActivityRequest: { + /** + * @description Agent activity state reported by an agent hook. + * @enum {string} + */ + state: "active" | "idle" | "waiting_input" | "exited"; + }; + SetActivityResponse: { + ok: boolean; + sessionId: string; + state: string; + }; + SetProjectConfigInput: { + config: components["schemas"]["ProjectConfig"]; + }; + SetSessionPreviewRequest: { + /** @description Preview target URL. When empty, the daemon autodetects a static entry point in the session workspace. */ + url?: string; + }; + SpawnOrchestratorRequest: { + clean?: boolean; + projectId: string; + }; + SpawnOrchestratorResponse: { + orchestrator: components["schemas"]["OrchestratorResponse"]; + }; + SpawnSessionRequest: { + branch?: string; + /** @enum {string} */ + harness?: + | "claude-code" + | "codex" + | "aider" + | "opencode" + | "grok" + | "droid" + | "amp" + | "agy" + | "crush" + | "cursor" + | "qwen" + | "copilot" + | "goose" + | "auggie" + | "continue" + | "devin" + | "cline" + | "kimi" + | "kiro" + | "kilocode" + | "vibe" + | "pi" + | "autohand"; + issueId?: string; + /** @enum {string} */ + kind?: "worker" | "orchestrator"; + projectId: string; + prompt?: string; + }; + SubmitReviewInput: { + /** @description Review body recorded by AO. Required for changes_requested. */ + body: string; + /** @description Id of the GitHub PR review the reviewer posted, if any. */ + githubReviewId: string; + /** @description Review run id being completed. */ + runId: string; + /** @description Review verdict: approved or changes_requested. */ + verdict: string; + }; + WorkspaceRepo: { + name: string; + relativePath: string; + repo: string; + }; + }; + responses: never; + parameters: never; + requestBodies: never; + headers: never; + pathItems: never; } export type $defs = Record; export interface operations { - streamEvents: { - parameters: { - query?: { - /** @description Replay events with seq greater than this cursor. When omitted, clients may send Last-Event-ID instead. */ - after?: null | number; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "text/event-stream": string; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - listNotifications: { - parameters: { - query?: { - /** @description Notification status filter. V1 supports only unread. */ - status?: "unread"; - /** @description Maximum notifications to return. Defaults to 50; capped at 100. */ - limit?: number; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ListNotificationsResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - markNotificationRead: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Notification identifier. */ - id: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["MarkNotificationReadRequest"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["NotificationEnvelope"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - markAllNotificationsRead: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MarkAllNotificationsReadResponse"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - streamNotifications: { - parameters: { - query?: { - /** @description Optional project id filter for live notifications. */ - projectId?: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "text/event-stream": string; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - listOrchestrators: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ListSessionsResponse"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - spawnOrchestrator: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SpawnOrchestratorRequest"]; - }; - }; - responses: { - /** @description Created */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SpawnOrchestratorResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - getOrchestrator: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Orchestrator session identifier, e.g. project-orchestrator. */ - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SessionResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - listProjects: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ListProjectsResponse"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - addProject: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["AddProjectInput"]; - }; - }; - responses: { - /** @description Created */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ProjectResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Conflict */ - 409: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - getProject: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Project identifier (registry key). */ - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ProjectGetResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - removeProject: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Project identifier (registry key). */ - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RemoveProjectResult"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - setProjectConfig: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Project identifier (registry key). */ - id: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SetProjectConfigInput"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ProjectResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - mergePR: { - parameters: { - query?: never; - header?: never; - path: { - /** @description PR number. */ - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["MergePRResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Conflict */ - 409: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Unprocessable Entity */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - resolveComments: { - parameters: { - query?: never; - header?: never; - path: { - /** @description PR number. */ - id: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ResolveCommentsResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Unprocessable Entity */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - listSessions: { - parameters: { - query?: { - /** @description Project id filter. */ - project?: string; - /** @description When true, return non-terminated sessions; when false, return terminated sessions. */ - active?: null | boolean; - /** @description When true, return only orchestrator sessions. */ - orchestratorOnly?: null | boolean; - /** @description When true, return only fresh non-terminated sessions. */ - fresh?: null | boolean; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ListSessionsResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - spawnSession: { - parameters: { - query?: never; - header?: never; - path?: never; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SpawnSessionRequest"]; - }; - }; - responses: { - /** @description Created */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SessionResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - getSession: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SessionResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - renameSession: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["RenameSessionRequest"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RenameSessionResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - setSessionActivity: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SetActivityRequest"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SetActivityResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - killSession: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["KillSessionResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Conflict */ - 409: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - listSessionPRs: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ListSessionPRsResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - claimSessionPR: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["ClaimPRRequest"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ClaimPRResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Conflict */ - 409: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Unprocessable Entity */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Service Unavailable */ - 503: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - getSessionPreview: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SessionPreviewResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - setSessionPreview: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SetSessionPreviewRequest"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SessionResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - clearSessionPreview: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SessionResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - getSessionPreviewFile: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "text/html": string; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - restoreSession: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RestoreSessionResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Conflict */ - 409: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - listReviews: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ListReviewsResponse"]; - }; - }; - /** @description Unprocessable Entity */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - submitReview: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SubmitReviewInput"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ReviewRunResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Unprocessable Entity */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - triggerReview: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ReviewRunResponse"]; - }; - }; - /** @description Created */ - 201: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["ReviewRunResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Unprocessable Entity */ - 422: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - rollbackSession: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["RollbackSessionResponse"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Conflict */ - 409: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - sendSessionMessage: { - parameters: { - query?: never; - header?: never; - path: { - /** @description Session identifier, e.g. project-1. */ - sessionId: string; - }; - cookie?: never; - }; - requestBody: { - content: { - "application/json": components["schemas"]["SendSessionMessageRequest"]; - }; - }; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["SendSessionMessageResponse"]; - }; - }; - /** @description Bad Request */ - 400: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Found */ - 404: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; - cleanupSessions: { - parameters: { - query?: { - /** @description Project id filter. When omitted, clean terminated sessions across all projects. */ - project?: string; - }; - header?: never; - path?: never; - cookie?: never; - }; - requestBody?: never; - responses: { - /** @description OK */ - 200: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["CleanupSessionsResponse"]; - }; - }; - /** @description Internal Server Error */ - 500: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - /** @description Not Implemented */ - 501: { - headers: { - [name: string]: unknown; - }; - content: { - "application/json": components["schemas"]["APIError"]; - }; - }; - }; - }; + streamEvents: { + parameters: { + query?: { + /** @description Replay events with seq greater than this cursor. When omitted, clients may send Last-Event-ID instead. */ + after?: null | number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/event-stream": string; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + listNotifications: { + parameters: { + query?: { + /** @description Notification status filter. V1 supports only unread. */ + status?: "unread"; + /** @description Maximum notifications to return. Defaults to 50; capped at 100. */ + limit?: number; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ListNotificationsResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + markNotificationRead: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Notification identifier. */ + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["MarkNotificationReadRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["NotificationEnvelope"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + markAllNotificationsRead: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MarkAllNotificationsReadResponse"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + streamNotifications: { + parameters: { + query?: { + /** @description Optional project id filter for live notifications. */ + projectId?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/event-stream": string; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + listOrchestrators: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ListSessionsResponse"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + spawnOrchestrator: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SpawnOrchestratorRequest"]; + }; + }; + responses: { + /** @description Created */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SpawnOrchestratorResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + getOrchestrator: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Orchestrator session identifier, e.g. project-orchestrator. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SessionResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + listProjects: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ListProjectsResponse"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + addProject: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["AddProjectInput"]; + }; + }; + responses: { + /** @description Created */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProjectResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + getProject: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Project identifier (registry key). */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProjectGetResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + removeProject: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Project identifier (registry key). */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RemoveProjectResult"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + setProjectConfig: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Project identifier (registry key). */ + id: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetProjectConfigInput"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ProjectResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + mergePR: { + parameters: { + query?: never; + header?: never; + path: { + /** @description PR number. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["MergePRResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Unprocessable Entity */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + resolveComments: { + parameters: { + query?: never; + header?: never; + path: { + /** @description PR number. */ + id: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ResolveCommentsResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Unprocessable Entity */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + listSessions: { + parameters: { + query?: { + /** @description Project id filter. */ + project?: string; + /** @description When true, return non-terminated sessions; when false, return terminated sessions. */ + active?: null | boolean; + /** @description When true, return only orchestrator sessions. */ + orchestratorOnly?: null | boolean; + /** @description When true, return only fresh non-terminated sessions. */ + fresh?: null | boolean; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ListSessionsResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + spawnSession: { + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SpawnSessionRequest"]; + }; + }; + responses: { + /** @description Created */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SessionResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + getSession: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SessionResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + renameSession: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["RenameSessionRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RenameSessionResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + setSessionActivity: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetActivityRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SetActivityResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + killSession: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["KillSessionResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + listSessionPRs: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ListSessionPRsResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + claimSessionPR: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["ClaimPRRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ClaimPRResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Unprocessable Entity */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Service Unavailable */ + 503: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + getSessionPreview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SessionPreviewResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + setSessionPreview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SetSessionPreviewRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SessionResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + clearSessionPreview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SessionResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + getSessionPreviewFile: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "text/html": string; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + restoreSession: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RestoreSessionResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + listReviews: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ListReviewsResponse"]; + }; + }; + /** @description Unprocessable Entity */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + submitReview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SubmitReviewInput"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReviewRunResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Unprocessable Entity */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + triggerReview: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReviewRunResponse"]; + }; + }; + /** @description Created */ + 201: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["ReviewRunResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Unprocessable Entity */ + 422: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + rollbackSession: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["RollbackSessionResponse"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Conflict */ + 409: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + sendSessionMessage: { + parameters: { + query?: never; + header?: never; + path: { + /** @description Session identifier, e.g. project-1. */ + sessionId: string; + }; + cookie?: never; + }; + requestBody: { + content: { + "application/json": components["schemas"]["SendSessionMessageRequest"]; + }; + }; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["SendSessionMessageResponse"]; + }; + }; + /** @description Bad Request */ + 400: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Found */ + 404: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; + cleanupSessions: { + parameters: { + query?: { + /** @description Project id filter. When omitted, clean terminated sessions across all projects. */ + project?: string; + }; + header?: never; + path?: never; + cookie?: never; + }; + requestBody?: never; + responses: { + /** @description OK */ + 200: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["CleanupSessionsResponse"]; + }; + }; + /** @description Internal Server Error */ + 500: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + /** @description Not Implemented */ + 501: { + headers: { + [name: string]: unknown; + }; + content: { + "application/json": components["schemas"]["APIError"]; + }; + }; + }; + }; } diff --git a/packages/desktop/src/renderer/routeTree.gen.ts b/packages/desktop/src/renderer/routeTree.gen.ts index 6a13a2dee..ffe4cdc41 100644 --- a/packages/desktop/src/renderer/routeTree.gen.ts +++ b/packages/desktop/src/renderer/routeTree.gen.ts @@ -8,188 +8,183 @@ // You should NOT make any changes in this file as it will be overwritten. // Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified. -import { Route as rootRouteImport } from './routes/__root' -import { Route as ShellRouteImport } from './routes/_shell' -import { Route as ShellIndexRouteImport } from './routes/_shell.index' -import { Route as ShellPrsRouteImport } from './routes/_shell.prs' -import { Route as ShellSessionsSessionIdRouteImport } from './routes/_shell.sessions.$sessionId' -import { Route as ShellProjectsProjectIdRouteImport } from './routes/_shell.projects.$projectId' -import { Route as ShellProjectsProjectIdSettingsRouteImport } from './routes/_shell.projects.$projectId_.settings' -import { Route as ShellProjectsProjectIdSessionsSessionIdRouteImport } from './routes/_shell.projects.$projectId_.sessions.$sessionId' +import { Route as rootRouteImport } from "./routes/__root"; +import { Route as ShellRouteImport } from "./routes/_shell"; +import { Route as ShellIndexRouteImport } from "./routes/_shell.index"; +import { Route as ShellPrsRouteImport } from "./routes/_shell.prs"; +import { Route as ShellSessionsSessionIdRouteImport } from "./routes/_shell.sessions.$sessionId"; +import { Route as ShellProjectsProjectIdRouteImport } from "./routes/_shell.projects.$projectId"; +import { Route as ShellProjectsProjectIdSettingsRouteImport } from "./routes/_shell.projects.$projectId_.settings"; +import { Route as ShellProjectsProjectIdSessionsSessionIdRouteImport } from "./routes/_shell.projects.$projectId_.sessions.$sessionId"; const ShellRoute = ShellRouteImport.update({ - id: '/_shell', - getParentRoute: () => rootRouteImport, -} as any) + id: "/_shell", + getParentRoute: () => rootRouteImport, +} as any); const ShellIndexRoute = ShellIndexRouteImport.update({ - id: '/', - path: '/', - getParentRoute: () => ShellRoute, -} as any) + id: "/", + path: "/", + getParentRoute: () => ShellRoute, +} as any); const ShellPrsRoute = ShellPrsRouteImport.update({ - id: '/prs', - path: '/prs', - getParentRoute: () => ShellRoute, -} as any) + id: "/prs", + path: "/prs", + getParentRoute: () => ShellRoute, +} as any); const ShellSessionsSessionIdRoute = ShellSessionsSessionIdRouteImport.update({ - id: '/sessions/$sessionId', - path: '/sessions/$sessionId', - getParentRoute: () => ShellRoute, -} as any) + id: "/sessions/$sessionId", + path: "/sessions/$sessionId", + getParentRoute: () => ShellRoute, +} as any); const ShellProjectsProjectIdRoute = ShellProjectsProjectIdRouteImport.update({ - id: '/projects/$projectId', - path: '/projects/$projectId', - getParentRoute: () => ShellRoute, -} as any) -const ShellProjectsProjectIdSettingsRoute = - ShellProjectsProjectIdSettingsRouteImport.update({ - id: '/projects/$projectId_/settings', - path: '/projects/$projectId/settings', - getParentRoute: () => ShellRoute, - } as any) -const ShellProjectsProjectIdSessionsSessionIdRoute = - ShellProjectsProjectIdSessionsSessionIdRouteImport.update({ - id: '/projects/$projectId_/sessions/$sessionId', - path: '/projects/$projectId/sessions/$sessionId', - getParentRoute: () => ShellRoute, - } as any) + id: "/projects/$projectId", + path: "/projects/$projectId", + getParentRoute: () => ShellRoute, +} as any); +const ShellProjectsProjectIdSettingsRoute = ShellProjectsProjectIdSettingsRouteImport.update({ + id: "/projects/$projectId_/settings", + path: "/projects/$projectId/settings", + getParentRoute: () => ShellRoute, +} as any); +const ShellProjectsProjectIdSessionsSessionIdRoute = ShellProjectsProjectIdSessionsSessionIdRouteImport.update({ + id: "/projects/$projectId_/sessions/$sessionId", + path: "/projects/$projectId/sessions/$sessionId", + getParentRoute: () => ShellRoute, +} as any); export interface FileRoutesByFullPath { - '/': typeof ShellIndexRoute - '/prs': typeof ShellPrsRoute - '/projects/$projectId': typeof ShellProjectsProjectIdRoute - '/sessions/$sessionId': typeof ShellSessionsSessionIdRoute - '/projects/$projectId/settings': typeof ShellProjectsProjectIdSettingsRoute - '/projects/$projectId/sessions/$sessionId': typeof ShellProjectsProjectIdSessionsSessionIdRoute + "/": typeof ShellIndexRoute; + "/prs": typeof ShellPrsRoute; + "/projects/$projectId": typeof ShellProjectsProjectIdRoute; + "/sessions/$sessionId": typeof ShellSessionsSessionIdRoute; + "/projects/$projectId/settings": typeof ShellProjectsProjectIdSettingsRoute; + "/projects/$projectId/sessions/$sessionId": typeof ShellProjectsProjectIdSessionsSessionIdRoute; } export interface FileRoutesByTo { - '/prs': typeof ShellPrsRoute - '/': typeof ShellIndexRoute - '/projects/$projectId': typeof ShellProjectsProjectIdRoute - '/sessions/$sessionId': typeof ShellSessionsSessionIdRoute - '/projects/$projectId/settings': typeof ShellProjectsProjectIdSettingsRoute - '/projects/$projectId/sessions/$sessionId': typeof ShellProjectsProjectIdSessionsSessionIdRoute + "/prs": typeof ShellPrsRoute; + "/": typeof ShellIndexRoute; + "/projects/$projectId": typeof ShellProjectsProjectIdRoute; + "/sessions/$sessionId": typeof ShellSessionsSessionIdRoute; + "/projects/$projectId/settings": typeof ShellProjectsProjectIdSettingsRoute; + "/projects/$projectId/sessions/$sessionId": typeof ShellProjectsProjectIdSessionsSessionIdRoute; } export interface FileRoutesById { - __root__: typeof rootRouteImport - '/_shell': typeof ShellRouteWithChildren - '/_shell/prs': typeof ShellPrsRoute - '/_shell/': typeof ShellIndexRoute - '/_shell/projects/$projectId': typeof ShellProjectsProjectIdRoute - '/_shell/sessions/$sessionId': typeof ShellSessionsSessionIdRoute - '/_shell/projects/$projectId_/settings': typeof ShellProjectsProjectIdSettingsRoute - '/_shell/projects/$projectId_/sessions/$sessionId': typeof ShellProjectsProjectIdSessionsSessionIdRoute + __root__: typeof rootRouteImport; + "/_shell": typeof ShellRouteWithChildren; + "/_shell/prs": typeof ShellPrsRoute; + "/_shell/": typeof ShellIndexRoute; + "/_shell/projects/$projectId": typeof ShellProjectsProjectIdRoute; + "/_shell/sessions/$sessionId": typeof ShellSessionsSessionIdRoute; + "/_shell/projects/$projectId_/settings": typeof ShellProjectsProjectIdSettingsRoute; + "/_shell/projects/$projectId_/sessions/$sessionId": typeof ShellProjectsProjectIdSessionsSessionIdRoute; } export interface FileRouteTypes { - fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: - | '/' - | '/prs' - | '/projects/$projectId' - | '/sessions/$sessionId' - | '/projects/$projectId/settings' - | '/projects/$projectId/sessions/$sessionId' - fileRoutesByTo: FileRoutesByTo - to: - | '/prs' - | '/' - | '/projects/$projectId' - | '/sessions/$sessionId' - | '/projects/$projectId/settings' - | '/projects/$projectId/sessions/$sessionId' - id: - | '__root__' - | '/_shell' - | '/_shell/prs' - | '/_shell/' - | '/_shell/projects/$projectId' - | '/_shell/sessions/$sessionId' - | '/_shell/projects/$projectId_/settings' - | '/_shell/projects/$projectId_/sessions/$sessionId' - fileRoutesById: FileRoutesById + fileRoutesByFullPath: FileRoutesByFullPath; + fullPaths: + | "/" + | "/prs" + | "/projects/$projectId" + | "/sessions/$sessionId" + | "/projects/$projectId/settings" + | "/projects/$projectId/sessions/$sessionId"; + fileRoutesByTo: FileRoutesByTo; + to: + | "/prs" + | "/" + | "/projects/$projectId" + | "/sessions/$sessionId" + | "/projects/$projectId/settings" + | "/projects/$projectId/sessions/$sessionId"; + id: + | "__root__" + | "/_shell" + | "/_shell/prs" + | "/_shell/" + | "/_shell/projects/$projectId" + | "/_shell/sessions/$sessionId" + | "/_shell/projects/$projectId_/settings" + | "/_shell/projects/$projectId_/sessions/$sessionId"; + fileRoutesById: FileRoutesById; } export interface RootRouteChildren { - ShellRoute: typeof ShellRouteWithChildren + ShellRoute: typeof ShellRouteWithChildren; } -declare module '@tanstack/react-router' { - interface FileRoutesByPath { - '/_shell': { - id: '/_shell' - path: '' - fullPath: '/' - preLoaderRoute: typeof ShellRouteImport - parentRoute: typeof rootRouteImport - } - '/_shell/': { - id: '/_shell/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof ShellIndexRouteImport - parentRoute: typeof ShellRoute - } - '/_shell/prs': { - id: '/_shell/prs' - path: '/prs' - fullPath: '/prs' - preLoaderRoute: typeof ShellPrsRouteImport - parentRoute: typeof ShellRoute - } - '/_shell/sessions/$sessionId': { - id: '/_shell/sessions/$sessionId' - path: '/sessions/$sessionId' - fullPath: '/sessions/$sessionId' - preLoaderRoute: typeof ShellSessionsSessionIdRouteImport - parentRoute: typeof ShellRoute - } - '/_shell/projects/$projectId': { - id: '/_shell/projects/$projectId' - path: '/projects/$projectId' - fullPath: '/projects/$projectId' - preLoaderRoute: typeof ShellProjectsProjectIdRouteImport - parentRoute: typeof ShellRoute - } - '/_shell/projects/$projectId_/settings': { - id: '/_shell/projects/$projectId_/settings' - path: '/projects/$projectId/settings' - fullPath: '/projects/$projectId/settings' - preLoaderRoute: typeof ShellProjectsProjectIdSettingsRouteImport - parentRoute: typeof ShellRoute - } - '/_shell/projects/$projectId_/sessions/$sessionId': { - id: '/_shell/projects/$projectId_/sessions/$sessionId' - path: '/projects/$projectId/sessions/$sessionId' - fullPath: '/projects/$projectId/sessions/$sessionId' - preLoaderRoute: typeof ShellProjectsProjectIdSessionsSessionIdRouteImport - parentRoute: typeof ShellRoute - } - } +declare module "@tanstack/react-router" { + interface FileRoutesByPath { + "/_shell": { + id: "/_shell"; + path: ""; + fullPath: "/"; + preLoaderRoute: typeof ShellRouteImport; + parentRoute: typeof rootRouteImport; + }; + "/_shell/": { + id: "/_shell/"; + path: "/"; + fullPath: "/"; + preLoaderRoute: typeof ShellIndexRouteImport; + parentRoute: typeof ShellRoute; + }; + "/_shell/prs": { + id: "/_shell/prs"; + path: "/prs"; + fullPath: "/prs"; + preLoaderRoute: typeof ShellPrsRouteImport; + parentRoute: typeof ShellRoute; + }; + "/_shell/sessions/$sessionId": { + id: "/_shell/sessions/$sessionId"; + path: "/sessions/$sessionId"; + fullPath: "/sessions/$sessionId"; + preLoaderRoute: typeof ShellSessionsSessionIdRouteImport; + parentRoute: typeof ShellRoute; + }; + "/_shell/projects/$projectId": { + id: "/_shell/projects/$projectId"; + path: "/projects/$projectId"; + fullPath: "/projects/$projectId"; + preLoaderRoute: typeof ShellProjectsProjectIdRouteImport; + parentRoute: typeof ShellRoute; + }; + "/_shell/projects/$projectId_/settings": { + id: "/_shell/projects/$projectId_/settings"; + path: "/projects/$projectId/settings"; + fullPath: "/projects/$projectId/settings"; + preLoaderRoute: typeof ShellProjectsProjectIdSettingsRouteImport; + parentRoute: typeof ShellRoute; + }; + "/_shell/projects/$projectId_/sessions/$sessionId": { + id: "/_shell/projects/$projectId_/sessions/$sessionId"; + path: "/projects/$projectId/sessions/$sessionId"; + fullPath: "/projects/$projectId/sessions/$sessionId"; + preLoaderRoute: typeof ShellProjectsProjectIdSessionsSessionIdRouteImport; + parentRoute: typeof ShellRoute; + }; + } } interface ShellRouteChildren { - ShellPrsRoute: typeof ShellPrsRoute - ShellIndexRoute: typeof ShellIndexRoute - ShellProjectsProjectIdRoute: typeof ShellProjectsProjectIdRoute - ShellSessionsSessionIdRoute: typeof ShellSessionsSessionIdRoute - ShellProjectsProjectIdSettingsRoute: typeof ShellProjectsProjectIdSettingsRoute - ShellProjectsProjectIdSessionsSessionIdRoute: typeof ShellProjectsProjectIdSessionsSessionIdRoute + ShellPrsRoute: typeof ShellPrsRoute; + ShellIndexRoute: typeof ShellIndexRoute; + ShellProjectsProjectIdRoute: typeof ShellProjectsProjectIdRoute; + ShellSessionsSessionIdRoute: typeof ShellSessionsSessionIdRoute; + ShellProjectsProjectIdSettingsRoute: typeof ShellProjectsProjectIdSettingsRoute; + ShellProjectsProjectIdSessionsSessionIdRoute: typeof ShellProjectsProjectIdSessionsSessionIdRoute; } const ShellRouteChildren: ShellRouteChildren = { - ShellPrsRoute: ShellPrsRoute, - ShellIndexRoute: ShellIndexRoute, - ShellProjectsProjectIdRoute: ShellProjectsProjectIdRoute, - ShellSessionsSessionIdRoute: ShellSessionsSessionIdRoute, - ShellProjectsProjectIdSettingsRoute: ShellProjectsProjectIdSettingsRoute, - ShellProjectsProjectIdSessionsSessionIdRoute: - ShellProjectsProjectIdSessionsSessionIdRoute, -} + ShellPrsRoute: ShellPrsRoute, + ShellIndexRoute: ShellIndexRoute, + ShellProjectsProjectIdRoute: ShellProjectsProjectIdRoute, + ShellSessionsSessionIdRoute: ShellSessionsSessionIdRoute, + ShellProjectsProjectIdSettingsRoute: ShellProjectsProjectIdSettingsRoute, + ShellProjectsProjectIdSessionsSessionIdRoute: ShellProjectsProjectIdSessionsSessionIdRoute, +}; -const ShellRouteWithChildren = ShellRoute._addFileChildren(ShellRouteChildren) +const ShellRouteWithChildren = ShellRoute._addFileChildren(ShellRouteChildren); const rootRouteChildren: RootRouteChildren = { - ShellRoute: ShellRouteWithChildren, -} -export const routeTree = rootRouteImport - ._addFileChildren(rootRouteChildren) - ._addFileTypes() + ShellRoute: ShellRouteWithChildren, +}; +export const routeTree = rootRouteImport._addFileChildren(rootRouteChildren)._addFileTypes(); diff --git a/packages/shared/jest.config.js b/packages/shared/jest.config.js index 6184fb157..34585ed1b 100644 --- a/packages/shared/jest.config.js +++ b/packages/shared/jest.config.js @@ -1,31 +1,29 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ export default { - preset: 'ts-jest/presets/default', - testEnvironment: 'jsdom', - testMatch: ['**/src/**/*.test.ts', '**/src/**/*.test.tsx'], - moduleNameMapper: { - '^(\\.{1,2}/.*)\\.js$': '$1', - '^react$': '/node_modules/react', - '^react-dom$': '/node_modules/react-dom', - }, - transform: { - '^.+\\.tsx?$': [ - 'ts-jest', - { - tsconfig: { - types: ['jest'], - jsx: 'react', - module: 'ESNext', - moduleResolution: 'bundler', - allowSyntheticDefaultImports: true, - esModuleInterop: true, - }, - }, - ], - }, - transformIgnorePatterns: [ - 'node_modules/(?!(react|react-dom|@tanstack/react-query|@testing-library)/)', - ], - setupFilesAfterEnv: ['/jest.setup.cjs'], - moduleDirectories: ['node_modules', '/node_modules'], -}; \ No newline at end of file + preset: "ts-jest/presets/default", + testEnvironment: "jsdom", + testMatch: ["**/src/**/*.test.ts", "**/src/**/*.test.tsx"], + moduleNameMapper: { + "^(\\.{1,2}/.*)\\.js$": "$1", + "^react$": "/node_modules/react", + "^react-dom$": "/node_modules/react-dom", + }, + transform: { + "^.+\\.tsx?$": [ + "ts-jest", + { + tsconfig: { + types: ["jest"], + jsx: "react", + module: "ESNext", + moduleResolution: "bundler", + allowSyntheticDefaultImports: true, + esModuleInterop: true, + }, + }, + ], + }, + transformIgnorePatterns: ["node_modules/(?!(react|react-dom|@tanstack/react-query|@testing-library)/)"], + setupFilesAfterEnv: ["/jest.setup.cjs"], + moduleDirectories: ["node_modules", "/node_modules"], +}; diff --git a/packages/shared/jest.setup.cjs b/packages/shared/jest.setup.cjs index 62818747c..290de0c7c 100644 --- a/packages/shared/jest.setup.cjs +++ b/packages/shared/jest.setup.cjs @@ -1 +1 @@ -module.exports = require('@testing-library/jest-dom'); +module.exports = require("@testing-library/jest-dom"); diff --git a/packages/shared/package.json b/packages/shared/package.json index 7707cf428..63084525d 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -1,32 +1,32 @@ { - "name": "@agent-orchestrator/shared", - "version": "0.0.0", - "private": true, - "main": "./dist/index.js", - "types": "./dist/index.d.ts", - "scripts": { - "build": "tsc", - "typecheck": "tsc --noEmit", - "test": "jest" - }, - "dependencies": { - "@tanstack/react-query": "^5.0.0", - "eventsource": "^2.0.0", - "zustand": "^4.0.0" - }, - "devDependencies": { - "@jest/globals": "^30.4.1", - "@testing-library/jest-dom": "^6.9.1", - "@testing-library/react": "^14.3.1", - "@types/jest": "^29.0.0", - "@types/react": "^18.0.0", - "jest": "^29.0.0", - "jest-environment-jsdom": "^30.4.1", - "react": "^18.3.1", - "react-dom": "^18.3.1", - "typescript": "^5.0.0" - }, - "peerDependencies": { - "react": "^18.0.0" - } + "name": "@agent-orchestrator/shared", + "version": "0.0.0", + "private": true, + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "scripts": { + "build": "tsc", + "typecheck": "tsc --noEmit", + "test": "jest" + }, + "dependencies": { + "@tanstack/react-query": "^5.0.0", + "eventsource": "^2.0.0", + "zustand": "^4.0.0" + }, + "devDependencies": { + "@jest/globals": "^30.4.1", + "@testing-library/jest-dom": "^6.9.1", + "@testing-library/react": "^14.3.1", + "@types/jest": "^29.0.0", + "@types/react": "^18.0.0", + "jest": "^29.0.0", + "jest-environment-jsdom": "^30.4.1", + "react": "^18.3.1", + "react-dom": "^18.3.1", + "typescript": "^5.0.0" + }, + "peerDependencies": { + "react": "^18.0.0" + } } diff --git a/packages/shared/src/api/client.ts b/packages/shared/src/api/client.ts index 25c0e1a79..24f409dd4 100644 --- a/packages/shared/src/api/client.ts +++ b/packages/shared/src/api/client.ts @@ -1,97 +1,97 @@ // packages/shared/src/api/client.ts -import { getPlatformBridge } from '../lib/bridge'; +import { getPlatformBridge } from "../lib/bridge"; export interface RequestOptions { - method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH'; - body?: any; - headers?: Record; + method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; + body?: any; + headers?: Record; } export class ApiError extends Error { - constructor( - public status: number, - public statusText: string, - public body?: any - ) { - super(`API Error ${status}: ${statusText}`); - this.name = 'ApiError'; - } + constructor( + public status: number, + public statusText: string, + public body?: any, + ) { + super(`API Error ${status}: ${statusText}`); + this.name = "ApiError"; + } } export class ApiClient { - private authToken?: string; + private authToken?: string; - constructor(authToken?: string) { - this.authToken = authToken; - } + constructor(authToken?: string) { + this.authToken = authToken; + } - private getBaseUrl(): string { - return getPlatformBridge().getApiBaseUrl(); - } + private getBaseUrl(): string { + return getPlatformBridge().getApiBaseUrl(); + } - private getDefaultHeaders(): Record { - const headers: Record = { - 'Content-Type': 'application/json', - }; + private getDefaultHeaders(): Record { + const headers: Record = { + "Content-Type": "application/json", + }; - if (this.authToken) { - headers['Authorization'] = `Bearer ${this.authToken}`; - } + if (this.authToken) { + headers["Authorization"] = `Bearer ${this.authToken}`; + } - return headers; - } + return headers; + } - async request(path: string, options: RequestOptions = {}): Promise { - const baseUrl = this.getBaseUrl(); - const url = `${baseUrl}${path}`; + async request(path: string, options: RequestOptions = {}): Promise { + const baseUrl = this.getBaseUrl(); + const url = `${baseUrl}${path}`; - const response = await fetch(url, { - method: options.method || 'GET', - headers: { - ...this.getDefaultHeaders(), - ...options.headers, - }, - body: options.body ? JSON.stringify(options.body) : undefined, - }); + const response = await fetch(url, { + method: options.method || "GET", + headers: { + ...this.getDefaultHeaders(), + ...options.headers, + }, + body: options.body ? JSON.stringify(options.body) : undefined, + }); - if (!response.ok) { - const body = await response.json().catch(() => undefined); - throw new ApiError(response.status, response.statusText, body); - } + if (!response.ok) { + const body = await response.json().catch(() => undefined); + throw new ApiError(response.status, response.statusText, body); + } - // Handle 204 No Content - if (response.status === 204) { - return undefined as T; - } + // Handle 204 No Content + if (response.status === 204) { + return undefined as T; + } - return response.json(); - } + return response.json(); + } - async get(path: string, headers?: Record): Promise { - return this.request(path, { method: 'GET', headers }); - } + async get(path: string, headers?: Record): Promise { + return this.request(path, { method: "GET", headers }); + } - async post(path: string, body: any, headers?: Record): Promise { - return this.request(path, { method: 'POST', body, headers }); - } + async post(path: string, body: any, headers?: Record): Promise { + return this.request(path, { method: "POST", body, headers }); + } - async put(path: string, body: any, headers?: Record): Promise { - return this.request(path, { method: 'PUT', body, headers }); - } + async put(path: string, body: any, headers?: Record): Promise { + return this.request(path, { method: "PUT", body, headers }); + } - async delete(path: string, headers?: Record): Promise { - return this.request(path, { method: 'DELETE', headers }); - } + async delete(path: string, headers?: Record): Promise { + return this.request(path, { method: "DELETE", headers }); + } - async patch(path: string, body: any, headers?: Record): Promise { - return this.request(path, { method: 'PATCH', body, headers }); - } + async patch(path: string, body: any, headers?: Record): Promise { + return this.request(path, { method: "PATCH", body, headers }); + } - setAuthToken(token: string): void { - this.authToken = token; - } + setAuthToken(token: string): void { + this.authToken = token; + } - clearAuthToken(): void { - this.authToken = undefined; - } + clearAuthToken(): void { + this.authToken = undefined; + } } diff --git a/packages/shared/src/api/paths.ts b/packages/shared/src/api/paths.ts index a9c279554..d477faaf3 100644 --- a/packages/shared/src/api/paths.ts +++ b/packages/shared/src/api/paths.ts @@ -1,6 +1,6 @@ // packages/shared/src/api/paths.ts // API path constants export const API_PATHS = { - workspaces: '/api/v1/workspaces', - sessions: '/api/v1/sessions', + workspaces: "/api/v1/workspaces", + sessions: "/api/v1/sessions", } as const; diff --git a/packages/shared/src/api/types.ts b/packages/shared/src/api/types.ts index 511a58135..ef46d0f8d 100644 --- a/packages/shared/src/api/types.ts +++ b/packages/shared/src/api/types.ts @@ -3,11 +3,11 @@ // This file is a placeholder for generated types export interface ApiResponse { - data: T; + data: T; } export interface ApiErrorResponse { - error: string; - message: string; - details?: Record; + error: string; + message: string; + details?: Record; } diff --git a/packages/shared/src/hooks/useDaemonStatus.ts b/packages/shared/src/hooks/useDaemonStatus.ts index fd58a9a27..d369b1d33 100644 --- a/packages/shared/src/hooks/useDaemonStatus.ts +++ b/packages/shared/src/hooks/useDaemonStatus.ts @@ -1,36 +1,36 @@ // packages/shared/src/hooks/useDaemonStatus.ts -import { useEffect, useState } from 'react'; -import { getPlatformBridge, DaemonStatus } from '../lib/bridge'; +import { useEffect, useState } from "react"; +import { getPlatformBridge, DaemonStatus } from "../lib/bridge"; export function useDaemonStatus() { - const [status, setStatus] = useState({ running: false, port: 0 }); - const [loading, setLoading] = useState(true); + const [status, setStatus] = useState({ running: false, port: 0 }); + const [loading, setLoading] = useState(true); - useEffect(() => { - let mounted = true; + useEffect(() => { + let mounted = true; - const checkStatus = async () => { - try { - const bridge = getPlatformBridge(); - const currentStatus = await bridge.getDaemonStatus(); - if (mounted) { - setStatus(currentStatus); - setLoading(false); - } - } catch (error) { - if (mounted) { - setStatus({ running: false, port: 0 }); - setLoading(false); - } - } - }; + const checkStatus = async () => { + try { + const bridge = getPlatformBridge(); + const currentStatus = await bridge.getDaemonStatus(); + if (mounted) { + setStatus(currentStatus); + setLoading(false); + } + } catch (error) { + if (mounted) { + setStatus({ running: false, port: 0 }); + setLoading(false); + } + } + }; - checkStatus(); + checkStatus(); - return () => { - mounted = false; - }; - }, []); + return () => { + mounted = false; + }; + }, []); - return { status, loading }; + return { status, loading }; } diff --git a/packages/shared/src/hooks/useWorkspaceQuery.test.tsx b/packages/shared/src/hooks/useWorkspaceQuery.test.tsx index 59b880dab..d5a78fdec 100644 --- a/packages/shared/src/hooks/useWorkspaceQuery.test.tsx +++ b/packages/shared/src/hooks/useWorkspaceQuery.test.tsx @@ -1,56 +1,52 @@ // packages/shared/src/hooks/useWorkspaceQuery.test.tsx -import React from 'react'; -import { describe, it, expect, beforeEach } from '@jest/globals'; -import { renderHook, waitFor } from '@testing-library/react'; -import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; -import { useWorkspaceQuery } from './useWorkspaceQuery'; -import { ApiClient } from '../api/client'; -import { setPlatformBridge } from '../lib/bridge'; +import React from "react"; +import { describe, it, expect, beforeEach } from "@jest/globals"; +import { renderHook, waitFor } from "@testing-library/react"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { useWorkspaceQuery } from "./useWorkspaceQuery"; +import { ApiClient } from "../api/client"; +import { setPlatformBridge } from "../lib/bridge"; -describe('useWorkspaceQuery', () => { - let queryClient: QueryClient; +describe("useWorkspaceQuery", () => { + let queryClient: QueryClient; - beforeEach(() => { - queryClient = new QueryClient({ - defaultOptions: { - queries: { retry: false }, - }, - }); + beforeEach(() => { + queryClient = new QueryClient({ + defaultOptions: { + queries: { retry: false }, + }, + }); - setPlatformBridge({ - getDaemonStatus: async () => ({ running: true, port: 3001 }), - startDaemon: async () => {}, - stopDaemon: async () => {}, - getApiBaseUrl: () => 'http://test:3001', - subscribeApiBaseUrl: () => () => {}, - }); - }); + setPlatformBridge({ + getDaemonStatus: async () => ({ running: true, port: 3001 }), + startDaemon: async () => {}, + stopDaemon: async () => {}, + getApiBaseUrl: () => "http://test:3001", + subscribeApiBaseUrl: () => () => {}, + }); + }); - it('should fetch workspace data', async () => { - const mockWorkspaces = [ - { id: '1', name: 'Project A', sessions: [] }, - { id: '2', name: 'Project B', sessions: [] }, - ]; + it("should fetch workspace data", async () => { + const mockWorkspaces = [ + { id: "1", name: "Project A", sessions: [] }, + { id: "2", name: "Project B", sessions: [] }, + ]; - globalThis.fetch = globalThis.fetch || jest.fn(); - (globalThis.fetch as jest.Mock).mockResolvedValue({ - ok: true, - json: async () => ({ workspaces: mockWorkspaces }), - }); + globalThis.fetch = globalThis.fetch || jest.fn(); + (globalThis.fetch as jest.Mock).mockResolvedValue({ + ok: true, + json: async () => ({ workspaces: mockWorkspaces }), + }); - const { result } = renderHook(() => useWorkspaceQuery(), { - wrapper: ({ children }) => ( - - {children} - - ), - }); + const { result } = renderHook(() => useWorkspaceQuery(), { + wrapper: ({ children }) => {children}, + }); - // Trigger the query and wait for it to complete - const refetchPromise = result.current.refetch(); - await waitFor(() => expect(result.current.isSuccess).toBe(true)); - await refetchPromise; + // Trigger the query and wait for it to complete + const refetchPromise = result.current.refetch(); + await waitFor(() => expect(result.current.isSuccess).toBe(true)); + await refetchPromise; - expect(result.current.data).toEqual({ workspaces: mockWorkspaces }); - }); + expect(result.current.data).toEqual({ workspaces: mockWorkspaces }); + }); }); diff --git a/packages/shared/src/hooks/useWorkspaceQuery.ts b/packages/shared/src/hooks/useWorkspaceQuery.ts index 26cc3002c..4188c365f 100644 --- a/packages/shared/src/hooks/useWorkspaceQuery.ts +++ b/packages/shared/src/hooks/useWorkspaceQuery.ts @@ -1,45 +1,45 @@ // packages/shared/src/hooks/useWorkspaceQuery.ts -import { useQuery } from '@tanstack/react-query'; -import { ApiClient } from '../api/client'; +import { useQuery } from "@tanstack/react-query"; +import { ApiClient } from "../api/client"; export interface Session { - id: string; - projectId: string; - agent: string; - status: string; - createdAt: string; + id: string; + projectId: string; + agent: string; + status: string; + createdAt: string; } export interface Project { - id: string; - name: string; - sessions: Session[]; + id: string; + name: string; + sessions: Session[]; } export interface WorkspaceResponse { - workspaces: Project[]; + workspaces: Project[]; } -const WORKSPACE_QUERY_KEY = ['workspaces'] as const; +const WORKSPACE_QUERY_KEY = ["workspaces"] as const; export function useWorkspaceQuery(client?: ApiClient) { - const apiClient = client || new ApiClient(); + const apiClient = client || new ApiClient(); - const query = useQuery({ - queryKey: WORKSPACE_QUERY_KEY, - queryFn: async () => { - const response = await apiClient.get('/api/v1/workspaces'); - return response; - }, - enabled: false, // Manually refetch on SSE events - refetchOnMount: false, - refetchOnWindowFocus: false, - }); + const query = useQuery({ + queryKey: WORKSPACE_QUERY_KEY, + queryFn: async () => { + const response = await apiClient.get("/api/v1/workspaces"); + return response; + }, + enabled: false, // Manually refetch on SSE events + refetchOnMount: false, + refetchOnWindowFocus: false, + }); - return { - ...query, - refetch: () => query.refetch(), - }; + return { + ...query, + refetch: () => query.refetch(), + }; } export { WORKSPACE_QUERY_KEY }; diff --git a/packages/shared/src/index.ts b/packages/shared/src/index.ts index 6fd690a89..7dfbf5f71 100644 --- a/packages/shared/src/index.ts +++ b/packages/shared/src/index.ts @@ -1,9 +1,9 @@ // packages/shared/src/index.ts -export * from './api/client'; -export * from './api/paths'; -export * from './api/types'; -export * from './lib/bridge'; -export * from './lib/event-transport'; -export * from './lib/events-connection'; -export * from './hooks/useWorkspaceQuery'; -export * from './hooks/useDaemonStatus'; +export * from "./api/client"; +export * from "./api/paths"; +export * from "./api/types"; +export * from "./lib/bridge"; +export * from "./lib/event-transport"; +export * from "./lib/events-connection"; +export * from "./hooks/useWorkspaceQuery"; +export * from "./hooks/useDaemonStatus"; diff --git a/packages/shared/src/lib/bridge.ts b/packages/shared/src/lib/bridge.ts index a050684c1..a2d61cc45 100644 --- a/packages/shared/src/lib/bridge.ts +++ b/packages/shared/src/lib/bridge.ts @@ -1,28 +1,28 @@ export interface DaemonStatus { - running: boolean; - port: number; + running: boolean; + port: number; } export interface PlatformBridge { - // Daemon lifecycle - getDaemonStatus: () => Promise; - startDaemon: () => Promise; - stopDaemon: () => Promise; + // Daemon lifecycle + getDaemonStatus: () => Promise; + startDaemon: () => Promise; + stopDaemon: () => Promise; - // API base URL resolution - getApiBaseUrl: () => string; - subscribeApiBaseUrl: (callback: (url: string) => void) => () => void; + // API base URL resolution + getApiBaseUrl: () => string; + subscribeApiBaseUrl: (callback: (url: string) => void) => () => void; } let platformBridgeInstance: PlatformBridge | null = null; export function setPlatformBridge(bridge: PlatformBridge): void { - platformBridgeInstance = bridge; + platformBridgeInstance = bridge; } export function getPlatformBridge(): PlatformBridge { - if (!platformBridgeInstance) { - throw new Error('PlatformBridge not initialized. Call setPlatformBridge() first.'); - } - return platformBridgeInstance; + if (!platformBridgeInstance) { + throw new Error("PlatformBridge not initialized. Call setPlatformBridge() first."); + } + return platformBridgeInstance; } diff --git a/packages/shared/src/lib/event-transport.test.ts b/packages/shared/src/lib/event-transport.test.ts index aa579d0bf..b58cc88e0 100644 --- a/packages/shared/src/lib/event-transport.test.ts +++ b/packages/shared/src/lib/event-transport.test.ts @@ -1,31 +1,31 @@ // packages/shared/src/lib/event-transport.test.ts -import { describe, it, expect, beforeEach } from '@jest/globals'; -import { createEventTransport } from './event-transport'; -import { QueryClient } from '@tanstack/react-query'; -import { setPlatformBridge } from './bridge'; +import { describe, it, expect, beforeEach } from "@jest/globals"; +import { createEventTransport } from "./event-transport"; +import { QueryClient } from "@tanstack/react-query"; +import { setPlatformBridge } from "./bridge"; -describe('EventTransport', () => { - let queryClient: QueryClient; +describe("EventTransport", () => { + let queryClient: QueryClient; - beforeEach(() => { - queryClient = new QueryClient(); - setPlatformBridge({ - getDaemonStatus: async () => ({ running: true, port: 3001 }), - startDaemon: async () => {}, - stopDaemon: async () => {}, - getApiBaseUrl: () => 'http://test:3001', - subscribeApiBaseUrl: () => () => {}, - }); - }); + beforeEach(() => { + queryClient = new QueryClient(); + setPlatformBridge({ + getDaemonStatus: async () => ({ running: true, port: 3001 }), + startDaemon: async () => {}, + stopDaemon: async () => {}, + getApiBaseUrl: () => "http://test:3001", + subscribeApiBaseUrl: () => () => {}, + }); + }); - it('should create transport with connect method', () => { - const transport = createEventTransport(queryClient); - expect(typeof transport.connect).toBe('function'); - }); + it("should create transport with connect method", () => { + const transport = createEventTransport(queryClient); + expect(typeof transport.connect).toBe("function"); + }); - it('should return cleanup function from connect', () => { - const transport = createEventTransport(queryClient); - const cleanup = transport.connect(); - expect(typeof cleanup).toBe('function'); - }); + it("should return cleanup function from connect", () => { + const transport = createEventTransport(queryClient); + const cleanup = transport.connect(); + expect(typeof cleanup).toBe("function"); + }); }); diff --git a/packages/shared/src/lib/event-transport.ts b/packages/shared/src/lib/event-transport.ts index 1d5c58d2d..b1c7aa78b 100644 --- a/packages/shared/src/lib/event-transport.ts +++ b/packages/shared/src/lib/event-transport.ts @@ -1,11 +1,11 @@ // packages/shared/src/lib/event-transport.ts -import type { QueryClient } from '@tanstack/react-query'; -import { getPlatformBridge } from './bridge'; -import { setEventsConnectionState } from './events-connection'; -import { WORKSPACE_QUERY_KEY } from '../hooks/useWorkspaceQuery'; +import type { QueryClient } from "@tanstack/react-query"; +import { getPlatformBridge } from "./bridge"; +import { setEventsConnectionState } from "./events-connection"; +import { WORKSPACE_QUERY_KEY } from "../hooks/useWorkspaceQuery"; export type EventTransport = { - connect: () => () => void; + connect: () => () => void; }; const INVALIDATE_DEBOUNCE_MS = 150; @@ -13,77 +13,77 @@ const SSE_RETRY_MS = 5_000; const EVENTSOURCE_CLOSED = 2; const CDC_EVENT_TYPES = [ - 'session_created', - 'session_updated', - 'pr_created', - 'pr_updated', - 'pr_check_recorded', - 'pr_session_changed', - 'pr_review_thread_added', - 'pr_review_thread_resolved', + "session_created", + "session_updated", + "pr_created", + "pr_updated", + "pr_check_recorded", + "pr_session_changed", + "pr_review_thread_added", + "pr_review_thread_resolved", ] as const; export function createEventTransport(queryClient: QueryClient): EventTransport { - return { - connect() { - let debounce: ReturnType | undefined; - let retryTimer: ReturnType | undefined; - let source: EventSource | undefined; - let sourceBaseUrl: string | undefined; + return { + connect() { + let debounce: ReturnType | undefined; + let retryTimer: ReturnType | undefined; + let source: EventSource | undefined; + let sourceBaseUrl: string | undefined; - const refreshWorkspaces = () => { - if (debounce) clearTimeout(debounce); - debounce = setTimeout(() => { - void queryClient.invalidateQueries({ queryKey: WORKSPACE_QUERY_KEY }); - }, INVALIDATE_DEBOUNCE_MS); - }; + const refreshWorkspaces = () => { + if (debounce) clearTimeout(debounce); + debounce = setTimeout(() => { + void queryClient.invalidateQueries({ queryKey: WORKSPACE_QUERY_KEY }); + }, INVALIDATE_DEBOUNCE_MS); + }; - const scheduleRetry = () => { - if (retryTimer) return; - retryTimer = setTimeout(() => { - retryTimer = undefined; - connectSource(); - }, SSE_RETRY_MS); - }; + const scheduleRetry = () => { + if (retryTimer) return; + retryTimer = setTimeout(() => { + retryTimer = undefined; + connectSource(); + }, SSE_RETRY_MS); + }; - const bridge = getPlatformBridge(); + const bridge = getPlatformBridge(); - const connectSource = () => { - if (typeof EventSource === 'undefined') return; - const baseUrl = bridge.getApiBaseUrl(); - if (source && sourceBaseUrl === baseUrl && source.readyState !== EVENTSOURCE_CLOSED) return; - source?.close(); - source = undefined; - sourceBaseUrl = baseUrl; - try { - source = new EventSource(`${baseUrl.replace(/\/+$/, '')}/api/v1/events`); - source.onopen = () => { - setEventsConnectionState('connected'); - refreshWorkspaces(); - }; - source.onerror = () => { - setEventsConnectionState('disconnected'); - if (source?.readyState === EVENTSOURCE_CLOSED) scheduleRetry(); - }; - source.onmessage = refreshWorkspaces; - for (const type of CDC_EVENT_TYPES) { - source.addEventListener(type, refreshWorkspaces); - } - } catch { - source = undefined; - } - }; + const connectSource = () => { + if (typeof EventSource === "undefined") return; + const baseUrl = bridge.getApiBaseUrl(); + if (source && sourceBaseUrl === baseUrl && source.readyState !== EVENTSOURCE_CLOSED) return; + source?.close(); + source = undefined; + sourceBaseUrl = baseUrl; + try { + source = new EventSource(`${baseUrl.replace(/\/+$/, "")}/api/v1/events`); + source.onopen = () => { + setEventsConnectionState("connected"); + refreshWorkspaces(); + }; + source.onerror = () => { + setEventsConnectionState("disconnected"); + if (source?.readyState === EVENTSOURCE_CLOSED) scheduleRetry(); + }; + source.onmessage = refreshWorkspaces; + for (const type of CDC_EVENT_TYPES) { + source.addEventListener(type, refreshWorkspaces); + } + } catch { + source = undefined; + } + }; - const removeBaseUrlListener = bridge.subscribeApiBaseUrl(connectSource); - connectSource(); + const removeBaseUrlListener = bridge.subscribeApiBaseUrl(connectSource); + connectSource(); - return () => { - if (debounce) clearTimeout(debounce); - if (retryTimer) clearTimeout(retryTimer); - removeBaseUrlListener(); - source?.close(); - setEventsConnectionState('idle'); - }; - }, - }; + return () => { + if (debounce) clearTimeout(debounce); + if (retryTimer) clearTimeout(retryTimer); + removeBaseUrlListener(); + source?.close(); + setEventsConnectionState("idle"); + }; + }, + }; } diff --git a/packages/shared/src/lib/events-connection.ts b/packages/shared/src/lib/events-connection.ts index 1ba73c0ad..a138dbd4c 100644 --- a/packages/shared/src/lib/events-connection.ts +++ b/packages/shared/src/lib/events-connection.ts @@ -1,22 +1,20 @@ // packages/shared/src/lib/events-connection.ts -type ConnectionState = 'idle' | 'connecting' | 'connected' | 'disconnected'; +type ConnectionState = "idle" | "connecting" | "connected" | "disconnected"; -let connectionState: ConnectionState = 'idle'; +let connectionState: ConnectionState = "idle"; const listeners: Set<(state: ConnectionState) => void> = new Set(); export function setEventsConnectionState(state: ConnectionState): void { - connectionState = state; - listeners.forEach((listener) => listener(state)); + connectionState = state; + listeners.forEach((listener) => listener(state)); } export function getEventsConnectionState(): ConnectionState { - return connectionState; + return connectionState; } -export function subscribeEventsConnectionState( - callback: (state: ConnectionState) => void -): () => void { - listeners.add(callback); - callback(connectionState); - return () => listeners.delete(callback); +export function subscribeEventsConnectionState(callback: (state: ConnectionState) => void): () => void { + listeners.add(callback); + callback(connectionState); + return () => listeners.delete(callback); } diff --git a/packages/shared/tsconfig.json b/packages/shared/tsconfig.json index 5944f7e71..5e21d37bb 100644 --- a/packages/shared/tsconfig.json +++ b/packages/shared/tsconfig.json @@ -1,19 +1,19 @@ { - "compilerOptions": { - "target": "ES2020", - "module": "ESNext", - "lib": ["ES2020", "DOM"], - "moduleResolution": "bundler", - "jsx": "react-jsx", - "strict": true, - "esModuleInterop": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true, - "resolveJsonModule": true, - "declaration": true, - "outDir": "./dist", - "rootDir": "./src" - }, - "include": ["src/**/*"], - "exclude": ["node_modules", "dist", "**/*.test.ts"] + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "lib": ["ES2020", "DOM"], + "moduleResolution": "bundler", + "jsx": "react-jsx", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "resolveJsonModule": true, + "declaration": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "**/*.test.ts"] }