import { type BoardTask } from "./board.js"; import { type Clock } from "./clock.js"; import { type RoostEvent } from "./events.js"; import type { DispatchArgs } from "./protocol.js"; /** Who did it, as the board records it: the hub (`user`), the concierge, or a session. */ export interface BoardWho { who: string; whoId: string | null; sessionId: string | null; concierge: boolean; project: string | null; } /** M65: where a Task's worktree is, for the launch its start takes (sourceDirty: the main checkout had changes it does not carry). */ export interface PreparedWorkspace { path: string; branch: string; baseRef: string; baseSha: string; sourceDirty?: boolean; } export type WorkspaceAction = "prepare" | "start" | "merge" | "back" | "abort" | "commit" | "approve" | "verify" | "pass" | "comment" | "uncomment" | "shelve" | "pr"; export declare const WORKSPACE_ACTIONS: readonly WorkspaceAction[]; /** The board: the tasks (the module writes a Task's workspace, and marks it done when merged). */ export interface BoardPort { tasks: Map; save(): void; record(e: Omit): void; push(): void; taskEvent(a: BoardWho, why: string, t: BoardTask, extra?: string): void; /** Whether it reached the session (delivered or queued); false when it takes no messages. */ tellOwner(owner: { id: string; name: string; }, from: string, body: string): Promise; /** The tasks that waited on this one, told they can be taken. */ tellOpened(t: BoardTask, by: string | null): void; } /** The jobs: sessions and commands the daemon runs. */ export interface JobsPort { dispatch(launch: DispatchArgs, meta?: { verifyOf?: number; setupOf?: number; task?: { id: number; title: string; path: string; branch: string; baseRef: string; }; }): Promise<{ id: string; name: string; }>; stop(id: string): Promise; remove(id: string): Promise; /** Whether the session that holds a claim is live. */ live(id: string): boolean; /** The jobs that ran a Task's Verify or setup (at a restart, those no run reports to are stopped and removed). */ commandJobs(): { id: string; verifyOf?: number; setupOf?: number; running: boolean; }[]; } export interface WorkspaceDeps { board: BoardPort; jobs: JobsPort; clock?: Clock; log?: (level: "info" | "warn" | "error", msg: string, extra?: Record) => void; /** Whether the concierge's policy lets it start sessions. */ conciergeMayAct(): boolean; /** A session the concierge starts runs what the concierge runs (M59: the daemon builds it). */ conciergeLaunch(launch: DispatchArgs): DispatchArgs; } export interface Workspaces { /** An action on a Task's Workspace (who may has been asked: lib/callers.ts). */ act(a: BoardWho, t: BoardTask, action: WorkspaceAction, args: Record): Promise<{ job?: { id: string; name: string; }; note?: string; hash?: string; workspace?: PreparedWorkspace; }>; /** Its Session said the Task is done: its work committed, Verify starts. */ done(a: BoardWho, t: BoardTask, result: unknown): Promise; /** The Task is dropped: refused while its Workspace is busy or merging; then `mark` drops it on the board (it may refuse); its command stops, its clean worktree goes. */ drop(t: BoardTask, mark: () => void): Promise; /** A Verify or setup command ended. */ commandEnded(jobId: string, of: { verifyOf?: number; setupOf?: number; }, code: number | null): void; /** At start: what a restart cut short. */ settle(): void; /** Branches merged into Base by hand (looked at most every 10 s). */ handMerges(): Promise; /** What /tasks cleanup removes (dry: what it would). */ cleanup(dry: boolean): Promise; } /** M65: how long a worktree prepared for a start is held for it. */ export declare const PREPARED_MS: number; export declare function createWorkspaces(deps: WorkspaceDeps): Workspaces;