Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Fixes from the page sweep | 1 | /** |
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 2 | * Runs, recorded sessions and memory, kept by the work service. Mirrors |
| Fixes from the page sweep | 3 | * `g1t_contracts::agents`. |
| 4 | */ | |
| 5 | import type { ServiceBinding } from "./clients"; | |
| 6 | import type { User, Viewer } from "./identity"; | |
| 7 | import type { RepoPath } from "./repos"; | |
| 8 | import type { Result } from "./result"; | |
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 9 | import type { Pull, PullStatus, SessionEntry } from "./work"; |
| Fixes from the page sweep | 10 | |
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 11 | /** |
| 12 | * The work a run does. Only checks, queue and mergecheck are started now; | |
| 13 | * the others are runs of the agents g1t once ran itself, kept so older | |
| 14 | * runs still read. | |
| 15 | */ | |
| Fixes from the page sweep | 16 | export type RunKind = |
| 17 | | "implement" | |
| 18 | | "revise" | |
| 19 | | "review" | |
| 20 | | "answer" | |
| 21 | | "update" | |
| 22 | | "plan" | |
| 23 | | "checks" | |
| 24 | | "queue" | |
| 25 | | "mergecheck"; | |
| 26 | ||
| 27 | export const RUN_KINDS: RunKind[] = ["implement", "revise", "review", "answer", "update", "plan", "checks", "queue", "mergecheck"]; | |
| 28 | ||
| 29 | /** How a kind of run reads in a sentence: "is implementing", "a review run". */ | |
| 30 | export const RUN_KIND_LABEL: Record<RunKind, string> = { | |
| 31 | implement: "Implementing", | |
| 32 | revise: "Revising", | |
| 33 | review: "Reviewing", | |
| 34 | answer: "Answering", | |
| 35 | update: "Catching up", | |
| 36 | plan: "Planning", | |
| 37 | checks: "Checks", | |
| 38 | queue: "Merge queue", | |
| 39 | mergecheck: "Merge check", | |
| 40 | }; | |
| 41 | ||
| 42 | export type AgentRunStatus = "queued" | "running" | "succeeded" | "failed" | "stopped"; | |
| 43 | ||
| 44 | export function isActiveRun(status: AgentRunStatus): boolean { | |
| 45 | return status === "queued" || status === "running"; | |
| 46 | } | |
| 47 | ||
| 48 | export type RunStep = { at: string; text: string }; | |
| 49 | ||
| 50 | export type AgentRun = { | |
| 51 | id: string; | |
| 52 | repo: RepoPath; | |
| 53 | number: number | null; | |
| 54 | title: string | null; | |
| 55 | kind: RunKind; | |
| 56 | /** `g1t`, for its own agent and for a sandbox that runs commands. */ | |
| 57 | agent: string; | |
| 58 | /** Members only. */ | |
| 59 | model: string | null; | |
| 60 | status: AgentRunStatus; | |
| 61 | step: string | null; | |
| 62 | /** Oldest first; empty in lists. */ | |
| 63 | steps: RunStep[]; | |
| 64 | stepCount: number; | |
| 65 | startedBy: string | null; | |
| 66 | error: string | null; | |
| 67 | /** Members only. */ | |
| 68 | costUsd: number | null; | |
| 69 | turns: number | null; | |
| 70 | /** The most it may cost, from its guardrails. Null: no cap, or not a member. */ | |
| 71 | budgetUsd?: number | null; | |
| 72 | /** The longest it may take, in minutes, from its guardrails. */ | |
| 73 | timeCapMinutes?: number | null; | |
| 74 | /** `budget` or `time` when g1t stopped it for reaching that cap. */ | |
| 75 | halted?: "budget" | "time" | "abuse" | null; | |
| 76 | createdAt: string; | |
| 77 | startedAt: string | null; | |
| 78 | finishedAt: string | null; | |
| 79 | updatedAt: string; | |
| 80 | }; | |
| 81 | ||
| 82 | export type AgentRunTicket = { runId: string; token: string }; | |
| 83 | ||
| 84 | export type OpenRunInput = { | |
| 85 | actor: User; | |
| 86 | repo: RepoPath; | |
| 87 | number?: number | null; | |
| 88 | pullId?: string | null; | |
| 89 | title?: string | null; | |
| 90 | kind: RunKind; | |
| 91 | agent?: string | null; | |
| 92 | model?: string | null; | |
| 93 | sandbox: string; | |
| 94 | startedBy?: string | null; | |
| 95 | /** Its caps, from its guardrails. */ | |
| 96 | budgetUsd?: number | null; | |
| 97 | timeCapMinutes?: number | null; | |
| 98 | }; | |
| 99 | ||
| 100 | export type RunFilter = { | |
| 101 | repo?: RepoPath; | |
| 102 | workspace?: string; | |
| 103 | active?: boolean; | |
| 104 | kind?: RunKind; | |
| 105 | status?: AgentRunStatus; | |
| 106 | number?: number; | |
| 107 | limit?: number; | |
| 108 | }; | |
| 109 | ||
| 110 | export type SessionSummary = { | |
| 111 | number: number; | |
| 112 | title: string; | |
| 113 | status: PullStatus; | |
| 114 | agent: string; | |
| 115 | entries: number; | |
| 116 | tools: number; | |
| 117 | prompt: string | null; | |
| 118 | kinds: RunKind[]; | |
| 119 | runs: number; | |
| 120 | costUsd: number | null; | |
| 121 | active: boolean; | |
| 122 | startedAt: string; | |
| 123 | lastAt: string; | |
| 124 | }; | |
| 125 | ||
| 126 | export type SessionFilter = { kind?: RunKind; outcome?: PullStatus; number?: number }; | |
| 127 | ||
| 128 | export type SessionView = { | |
| 129 | pull: Pull; | |
| 130 | entries: SessionEntry[]; | |
| 131 | runs: AgentRun[]; | |
| 132 | costUsd: number | null; | |
| 133 | }; | |
| 134 | ||
| 135 | export type MemoryScope = "project" | "workspace"; | |
| 136 | export type MemoryKind = "fact" | "convention" | "decision" | "gotcha"; | |
| 137 | export const MEMORY_KINDS: MemoryKind[] = ["fact", "convention", "decision", "gotcha"]; | |
| 138 | ||
| 139 | export type MemorySource = { | |
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 140 | /** `person`, `agent` or `run`; on memory captured before capture was retired, `review`, `pr` or `doc` too. */ |
| Fixes from the page sweep | 141 | kind: string; |
| 142 | runId: string | null; | |
| 143 | repo: RepoPath | null; | |
| 144 | number: number | null; | |
| 145 | /** What it was captured from: `run:<id>`, `comment:<id>`, `pull:<repo id>#<n>`, `doc:<repo id>:<path>`. */ | |
| 146 | reference?: string | null; | |
| 147 | /** What it was learned from, quoted. */ | |
| 148 | evidence?: string | null; | |
| 149 | }; | |
| 150 | ||
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 151 | /** Only kept memories are recalled; candidates and dismissed ones are from automatic capture, which is retired. */ |
| Fixes from the page sweep | 152 | export type MemoryStatus = "candidate" | "kept" | "dismissed"; |
| 153 | ||
| 154 | export type Memory = { | |
| 155 | id: string; | |
| 156 | scope: MemoryScope; | |
| 157 | workspace: string; | |
| 158 | repo: RepoPath | null; | |
| 159 | text: string; | |
| 160 | kind: MemoryKind; | |
| 161 | source: MemorySource; | |
| 162 | createdBy: string; | |
| 163 | pinned: boolean; | |
| 164 | createdAt: string; | |
| 165 | updatedAt: string; | |
| 166 | lastUsedAt: string | null; | |
| 167 | /** Absent from services that predate capture: `kept`. */ | |
| 168 | status?: MemoryStatus; | |
| 169 | /** 0 to 1: how sure its source was. Null for what people wrote. */ | |
| 170 | confidence?: number | null; | |
| 171 | /** How many independent sources said it. */ | |
| 172 | seen?: number; | |
| 173 | }; | |
| 174 | ||
| 175 | export type Memories = { project: Memory[]; workspace: Memory[] }; | |
| 176 | ||
| 177 | export type NewMemory = { | |
| 178 | scope: MemoryScope; | |
| 179 | repo?: RepoPath | null; | |
| 180 | text: string; | |
| 181 | kind?: MemoryKind; | |
| 182 | pinned?: boolean; | |
| 183 | }; | |
| 184 | ||
| 185 | export type MemoryChange = { text?: string; kind?: MemoryKind; pinned?: boolean }; | |
| 186 | ||
| 187 | export interface AgentsApi { | |
| 188 | /** For the runner: records a sandbox it is starting. */ | |
| 189 | openRun(input: OpenRunInput): Promise<Result<AgentRunTicket>>; | |
| 190 | /** For the runner: ends a run when its sandbox stops. Refused once it has ended. */ | |
| 191 | closeRun(runId: string, token: string, outcome: "succeeded" | "failed", error?: string): Promise<Result<AgentRunStatus>>; | |
| 192 | listRuns(viewer: Viewer, filter: RunFilter): Promise<Result<AgentRun[]>>; | |
| 193 | getRun(viewer: Viewer, repo: RepoPath, id: string): Promise<Result<AgentRun>>; | |
| 194 | listSessions(viewer: Viewer, repo: RepoPath, filter?: SessionFilter): Promise<Result<SessionSummary[]>>; | |
| 195 | getSession(viewer: Viewer, repo: RepoPath, number: number): Promise<Result<SessionView>>; | |
| 196 | listMemories(viewer: Viewer, workspace: string, repo?: RepoPath | null): Promise<Result<Memories>>; | |
| 197 | addMemory(actor: User, workspace: string, memory: NewMemory): Promise<Result<Memory>>; | |
| 198 | updateMemory(actor: User, workspace: string, id: string, change: MemoryChange): Promise<Result<Memory>>; | |
| 199 | deleteMemory(actor: User, workspace: string, id: string): Promise<Result<boolean>>; | |
| 200 | } | |
| 201 | ||
| The contracts no longer describe g1t's own agents, and workspaces can keep their AI providers. Every consumer had already stopped using them, so the TypeScript and Rust contracts drop the workspace-agent, ability, look, skill-library, context, runner-agent and mention modules, the chat and docs RPCs agents posted and read through, the folio agent methods, the agent_waiting notification, agent.asked and memory.changed events, AI credit, token and gateway billing types, model routes and sessions, team agents, agent tokens, plan, review, message and confidence types, command rules, cost caps and confidence rules. The agents:run and models:* scopes are no longer offered by any preset, OAuth default or permission form, but a stored token or grant that names them still reads; and the removed operations are gone from the scope table, so the API's check that every operation has exactly one scope is strict again. What stored data needs in order to parse (old run and credential kinds, an agent team lead, retired rules and webhook events, old guardrail and integration settings) still parses, and a run's token is still PrincipalKind::Agent, which now means a run's token and the @g1t rows written before. The customize, marketplace, skills and claude-plugin contracts stay only until the mobile app drops its Customize screens. | 202 | /** The runs, sessions and memory methods of the work service. */ |
| Fixes from the page sweep | 203 | export function agentsClient(service: ServiceBinding): AgentsApi { |
| 204 | const call = async <T>(method: string, args: object): Promise<T> => { | |
| 205 | const response = await service.fetch(`https://service/rpc/${method}`, { | |
| 206 | method: "POST", | |
| 207 | headers: { "content-type": "application/json" }, | |
| 208 | body: JSON.stringify(args), | |
| 209 | }); | |
| 210 | if (!response.ok) throw new Error(`${method} failed with status ${response.status}`); | |
| 211 | return (await response.json()) as T; | |
| 212 | }; | |
| 213 | return { | |
| 214 | openRun: (input) => call("open_run", input), | |
| 215 | closeRun: (runId, token, outcome, error) => call("report_run", { runId, token, outcome, error }), | |
| 216 | listRuns: (viewer, filter) => call("list_runs", { viewer, ...filter }), | |
| 217 | getRun: (viewer, repo, id) => call("get_run", { viewer, repo, id }), | |
| 218 | listSessions: (viewer, repo, filter = {}) => call("list_sessions", { viewer, repo, ...filter }), | |
| 219 | getSession: (viewer, repo, number) => call("get_session", { viewer, repo, number }), | |
| 220 | listMemories: (viewer, workspace, repo) => call("list_memories", { viewer, workspace, repo: repo ?? null }), | |
| 221 | addMemory: (actor, workspace, memory) => | |
| 222 | call("add_memory", { actor, workspace, repo: memory.repo ?? null, scope: memory.scope, text: memory.text, kind: memory.kind ?? "fact", pinned: memory.pinned ?? false }), | |
| 223 | updateMemory: (actor, workspace, id, change) => call("update_memory", { actor, workspace, id, ...change }), | |
| 224 | deleteMemory: (actor, workspace, id) => call("delete_memory", { actor, workspace, id }), | |
| 225 | }; | |
| 226 | } |
This file's history is long; its oldest lines are credited to the oldest commit read.