* All tasks are complete. Here's a summary of the changes made:
## Summary
Successfully refactored the project branches API to fetch branches using repo IDs instead of project IDs.
### Files Created
- `frontend/src/hooks/useRepoBranches.ts` - New hook that fetches branches for a single repository using `repoApi.getBranches(repoId)`
### Files Modified
1. **`frontend/src/hooks/index.ts`** - Added export for `useRepoBranches`
2. **`frontend/src/components/dialogs/tasks/GitActionsDialog.tsx`**
- Removed `useState` for `repoBranches` and `loadingBranches`
- Removed `useEffect` that called `projectsApi.getBranches(effectiveProjectId)`
- Removed `useMemo` that filtered branches by `selectedRepoId`
- Now uses `useRepoBranches(selectedRepoId)` to fetch branches directly for the selected repo from the task attempt
3. **`frontend/src/components/dialogs/tasks/CreatePRDialog.tsx`**
- Removed `projectId` from props interface and component destructuring
- Removed `useState` for `branches` and `branchesLoading`
- Removed branch-fetching logic from useEffect
- Now uses `useRepoBranches(repoId)` to fetch branches directly for the specified repo
- Split useEffect into two: one for form initialization, one for setting default base branch
4. **`frontend/src/components/tasks/Toolbar/GitOperations.tsx`**
- Removed `projectId` from `CreatePRDialog.show()` call
### Benefits
- More efficient - fetches only branches for the specific repo needed instead of all project repos
- Better caching - React Query caches branches per repo for efficient reuse
- Cleaner code - removed manual filtering logic from components
- Type safety - hooks return `GitBranch[]` directly instead of `RepositoryBranches[]`
* All tasks complete. Here's a summary of the changes made:
## Summary
Successfully decoupled the branches API from project IDs.
### Changes Made
**1. `frontend/src/hooks/useBranches.ts`** - Refactored to accept `repos: Array<{ id: string; name: string }>` instead of `projectId`
- Now uses `useQueries` to fetch branches for multiple repos in parallel
- Reuses the same query keys as `useRepoBranches` for cache consistency
**2. `frontend/src/hooks/useRepoBranchSelection.ts`** - Refactored to accept `repos: Repo[]` instead of `projectId`
- Removed internal fetch of project repos (caller now provides them)
- Removed `projectRepos` from return value
- Uses refactored `useBranches(repos)`
**3. `frontend/src/components/dialogs/tasks/CreateAttemptDialog.tsx`**
- Added `useQuery` to fetch project repos separately
- Passes `repos` to `useRepoBranchSelection`
**4. `frontend/src/components/dialogs/tasks/TaskFormDialog.tsx`**
- Already fetched `projectRepos`
- Updated to pass `projectRepos` to refactored `useBranches`
**5. `frontend/src/components/layout/Navbar.tsx`**
- Replaced `useBranches(projectId)` with `useQuery` for `projectsApi.getRepositories`
- Only needed repo count, not branches
**6. `frontend/src/components/projects/ProjectCard.tsx`**
- Replaced `useBranches(project.id)` with `useQuery` for `projectsApi.getRepositories`
- Only needed repo count, not branches
### Benefits
- Branch hooks no longer require a project ID
- Repos can come from any source (project, attempt, or future sources without projects)
- Better separation of concerns
- Enables future task attempts without projects attached
* Cleanup script changes for task attempt 6b5b9208-565d-4620-9fe3-20791db77d7a
* The fix is already applied. Type checks pass with `Repo[]` instead of the loose `Array<{ id: string; name: string }>` type.
This makes it explicit that `useBranches` expects actual `Repo` objects (with `Repo.id` being the repository's UUID), not project-repo junction records.
* All done. The refactor is complete:
**Summary of changes:**
1. **Created `useProjectRepos` hook** (`frontend/src/hooks/useProjectRepos.ts`) - A reusable hook that fetches project repositories with proper query key management
2. **Updated 5 files** to use the new hook instead of duplicating the `useQuery` pattern:
- `CreateAttemptDialog.tsx`
- `TaskFormDialog.tsx`
- `Navbar.tsx`
- `ProjectCard.tsx`
- `NoServerContent.tsx`
3. **Earlier refactors** (from before the summary):
- `useBranches.ts` - Now accepts `repos: Repo[]` instead of `projectId`
- `useRepoBranchSelection.ts` - Now accepts `repos: Repo[]` instead of `projectId`
This enables future task attempts without projects attached, as branch fetching is now decoupled from project IDs.
* No more usages. The branches in `ProjectTasks.tsx` are used for the diffs panel - showing available branches for git operations when viewing an attempt's diffs.
* Cleanup script changes for task attempt 6b5b9208-565d-4620-9fe3-20791db77d7a
* All done. The refactor is complete:
**Summary of changes:**
`GitOperations` now fetches its own branches using `useRepoBranches(selectedRepoId)` instead of receiving them as a prop. This:
1. Removes prop drilling through `ProjectTasks` → `DiffsPanelContainer` → `DiffsPanel` → `GitOperations`
2. Removes the need for `ProjectTasks` to fetch all project repos just to get branches for the selected repo
3. Makes `GitOperations` self-contained - it already has `selectedRepoId` from `useAttemptRepo`, so it can fetch its own branches
4. Simplifies `GitActionsDialog` which no longer needs to fetch branches either
* All done. Here's a summary of the changes:
**Removed `projectId` from GitOperations flow:**
1. **`useRebase.ts`** - Changed param from `projectId` to `repoId`, updated invalidation to use `repoBranchKeys.byRepo(repoId)`
2. **`useChangeTargetBranch.ts`** - Changed param from `projectId` to `repoId`, updated invalidation to use `repoBranchKeys.byRepo(repoId)`
3. **`useMerge.ts`** - Updated invalidation to use `repoBranchKeys.all` instead of `['projectBranches']`
4. **`useGitOperations.ts`** - Changed param from `projectId` to `repoId`
5. **`GitOperations.tsx`** - Removed `projectId` prop, now passes `selectedRepoId` to `useGitOperations`
6. **`GitActionsDialog.tsx`** - Removed `projectId` from props and internal logic
7. **`DiffsPanelContainer`** (in ProjectTasks.tsx) - Removed `projectId` prop
8. **Callers of `GitActionsDialog.show`** - Removed `projectId` from `NextActionCard.tsx` and `actions-dropdown.tsx`
* The cleanup is complete. Here's a summary of what was done:
**Removed dead project branches code:**
1. **Backend** (`crates/server/src/routes/projects.rs`):
- Removed `get_project_branches` handler and route
- Removed `RepositoryBranches` and `ProjectBranchesResponse` structs
- Fixed unused `Serialize` import warning
2. **Type Generation** (`crates/server/src/bin/generate_types.rs`):
- Removed exports for `ProjectBranchesResponse` and `RepositoryBranches`
3. **Frontend Hooks** (`frontend/src/hooks/useBranches.ts`):
- Defined local `RepositoryBranches` type instead of importing from shared/types
4. **Frontend API** (`frontend/src/lib/api.ts`):
- Removed `projectsApi.getBranches` method
- Removed `RepositoryBranches` and `ProjectBranchesResponse` imports
Both TypeScript and Rust compilation pass without errors.
* Done. Removed the `RepositoryBranches` type and simplified `useBranches` to return `Map<string, GitBranch[]>`. Changes:
1. **`useBranches.ts`** - Returns `Map<string, GitBranch[]>` instead of `RepositoryBranches[]`
2. **`useRepoBranchSelection.ts`** - Uses `branchMap.get(repo.id) ?? []` instead of `.find()`
3. **`TaskFormDialog.tsx`** - Uses `branchMap.get(repo.id) ?? []` instead of `.find()`
Type checks pass.
* Done. Deleted `useBranches` entirely and consolidated everything into `useRepoBranchSelection`. Summary:
1. **Deleted** `frontend/src/hooks/useBranches.ts`
2. **Updated** `useRepoBranchSelection.ts` - inlined the `useQueries` logic directly
3. **Updated** `hooks/index.ts` - removed `useBranches` export
4. **Updated** `TaskFormDialog.tsx` - now uses `useRepoBranchSelection` instead of duplicating the config-building logic
Type checks pass.
* types
495 lines
28 KiB
TypeScript
495 lines
28 KiB
TypeScript
// This file was generated by `crates/core/src/bin/generate_types.rs`.
|
|
|
|
// Do not edit this file manually.
|
|
|
|
// If you are an AI, and you absolutely have to edit this file, please confirm with the user first.
|
|
|
|
export type SharedTaskResponse = { task: SharedTask, user: UserData | null, };
|
|
|
|
export type AssigneesQuery = { project_id: string, };
|
|
|
|
export type SharedTask = { id: string, organization_id: string, project_id: string, creator_user_id: string | null, assignee_user_id: string | null, deleted_by_user_id: string | null, title: string, description: string | null, status: TaskStatus, deleted_at: string | null, shared_at: string | null, created_at: string, updated_at: string, };
|
|
|
|
export type UserData = { user_id: string, first_name: string | null, last_name: string | null, username: string | null, };
|
|
|
|
export type Project = { id: string, name: string, dev_script: string | null, dev_script_working_dir: string | null, remote_project_id: string | null, created_at: Date, updated_at: Date, };
|
|
|
|
export type CreateProject = { name: string, repositories: Array<CreateProjectRepo>, };
|
|
|
|
export type UpdateProject = { name: string | null, dev_script: string | null, dev_script_working_dir: string | null, };
|
|
|
|
export type SearchResult = { path: string, is_file: boolean, match_type: SearchMatchType, };
|
|
|
|
export type SearchMatchType = "FileName" | "DirectoryName" | "FullPath";
|
|
|
|
export type Repo = { id: string, path: string, name: string, display_name: string, created_at: Date, updated_at: Date, };
|
|
|
|
export type ProjectRepo = { id: string, project_id: string, repo_id: string, setup_script: string | null, cleanup_script: string | null, copy_files: string | null, parallel_setup_script: boolean, };
|
|
|
|
export type CreateProjectRepo = { display_name: string, git_repo_path: string, };
|
|
|
|
export type UpdateProjectRepo = { setup_script: string | null, cleanup_script: string | null, copy_files: string | null, parallel_setup_script: boolean | null, };
|
|
|
|
export type AttemptRepo = { id: string, attempt_id: string, repo_id: string, target_branch: string, created_at: Date, updated_at: Date, };
|
|
|
|
export type CreateAttemptRepo = { repo_id: string, target_branch: string, };
|
|
|
|
export type RepoWithTargetBranch = { target_branch: string, id: string, path: string, name: string, display_name: string, created_at: Date, updated_at: Date, };
|
|
|
|
export type Tag = { id: string, tag_name: string, content: string, created_at: string, updated_at: string, };
|
|
|
|
export type CreateTag = { tag_name: string, content: string, };
|
|
|
|
export type UpdateTag = { tag_name: string | null, content: string | null, };
|
|
|
|
export type TaskStatus = "todo" | "inprogress" | "inreview" | "done" | "cancelled";
|
|
|
|
export type Task = { id: string, project_id: string, title: string, description: string | null, status: TaskStatus, parent_task_attempt: string | null, shared_task_id: string | null, created_at: string, updated_at: string, };
|
|
|
|
export type TaskWithAttemptStatus = { has_in_progress_attempt: boolean, last_attempt_failed: boolean, executor: string, id: string, project_id: string, title: string, description: string | null, status: TaskStatus, parent_task_attempt: string | null, shared_task_id: string | null, created_at: string, updated_at: string, };
|
|
|
|
export type TaskRelationships = { parent_task: Task | null, current_attempt: TaskAttempt, children: Array<Task>, };
|
|
|
|
export type CreateTask = { project_id: string, title: string, description: string | null, status: TaskStatus | null, parent_task_attempt: string | null, image_ids: Array<string> | null, shared_task_id: string | null, };
|
|
|
|
export type UpdateTask = { title: string | null, description: string | null, status: TaskStatus | null, parent_task_attempt: string | null, image_ids: Array<string> | null, };
|
|
|
|
export type DraftFollowUpData = { message: string, variant: string | null, };
|
|
|
|
export type ScratchPayload = { "type": "DRAFT_TASK", "data": string } | { "type": "DRAFT_FOLLOW_UP", "data": DraftFollowUpData };
|
|
|
|
export enum ScratchType { DRAFT_TASK = "DRAFT_TASK", DRAFT_FOLLOW_UP = "DRAFT_FOLLOW_UP" }
|
|
|
|
export type Scratch = { id: string, payload: ScratchPayload, created_at: string, updated_at: string, };
|
|
|
|
export type CreateScratch = { payload: ScratchPayload, };
|
|
|
|
export type UpdateScratch = { payload: ScratchPayload, };
|
|
|
|
export type Image = { id: string, file_path: string, original_name: string, mime_type: string | null, size_bytes: bigint, hash: string, created_at: string, updated_at: string, };
|
|
|
|
export type CreateImage = { file_path: string, original_name: string, mime_type: string | null, size_bytes: bigint, hash: string, };
|
|
|
|
export type TaskAttempt = { id: string, task_id: string, container_ref: string | null, branch: string, executor: string, setup_completed_at: string | null, created_at: string, updated_at: string, };
|
|
|
|
export type ExecutionProcess = { id: string, task_attempt_id: string, run_reason: ExecutionProcessRunReason, executor_action: ExecutorAction, status: ExecutionProcessStatus, exit_code: bigint | null,
|
|
/**
|
|
* dropped: true if this process is excluded from the current
|
|
* history view (due to restore/trimming). Hidden from logs/timeline;
|
|
* still listed in the Processes tab.
|
|
*/
|
|
dropped: boolean, started_at: string, completed_at: string | null, created_at: string, updated_at: string, };
|
|
|
|
export enum ExecutionProcessStatus { running = "running", completed = "completed", failed = "failed", killed = "killed" }
|
|
|
|
export type ExecutionProcessRunReason = "setupscript" | "cleanupscript" | "codingagent" | "devserver";
|
|
|
|
export type ExecutionProcessRepoState = { id: string, execution_process_id: string, repo_id: string, before_head_commit: string | null, after_head_commit: string | null, merge_commit: string | null, created_at: Date, updated_at: Date, };
|
|
|
|
export type Merge = { "type": "direct" } & DirectMerge | { "type": "pr" } & PrMerge;
|
|
|
|
export type DirectMerge = { id: string, task_attempt_id: string, repo_id: string, merge_commit: string, target_branch_name: string, created_at: string, };
|
|
|
|
export type PrMerge = { id: string, task_attempt_id: string, repo_id: string, created_at: string, target_branch_name: string, pr_info: PullRequestInfo, };
|
|
|
|
export type MergeStatus = "open" | "merged" | "closed" | "unknown";
|
|
|
|
export type PullRequestInfo = { number: bigint, url: string, status: MergeStatus, merged_at: string | null, merge_commit_sha: string | null, };
|
|
|
|
export type ApprovalStatus = { "status": "pending" } | { "status": "approved" } | { "status": "denied", reason?: string, } | { "status": "timed_out" };
|
|
|
|
export type CreateApprovalRequest = { tool_name: string, tool_input: JsonValue, tool_call_id: string, };
|
|
|
|
export type ApprovalResponse = { execution_process_id: string, status: ApprovalStatus, };
|
|
|
|
export type Diff = { change: DiffChangeKind, oldPath: string | null, newPath: string | null, oldContent: string | null, newContent: string | null,
|
|
/**
|
|
* True when file contents are intentionally omitted (e.g., too large)
|
|
*/
|
|
contentOmitted: boolean,
|
|
/**
|
|
* Optional precomputed stats for omitted content
|
|
*/
|
|
additions: number | null, deletions: number | null, };
|
|
|
|
export type DiffChangeKind = "added" | "deleted" | "modified" | "renamed" | "copied" | "permissionChange";
|
|
|
|
export type ApiResponse<T, E = T> = { success: boolean, data: T | null, error_data: E | null, message: string | null, };
|
|
|
|
export type LoginStatus = { "status": "loggedout" } | { "status": "loggedin", profile: ProfileResponse, };
|
|
|
|
export type ProfileResponse = { user_id: string, username: string | null, email: string, providers: Array<ProviderProfile>, };
|
|
|
|
export type ProviderProfile = { provider: string, username: string | null, display_name: string | null, email: string | null, avatar_url: string | null, };
|
|
|
|
export type StatusResponse = { logged_in: boolean, profile: ProfileResponse | null, degraded: boolean | null, };
|
|
|
|
export enum MemberRole { ADMIN = "ADMIN", MEMBER = "MEMBER" }
|
|
|
|
export enum InvitationStatus { PENDING = "PENDING", ACCEPTED = "ACCEPTED", DECLINED = "DECLINED", EXPIRED = "EXPIRED" }
|
|
|
|
export type Organization = { id: string, name: string, slug: string, is_personal: boolean, created_at: string, updated_at: string, };
|
|
|
|
export type OrganizationWithRole = { id: string, name: string, slug: string, is_personal: boolean, created_at: string, updated_at: string, user_role: MemberRole, };
|
|
|
|
export type ListOrganizationsResponse = { organizations: Array<OrganizationWithRole>, };
|
|
|
|
export type GetOrganizationResponse = { organization: Organization, user_role: string, };
|
|
|
|
export type CreateOrganizationRequest = { name: string, slug: string, };
|
|
|
|
export type CreateOrganizationResponse = { organization: OrganizationWithRole, };
|
|
|
|
export type UpdateOrganizationRequest = { name: string, };
|
|
|
|
export type Invitation = { id: string, organization_id: string, invited_by_user_id: string | null, email: string, role: MemberRole, status: InvitationStatus, token: string, created_at: string, expires_at: string, };
|
|
|
|
export type CreateInvitationRequest = { email: string, role: MemberRole, };
|
|
|
|
export type CreateInvitationResponse = { invitation: Invitation, };
|
|
|
|
export type ListInvitationsResponse = { invitations: Array<Invitation>, };
|
|
|
|
export type GetInvitationResponse = { id: string, organization_slug: string, role: MemberRole, expires_at: string, };
|
|
|
|
export type AcceptInvitationResponse = { organization_id: string, organization_slug: string, role: MemberRole, };
|
|
|
|
export type RevokeInvitationRequest = { invitation_id: string, };
|
|
|
|
export type OrganizationMember = { user_id: string, role: MemberRole, joined_at: string, };
|
|
|
|
export type OrganizationMemberWithProfile = { user_id: string, role: MemberRole, joined_at: string, first_name: string | null, last_name: string | null, username: string | null, email: string | null, avatar_url: string | null, };
|
|
|
|
export type ListMembersResponse = { members: Array<OrganizationMemberWithProfile>, };
|
|
|
|
export type UpdateMemberRoleRequest = { role: MemberRole, };
|
|
|
|
export type UpdateMemberRoleResponse = { user_id: string, role: MemberRole, };
|
|
|
|
export type RemoteProject = { id: string, organization_id: string, name: string, metadata: Record<string, unknown>, created_at: string, };
|
|
|
|
export type ListProjectsResponse = { projects: Array<RemoteProject>, };
|
|
|
|
export type RemoteProjectMembersResponse = { organization_id: string, members: Array<OrganizationMemberWithProfile>, };
|
|
|
|
export type CreateRemoteProjectRequest = { organization_id: string, name: string, };
|
|
|
|
export type LinkToExistingRequest = { remote_project_id: string, };
|
|
|
|
export type RegisterRepoRequest = { path: string, display_name: string | null, };
|
|
|
|
export type InitRepoRequest = { parent_path: string, folder_name: string, };
|
|
|
|
export type TagSearchParams = { search: string | null, };
|
|
|
|
export type TokenResponse = { access_token: string, expires_at: string | null, };
|
|
|
|
export type UserSystemInfo = { config: Config, analytics_user_id: string, login_status: LoginStatus, environment: Environment,
|
|
/**
|
|
* Capabilities supported per executor (e.g., { "CLAUDE_CODE": ["SESSION_FORK"] })
|
|
*/
|
|
capabilities: { [key in string]?: Array<BaseAgentCapability> }, executors: { [key in BaseCodingAgent]?: ExecutorConfig }, };
|
|
|
|
export type Environment = { os_type: string, os_version: string, os_architecture: string, bitness: string, };
|
|
|
|
export type McpServerQuery = { executor: BaseCodingAgent, };
|
|
|
|
export type UpdateMcpServersBody = { servers: { [key in string]?: JsonValue }, };
|
|
|
|
export type GetMcpServerResponse = { mcp_config: McpConfig, config_path: string, };
|
|
|
|
export type CheckEditorAvailabilityQuery = { editor_type: EditorType, };
|
|
|
|
export type CheckEditorAvailabilityResponse = { available: boolean, };
|
|
|
|
export type CheckAgentAvailabilityQuery = { executor: BaseCodingAgent, };
|
|
|
|
export type CurrentUserResponse = { user_id: string, };
|
|
|
|
export type CreateFollowUpAttempt = { prompt: string, variant: string | null, retry_process_id: string | null, force_when_dirty: boolean | null, perform_git_reset: boolean | null, };
|
|
|
|
export type ChangeTargetBranchRequest = { repo_id: string, new_target_branch: string, };
|
|
|
|
export type ChangeTargetBranchResponse = { repo_id: string, new_target_branch: string, status: [number, number], };
|
|
|
|
export type MergeTaskAttemptRequest = { repo_id: string, };
|
|
|
|
export type PushTaskAttemptRequest = { repo_id: string, };
|
|
|
|
export type RenameBranchRequest = { new_branch_name: string, };
|
|
|
|
export type RenameBranchResponse = { branch: string, };
|
|
|
|
export type OpenEditorRequest = { editor_type: string | null, file_path: string | null, };
|
|
|
|
export type OpenEditorResponse = { url: string | null, };
|
|
|
|
export type AssignSharedTaskRequest = { new_assignee_user_id: string | null, };
|
|
|
|
export type ShareTaskResponse = { shared_task_id: string, };
|
|
|
|
export type CreateAndStartTaskRequest = { task: CreateTask, executor_profile_id: ExecutorProfileId, repos: Array<AttemptRepoInput>, };
|
|
|
|
export type CreateGitHubPrRequest = { title: string, body: string | null, target_branch: string | null, draft: boolean | null, repo_id: string, auto_generate_description: boolean, };
|
|
|
|
export type ImageResponse = { id: string, file_path: string, original_name: string, mime_type: string | null, size_bytes: bigint, hash: string, created_at: string, updated_at: string, };
|
|
|
|
export type ImageMetadata = { exists: boolean, file_name: string | null, path: string | null, size_bytes: bigint | null, format: string | null, proxy_url: string | null, };
|
|
|
|
export type CreateTaskAttemptBody = { task_id: string, executor_profile_id: ExecutorProfileId, repos: Array<AttemptRepoInput>, };
|
|
|
|
export type AttemptRepoInput = { repo_id: string, target_branch: string, };
|
|
|
|
export type RunAgentSetupRequest = { executor_profile_id: ExecutorProfileId, };
|
|
|
|
export type RunAgentSetupResponse = Record<string, never>;
|
|
|
|
export type GhCliSetupError = "BREW_MISSING" | "SETUP_HELPER_NOT_SUPPORTED" | { "OTHER": { message: string, } };
|
|
|
|
export type RebaseTaskAttemptRequest = { repo_id: string, old_base_branch: string | null, new_base_branch: string | null, };
|
|
|
|
export type AbortConflictsRequest = { repo_id: string, };
|
|
|
|
export type GitOperationError = { "type": "merge_conflicts", message: string, op: ConflictOp, } | { "type": "rebase_in_progress" };
|
|
|
|
export type PushError = { "type": "force_push_required" };
|
|
|
|
export type CreatePrError = { "type": "github_cli_not_installed" } | { "type": "github_cli_not_logged_in" } | { "type": "git_cli_not_logged_in" } | { "type": "git_cli_not_installed" } | { "type": "target_branch_not_found", branch: string, };
|
|
|
|
export type BranchStatus = { commits_behind: number | null, commits_ahead: number | null, has_uncommitted_changes: boolean | null, head_oid: string | null, uncommitted_count: number | null, untracked_count: number | null, target_branch_name: string, remote_commits_behind: number | null, remote_commits_ahead: number | null, merges: Array<Merge>,
|
|
/**
|
|
* True if a `git rebase` is currently in progress in this worktree
|
|
*/
|
|
is_rebase_in_progress: boolean,
|
|
/**
|
|
* Current conflict operation if any
|
|
*/
|
|
conflict_op: ConflictOp | null,
|
|
/**
|
|
* List of files currently in conflicted (unmerged) state
|
|
*/
|
|
conflicted_files: Array<string>, };
|
|
|
|
export type RunScriptError = { "type": "no_script_configured" } | { "type": "process_already_running" };
|
|
|
|
export type AttachPrResponse = { pr_attached: boolean, pr_url: string | null, pr_number: bigint | null, pr_status: MergeStatus | null, };
|
|
|
|
export type AttachExistingPrRequest = { repo_id: string, };
|
|
|
|
export type PrCommentsResponse = { comments: Array<UnifiedPrComment>, };
|
|
|
|
export type GetPrCommentsError = { "type": "no_pr_attached" } | { "type": "github_cli_not_installed" } | { "type": "github_cli_not_logged_in" };
|
|
|
|
export type GetPrCommentsQuery = { repo_id: string, };
|
|
|
|
export type UnifiedPrComment = { "comment_type": "general", id: string, author: string, author_association: string, body: string, created_at: string, url: string, } | { "comment_type": "review", id: bigint, author: string, author_association: string, body: string, created_at: string, url: string, path: string, line: bigint | null, diff_hunk: string, };
|
|
|
|
export type RepoBranchStatus = { repo_id: string, repo_name: string, commits_behind: number | null, commits_ahead: number | null, has_uncommitted_changes: boolean | null, head_oid: string | null, uncommitted_count: number | null, untracked_count: number | null, target_branch_name: string, remote_commits_behind: number | null, remote_commits_ahead: number | null, merges: Array<Merge>,
|
|
/**
|
|
* True if a `git rebase` is currently in progress in this worktree
|
|
*/
|
|
is_rebase_in_progress: boolean,
|
|
/**
|
|
* Current conflict operation if any
|
|
*/
|
|
conflict_op: ConflictOp | null,
|
|
/**
|
|
* List of files currently in conflicted (unmerged) state
|
|
*/
|
|
conflicted_files: Array<string>, };
|
|
|
|
export type DirectoryEntry = { name: string, path: string, is_directory: boolean, is_git_repo: boolean, last_modified: bigint | null, };
|
|
|
|
export type DirectoryListResponse = { entries: Array<DirectoryEntry>, current_path: string, };
|
|
|
|
export type Config = { config_version: string, theme: ThemeMode, executor_profile: ExecutorProfileId, disclaimer_acknowledged: boolean, onboarding_acknowledged: boolean, notifications: NotificationConfig, editor: EditorConfig, github: GitHubConfig, analytics_enabled: boolean, workspace_dir: string | null, last_app_version: string | null, show_release_notes: boolean, language: UiLanguage, git_branch_prefix: string, showcases: ShowcaseState, pr_auto_description_enabled: boolean, pr_auto_description_prompt: string | null, };
|
|
|
|
export type NotificationConfig = { sound_enabled: boolean, push_enabled: boolean, sound_file: SoundFile, };
|
|
|
|
export enum ThemeMode { LIGHT = "LIGHT", DARK = "DARK", SYSTEM = "SYSTEM" }
|
|
|
|
export type EditorConfig = { editor_type: EditorType, custom_command: string | null, remote_ssh_host: string | null, remote_ssh_user: string | null, };
|
|
|
|
export enum EditorType { VS_CODE = "VS_CODE", CURSOR = "CURSOR", WINDSURF = "WINDSURF", INTELLI_J = "INTELLI_J", ZED = "ZED", XCODE = "XCODE", CUSTOM = "CUSTOM" }
|
|
|
|
export type EditorOpenError = { "type": "executable_not_found", executable: string, editor_type: EditorType, } | { "type": "invalid_command", details: string, editor_type: EditorType, } | { "type": "launch_failed", executable: string, details: string, editor_type: EditorType, };
|
|
|
|
export type GitHubConfig = { pat: string | null, oauth_token: string | null, username: string | null, primary_email: string | null, default_pr_base: string | null, };
|
|
|
|
export enum SoundFile { ABSTRACT_SOUND1 = "ABSTRACT_SOUND1", ABSTRACT_SOUND2 = "ABSTRACT_SOUND2", ABSTRACT_SOUND3 = "ABSTRACT_SOUND3", ABSTRACT_SOUND4 = "ABSTRACT_SOUND4", COW_MOOING = "COW_MOOING", PHONE_VIBRATION = "PHONE_VIBRATION", ROOSTER = "ROOSTER" }
|
|
|
|
export type UiLanguage = "BROWSER" | "EN" | "JA" | "ES" | "KO" | "ZH_HANS";
|
|
|
|
export type ShowcaseState = { seen_features: Array<string>, };
|
|
|
|
export type GitBranch = { name: string, is_current: boolean, is_remote: boolean, last_commit_date: Date, };
|
|
|
|
export type SharedTaskDetails = { id: string, project_id: string, title: string, description: string | null, status: TaskStatus, };
|
|
|
|
export type QueuedMessage = {
|
|
/**
|
|
* The task attempt this message is queued for
|
|
*/
|
|
task_attempt_id: string,
|
|
/**
|
|
* The follow-up data (message + variant)
|
|
*/
|
|
data: DraftFollowUpData,
|
|
/**
|
|
* Timestamp when the message was queued
|
|
*/
|
|
queued_at: string, };
|
|
|
|
export type QueueStatus = { "status": "empty" } | { "status": "queued", message: QueuedMessage, };
|
|
|
|
export type ConflictOp = "rebase" | "merge" | "cherry_pick" | "revert";
|
|
|
|
export type ExecutorAction = { typ: ExecutorActionType, next_action: ExecutorAction | null, };
|
|
|
|
export type McpConfig = { servers: { [key in string]?: JsonValue }, servers_path: Array<string>, template: JsonValue, preconfigured: JsonValue, is_toml_config: boolean, };
|
|
|
|
export type ExecutorActionType = { "type": "CodingAgentInitialRequest" } & CodingAgentInitialRequest | { "type": "CodingAgentFollowUpRequest" } & CodingAgentFollowUpRequest | { "type": "ScriptRequest" } & ScriptRequest;
|
|
|
|
export type ScriptContext = "SetupScript" | "CleanupScript" | "DevServer" | "ToolInstallScript";
|
|
|
|
export type ScriptRequest = { script: string, language: ScriptRequestLanguage, context: ScriptContext,
|
|
/**
|
|
* Optional relative path to execute the script in (relative to container_ref).
|
|
* If None, uses the container_ref directory directly.
|
|
*/
|
|
working_dir: string | null, };
|
|
|
|
export type ScriptRequestLanguage = "Bash";
|
|
|
|
export enum BaseCodingAgent { CLAUDE_CODE = "CLAUDE_CODE", AMP = "AMP", GEMINI = "GEMINI", CODEX = "CODEX", OPENCODE = "OPENCODE", CURSOR_AGENT = "CURSOR_AGENT", QWEN_CODE = "QWEN_CODE", COPILOT = "COPILOT", DROID = "DROID" }
|
|
|
|
export type CodingAgent = { "CLAUDE_CODE": ClaudeCode } | { "AMP": Amp } | { "GEMINI": Gemini } | { "CODEX": Codex } | { "OPENCODE": Opencode } | { "CURSOR_AGENT": CursorAgent } | { "QWEN_CODE": QwenCode } | { "COPILOT": Copilot } | { "DROID": Droid };
|
|
|
|
export type AvailabilityInfo = { "type": "LOGIN_DETECTED", last_auth_timestamp: bigint, } | { "type": "INSTALLATION_FOUND" } | { "type": "NOT_FOUND" };
|
|
|
|
export type CommandBuilder = {
|
|
/**
|
|
* Base executable command (e.g., "npx -y @anthropic-ai/claude-code@latest")
|
|
*/
|
|
base: string,
|
|
/**
|
|
* Optional parameters to append to the base command
|
|
*/
|
|
params: Array<string> | null, };
|
|
|
|
export type ExecutorProfileId = {
|
|
/**
|
|
* The executor type (e.g., "CLAUDE_CODE", "AMP")
|
|
*/
|
|
executor: BaseCodingAgent,
|
|
/**
|
|
* Optional variant name (e.g., "PLAN", "ROUTER")
|
|
*/
|
|
variant: string | null, };
|
|
|
|
export type ExecutorConfig = { [key in string]?: { "CLAUDE_CODE": ClaudeCode } | { "AMP": Amp } | { "GEMINI": Gemini } | { "CODEX": Codex } | { "OPENCODE": Opencode } | { "CURSOR_AGENT": CursorAgent } | { "QWEN_CODE": QwenCode } | { "COPILOT": Copilot } | { "DROID": Droid } };
|
|
|
|
export type ExecutorConfigs = { executors: { [key in BaseCodingAgent]?: ExecutorConfig }, };
|
|
|
|
export enum BaseAgentCapability { SESSION_FORK = "SESSION_FORK", SETUP_HELPER = "SETUP_HELPER" }
|
|
|
|
export type ClaudeCode = { append_prompt: AppendPrompt, claude_code_router?: boolean | null, plan?: boolean | null, approvals?: boolean | null, model?: string | null, dangerously_skip_permissions?: boolean | null, disable_api_key?: boolean | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Gemini = { append_prompt: AppendPrompt, model?: string | null, yolo?: boolean | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Amp = { append_prompt: AppendPrompt, dangerously_allow_all?: boolean | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Codex = { append_prompt: AppendPrompt, sandbox?: SandboxMode | null, ask_for_approval?: AskForApproval | null, oss?: boolean | null, model?: string | null, model_reasoning_effort?: ReasoningEffort | null, model_reasoning_summary?: ReasoningSummary | null, model_reasoning_summary_format?: ReasoningSummaryFormat | null, profile?: string | null, base_instructions?: string | null, include_apply_patch_tool?: boolean | null, model_provider?: string | null, compact_prompt?: string | null, developer_instructions?: string | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type SandboxMode = "auto" | "read-only" | "workspace-write" | "danger-full-access";
|
|
|
|
export type AskForApproval = "unless-trusted" | "on-failure" | "on-request" | "never";
|
|
|
|
export type ReasoningEffort = "low" | "medium" | "high" | "xhigh";
|
|
|
|
export type ReasoningSummary = "auto" | "concise" | "detailed" | "none";
|
|
|
|
export type ReasoningSummaryFormat = "none" | "experimental";
|
|
|
|
export type CursorAgent = { append_prompt: AppendPrompt, force?: boolean | null, model?: string | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Copilot = { append_prompt: AppendPrompt, model?: string | null, allow_all_tools?: boolean | null, allow_tool?: string | null, deny_tool?: string | null, add_dir?: Array<string> | null, disable_mcp_server?: Array<string> | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Opencode = { append_prompt: AppendPrompt, model?: string | null, mode?: string | null,
|
|
/**
|
|
* Auto-approve agent actions
|
|
*/
|
|
auto_approve: boolean, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type QwenCode = { append_prompt: AppendPrompt, yolo?: boolean | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Droid = { append_prompt: AppendPrompt, autonomy: Autonomy, model?: string | null, reasoning_effort?: DroidReasoningEffort | null, base_command_override?: string | null, additional_params?: Array<string> | null, env?: { [key in string]?: string } | null, };
|
|
|
|
export type Autonomy = "normal" | "low" | "medium" | "high" | "skip-permissions-unsafe";
|
|
|
|
export type DroidReasoningEffort = "none" | "dynamic" | "off" | "low" | "medium" | "high";
|
|
|
|
export type AppendPrompt = string | null;
|
|
|
|
export type CodingAgentInitialRequest = { prompt: string,
|
|
/**
|
|
* Executor profile specification
|
|
*/
|
|
executor_profile_id: ExecutorProfileId, };
|
|
|
|
export type CodingAgentFollowUpRequest = { prompt: string, session_id: string,
|
|
/**
|
|
* Executor profile specification
|
|
*/
|
|
executor_profile_id: ExecutorProfileId, };
|
|
|
|
export type CommandExitStatus = { "type": "exit_code", code: number, } | { "type": "success", success: boolean, };
|
|
|
|
export type CommandRunResult = { exit_status: CommandExitStatus | null, output: string | null, };
|
|
|
|
export type NormalizedEntry = { timestamp: string | null, entry_type: NormalizedEntryType, content: string, };
|
|
|
|
export type NormalizedEntryType = { "type": "user_message" } | { "type": "user_feedback", denied_tool: string, } | { "type": "assistant_message" } | { "type": "tool_use", tool_name: string, action_type: ActionType, status: ToolStatus, } | { "type": "system_message" } | { "type": "error_message", error_type: NormalizedEntryError, } | { "type": "thinking" } | { "type": "loading" } | { "type": "next_action", failed: boolean, execution_processes: number, needs_setup: boolean, };
|
|
|
|
export type FileChange = { "action": "write", content: string, } | { "action": "delete" } | { "action": "rename", new_path: string, } | { "action": "edit",
|
|
/**
|
|
* Unified diff containing file header and hunks.
|
|
*/
|
|
unified_diff: string,
|
|
/**
|
|
* Whether line number in the hunks are reliable.
|
|
*/
|
|
has_line_numbers: boolean, };
|
|
|
|
export type ActionType = { "action": "file_read", path: string, } | { "action": "file_edit", path: string, changes: Array<FileChange>, } | { "action": "command_run", command: string, result: CommandRunResult | null, } | { "action": "search", query: string, } | { "action": "web_fetch", url: string, } | { "action": "tool", tool_name: string, arguments: JsonValue | null, result: ToolResult | null, } | { "action": "task_create", description: string, } | { "action": "plan_presentation", plan: string, } | { "action": "todo_management", todos: Array<TodoItem>, operation: string, } | { "action": "other", description: string, };
|
|
|
|
export type TodoItem = { content: string, status: string, priority: string | null, };
|
|
|
|
export type NormalizedEntryError = { "type": "setup_required" } | { "type": "other" };
|
|
|
|
export type ToolResult = { type: ToolResultValueType,
|
|
/**
|
|
* For Markdown, this will be a JSON string; for JSON, a structured value
|
|
*/
|
|
value: JsonValue, };
|
|
|
|
export type ToolResultValueType = { "type": "markdown" } | { "type": "json" };
|
|
|
|
export type ToolStatus = { "status": "created" } | { "status": "success" } | { "status": "failed" } | { "status": "denied", reason: string | null, } | { "status": "pending_approval", approval_id: string, requested_at: string, timeout_at: string, } | { "status": "timed_out" };
|
|
|
|
export type PatchType = { "type": "NORMALIZED_ENTRY", "content": NormalizedEntry } | { "type": "STDOUT", "content": string } | { "type": "STDERR", "content": string } | { "type": "DIFF", "content": Diff };
|
|
|
|
export type JsonValue = number | string | boolean | Array<JsonValue> | { [key in string]?: JsonValue } | null;
|
|
|
|
export const DEFAULT_PR_DESCRIPTION_PROMPT = `Update the GitHub PR that was just created with a better title and description.
|
|
The PR number is #{pr_number} and the URL is {pr_url}.
|
|
|
|
Analyze the changes in this branch and write:
|
|
1. A concise, descriptive title that summarizes the changes, postfixed with "(Vibe Kanban)"
|
|
2. A detailed description that explains:
|
|
- What changes were made
|
|
- Why they were made (based on the task context)
|
|
- Any important implementation details
|
|
- At the end, include a note: "This PR was written using [Vibe Kanban](https://vibekanban.com)"
|
|
|
|
Use \`gh pr edit\` to update the PR.`; |