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.
| g1t coordinates the work and the person's own sessions do it: Ask g1t reads g1t with the same tools any agent gets, answers in one conversation shared with the @g1t direct message in Chat, and hands work to sessions in the person's own harness, whose subagents g1t records, ties to issues and pull requests, and lets see each other. | 1 | /** |
| 2 | * Starting work on an issue in a session on the person's own Claude. | |
| 3 | * Mirrors `crates/contracts/src/agent_sessions.rs` (the integrations | |
| 4 | * service's `start_agent_session`, `agent_sessions_setup`, | |
| 5 | * `sync_agent_session` and `stop_agent_session`). | |
| 6 | */ | |
| 7 | import type { ServiceBinding } from "./clients"; | |
| 8 | import type { User, Viewer } from "./identity"; | |
| 9 | import type { RepoPath } from "./repos"; | |
| 10 | import type { Result } from "./result"; | |
| 11 | import type { WorkSession } from "./work"; | |
| 12 | ||
| 13 | /** What kind of work a session is asked for. */ | |
| 14 | export type AgentMode = "plan" | "implement" | "review"; | |
| 15 | ||
| 16 | export const AGENT_MODES: { mode: AgentMode; label: string; hint: string }[] = [ | |
| 17 | { mode: "implement", label: "Implement", hint: "Make the change and open a pull request." }, | |
| 18 | { mode: "plan", label: "Plan", hint: "Work out how, and post the plan on the issue. No code." }, | |
| 19 | { mode: "review", label: "Review", hint: "Review the issue's pull request." }, | |
| 20 | ]; | |
| 21 | ||
| 22 | /** What `start_agent_session` started, or the hand-off to run. */ | |
| 23 | export type AgentSessionStarted = { | |
| 24 | issue: number; | |
| 25 | session: WorkSession | null; | |
| 26 | sessionUrl: string | null; | |
| 27 | provider: string | null; | |
| 28 | providerSessionId: string | null; | |
| 29 | providerSessionUrl: string | null; | |
| 30 | handoff: boolean; | |
| 31 | command: string | null; | |
| 32 | prompt: string; | |
| 33 | }; | |
| 34 | ||
| 35 | /** Whether sessions can start on the workspace's Anthropic account. */ | |
| 36 | export type AgentSessionsSetup = { | |
| 37 | available: boolean; | |
| 38 | connectionName: string | null; | |
| 39 | model: string | null; | |
| 40 | problem: string | null; | |
| 41 | }; | |
| 42 | ||
| 43 | /** What to start: an issue, or a new one from a title and body. */ | |
| 44 | export type StartAgentSessionInput = { | |
| 45 | issue?: number; | |
| 46 | title?: string; | |
| 47 | body?: string; | |
| 48 | instruction?: string; | |
| 49 | mode?: AgentMode; | |
| 50 | /** true: the Claude Code hand-off only; false: a session on the workspace's account, or a refusal. */ | |
| 51 | handoff?: boolean; | |
| 52 | }; | |
| 53 | ||
| 54 | /** The integrations service's methods for sessions on a workspace's Anthropic account. */ | |
| 55 | export interface AgentSessionsApi { | |
| 56 | setup(workspace: string, viewer: Viewer): Promise<Result<AgentSessionsSetup>>; | |
| 57 | start(actor: User, repo: RepoPath, input: StartAgentSessionInput): Promise<Result<AgentSessionStarted>>; | |
| 58 | /** Reads the session now (it is otherwise followed every minute). Whether it is still going. */ | |
| 59 | sync(repo: RepoPath, id: string, viewer: Viewer): Promise<Result<boolean>>; | |
| 60 | /** Interrupts it and ends its record. Only whoever started it. */ | |
| 61 | stop(actor: User, repo: RepoPath, id: string): Promise<Result<boolean>>; | |
| 62 | } | |
| 63 | ||
| 64 | async function rpc<T>(service: ServiceBinding, method: string, args: object): Promise<T> { | |
| 65 | const response = await service.fetch(`https://service/rpc/${method}`, { | |
| 66 | method: "POST", | |
| 67 | headers: { "content-type": "application/json" }, | |
| 68 | body: JSON.stringify(args), | |
| 69 | }); | |
| 70 | if (!response.ok) { | |
| 71 | throw new Error(`${method} failed with status ${response.status}`); | |
| 72 | } | |
| 73 | return (await response.json()) as T; | |
| 74 | } | |
| 75 | ||
| 76 | export function agentSessionsClient(service: ServiceBinding): AgentSessionsApi { | |
| 77 | const call = <T>(method: string, args: object) => rpc<T>(service, method, args); | |
| 78 | return { | |
| 79 | setup: (workspace, viewer) => call("agent_sessions_setup", { workspace, viewer }), | |
| 80 | start: (actor, repo, input) => | |
| 81 | call("start_agent_session", { | |
| 82 | actor, | |
| 83 | repo, | |
| 84 | issue: input.issue ?? null, | |
| 85 | title: input.title ?? null, | |
| 86 | body: input.body ?? null, | |
| 87 | instruction: input.instruction ?? null, | |
| 88 | mode: input.mode ?? null, | |
| 89 | handoff: input.handoff ?? null, | |
| 90 | }), | |
| 91 | sync: (repo, id, viewer) => call("sync_agent_session", { repo, id, viewer }), | |
| 92 | stop: (actor, repo, id) => call("stop_agent_session", { actor, repo, id }), | |
| 93 | }; | |
| 94 | } |