| 1 | import type { EventSubscriber } from "./events"; |
| 2 | import type { User, Viewer } from "./identity"; |
| 3 | import type { RepoPath } from "./repos"; |
| 4 | import type { Result } from "./result"; |
| 5 | |
| 6 | export type IntentStatus = "open" | "shipped" | "withdrawn"; |
| 7 | |
| 8 | /** A goal stated against a repo. Replaces the issue and the pull request. */ |
| 9 | export type Intent = { |
| 10 | id: string; |
| 11 | repoId: string; |
| 12 | /** Sequential per repo, shown as `#12`. */ |
| 13 | number: number; |
| 14 | title: string; |
| 15 | /** The goal in prose: what an agent is given to work from. */ |
| 16 | brief: string; |
| 17 | /** Commands that must pass for an attempt to be accepted. */ |
| 18 | checks: string[]; |
| 19 | status: IntentStatus; |
| 20 | author: User; |
| 21 | createdAt: number; |
| 22 | attemptCount: number; |
| 23 | }; |
| 24 | |
| 25 | export type AttemptStatus = "working" | "submitted" | "shipped" | "abandoned"; |
| 26 | |
| 27 | /** Where the agent runs: on g1t's sandboxes, or in someone's own session. */ |
| 28 | export type AttemptRuntime = "hosted" | "external"; |
| 29 | |
| 30 | /** One agent's run at an intent, in its own fork. */ |
| 31 | export type Attempt = { |
| 32 | id: string; |
| 33 | intentId: string; |
| 34 | repoId: string; |
| 35 | /** Sequential per intent. */ |
| 36 | number: number; |
| 37 | /** A label for the agent doing the work, e.g. `claude-code`. */ |
| 38 | agent: string; |
| 39 | runtime: AttemptRuntime; |
| 40 | status: AttemptStatus; |
| 41 | /** The agent's own account of what it did, set on submit. */ |
| 42 | summary: string | null; |
| 43 | fork: RepoPath; |
| 44 | headCommit: string | null; |
| 45 | startedBy: User; |
| 46 | createdAt: number; |
| 47 | updatedAt: number; |
| 48 | }; |
| 49 | |
| 50 | export type SessionEntryKind = "prompt" | "message" | "tool_call" | "tool_result" | "note"; |
| 51 | |
| 52 | /** One step of an agent's session: the "why" behind an attempt's commits. */ |
| 53 | export type SessionEntry = { |
| 54 | seq: number; |
| 55 | kind: SessionEntryKind; |
| 56 | text: string; |
| 57 | /** For tool calls and results. */ |
| 58 | tool: string | null; |
| 59 | /** The fork's head commit when this entry was recorded, if known. */ |
| 60 | commit: string | null; |
| 61 | at: number; |
| 62 | }; |
| 63 | |
| 64 | export type NewSessionEntry = Pick<SessionEntry, "kind" | "text"> & |
| 65 | Partial<Pick<SessionEntry, "tool" | "commit" | "at">>; |
| 66 | |
| 67 | export type IntentDetail = { intent: Intent; attempts: Attempt[] }; |
| 68 | |
| 69 | export type OpenIntentInput = { title: string; brief: string; checks?: string[] }; |
| 70 | |
| 71 | export type StartAttemptInput = { agent: string; runtime: AttemptRuntime }; |
| 72 | |
| 73 | /** Intents, attempts and sessions. */ |
| 74 | export interface WorkApi extends EventSubscriber { |
| 75 | openIntent(actor: User, repo: RepoPath, input: OpenIntentInput): Promise<Result<Intent>>; |
| 76 | listIntents(repo: RepoPath, viewer: Viewer, status?: IntentStatus): Promise<Result<Intent[]>>; |
| 77 | getIntent(repo: RepoPath, number: number, viewer: Viewer): Promise<Result<IntentDetail>>; |
| 78 | withdrawIntent(actor: User, intentId: string): Promise<Result<Intent>>; |
| 79 | |
| 80 | /** Forks the repo for the agent and returns the attempt to push to. */ |
| 81 | startAttempt(actor: User, intentId: string, input: StartAttemptInput): Promise<Result<Attempt>>; |
| 82 | getAttempt(attemptId: string, viewer: Viewer): Promise<Result<{ attempt: Attempt; intent: Intent }>>; |
| 83 | submitAttempt(actor: User, attemptId: string, summary: string): Promise<Result<Attempt>>; |
| 84 | abandonAttempt(actor: User, attemptId: string): Promise<Result<Attempt>>; |
| 85 | /** Attempts in progress that the viewer started, newest first. */ |
| 86 | listActiveAttempts(viewer: Viewer): Promise<{ attempt: Attempt; intent: Intent }[]>; |
| 87 | |
| 88 | appendSession(actor: User, attemptId: string, entries: NewSessionEntry[]): Promise<Result<{ count: number }>>; |
| 89 | readSession(attemptId: string, viewer: Viewer, afterSeq?: number): Promise<Result<SessionEntry[]>>; |
| 90 | } |