@aictiq/cli 0.2.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +727 -141
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors.ts","../src/program.ts","../src/commands/attachment.ts","../src/api/client.ts","../src/config.ts","../src/context.ts","../src/commands/auth.ts","../src/output.ts","../src/prompt.ts","../src/commands/item.ts","../src/resolve.ts","../src/commands/mcp.ts","../src/version.ts","../src/commands/project.ts","../src/commands/run.ts","../src/commands/runner.ts","../src/runner/client.ts","../src/runner/config.ts","../src/runner/workspace.ts","../src/runner/types.ts","../src/runner/execute.ts","../src/runner/log.ts","../src/runner/process.ts","../src/runner/harness/claude.ts","../src/runner/harness/codex.ts","../src/runner/harness/opencode.ts","../src/runner/harness/index.ts","../src/runner/loop.ts","../src/commands/sprint.ts","../src/commands/wiki.ts","../src/index.ts"],"sourcesContent":["/**\n * Exit codes are part of the CLI's contract (03-API-MCP-CLI.md §4): a script or an agent\n * decides what to do next from the code alone, without parsing prose. 3 (conflict) is the\n * one worth acting on - refetch and retry with the fresh version - which is why it is\n * distinct from 2 (the request was wrong and retrying it will fail again).\n */\nexport const ExitCode = {\n Ok: 0,\n Error: 1,\n Validation: 2,\n Conflict: 3,\n NotFound: 4,\n Auth: 5,\n} as const\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode]\n\n/** RFC 9457 problem+json, as the API emits it. */\nexport interface ProblemDetails {\n type?: string\n title?: string\n status?: number\n detail?: string\n errors?: Record<string, string[]>\n}\n\nexport class CliError extends Error {\n readonly exitCode: ExitCodeValue\n readonly problem: ProblemDetails | undefined\n\n constructor(message: string, exitCode: ExitCodeValue = ExitCode.Error, problem?: ProblemDetails) {\n super(message)\n this.name = 'CliError'\n this.exitCode = exitCode\n this.problem = problem\n }\n}\n\nexport function exitCodeForStatus(status: number): ExitCodeValue {\n if (status === 401) return ExitCode.Auth\n if (status === 403) return ExitCode.Auth\n if (status === 404) return ExitCode.NotFound\n if (status === 409) return ExitCode.Conflict\n if (status >= 400 && status < 500) return ExitCode.Validation\n return ExitCode.Error\n}\n\n/** The human rendering of a failure: the problem title, then each field error. */\nexport function formatProblem(problem: ProblemDetails | undefined, fallback: string): string {\n const lines: string[] = [problem?.title?.trim() || fallback]\n if (problem?.detail && problem.detail !== problem.title) lines.push(problem.detail)\n for (const [field, messages] of Object.entries(problem?.errors ?? {})) {\n for (const message of messages) lines.push(` ${field}: ${message}`)\n }\n return lines.join('\\n')\n}\n","import { Command } from 'commander'\nimport { attachmentCommand } from './commands/attachment.js'\nimport { authCommand } from './commands/auth.js'\nimport { itemCommand } from './commands/item.js'\nimport { mcpCommand } from './commands/mcp.js'\nimport { projectCommand } from './commands/project.js'\nimport { runCommand } from './commands/run.js'\nimport { runnerCommand } from './commands/runner.js'\nimport { sprintCommand } from './commands/sprint.js'\nimport { wikiCommand } from './commands/wiki.js'\nimport type { GlobalOptions } from './context.js'\nimport { version } from './version.js'\n\nexport function createProgram(): Command {\n const program = new Command('aictiq')\n .description('Aictiq from the command line, for people and for agents')\n .version(version, '-v, --version')\n .option('--url <url>', 'Aictiq base URL (overrides AICTIQ_URL and the config file)')\n .option('--token <token>', 'Personal access token (overrides AICTIQ_TOKEN)')\n .option('--org <slug>', 'Organization slug (overrides AICTIQ_ORG)')\n .option('--json', 'Print machine-readable JSON instead of a table')\n // Subcommands read the globals lazily: commander parses the root options before it\n // hands control to the subcommand's action, so this closure always sees them.\n .showHelpAfterError()\n\n const globals = () => program.opts<GlobalOptions>()\n\n program.addCommand(authCommand(globals))\n program.addCommand(attachmentCommand(globals))\n program.addCommand(projectCommand(globals))\n program.addCommand(itemCommand(globals))\n program.addCommand(sprintCommand(globals))\n program.addCommand(wikiCommand(globals))\n program.addCommand(runCommand(globals))\n program.addCommand(mcpCommand(globals))\n program.addCommand(runnerCommand(globals))\n\n return program\n}\n","import { writeFile } from 'node:fs/promises'\nimport { Command } from 'commander'\nimport { createContext } from '../context.js'\nimport type { GlobalOptions } from '../context.js'\n\n/** Attachment bytes are intentionally written verbatim: agents may fetch screenshots, logs,\n * PDFs or archives, and formatting them would corrupt every type except text. */\nexport function attachmentCommand(globals: () => GlobalOptions): Command {\n const attachment = new Command('attachment').description('Download an attachment')\n attachment\n .command('get')\n .description('Write an attachment to stdout, or to --output')\n .argument('<id>', 'Attachment UUID')\n .option('-o, --output <path>', 'Write to this path instead of stdout')\n .action(async (id: string, options: { output?: string }) => {\n const ctx = createContext(globals())\n const bytes = await ctx.client.download(\n '/api/v1/orgs/{orgSlug}/attachments/{attachmentId}/download',\n { path: { orgSlug: await ctx.org(), attachmentId: id } },\n )\n if (options.output) {\n await writeFile(options.output, bytes, { mode: 0o600 })\n return\n }\n process.stdout.write(bytes)\n })\n return attachment\n}\n","import { CliError, ExitCode, exitCodeForStatus, formatProblem } from '../errors.js'\nimport type { ProblemDetails } from '../errors.js'\nimport type { paths } from './schema.js'\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'\n\n/** The documented routes that support a given method - a typo in a path is a type error. */\nexport type PathFor<M extends HttpMethod> = {\n [P in keyof paths]: paths[P] extends { [K in M]: object } ? P : never\n}[keyof paths]\n\ntype Operation<P extends keyof paths, M extends HttpMethod> = paths[P] extends {\n [K in M]: infer O\n}\n ? O\n : never\n\n/**\n * A C# record's optional members are nullable rather than absent, and the OpenAPI document\n * says nothing about which are required, so every documented property comes through as\n * required-and-nullable. `Partial` is the honest reading: omitting a field is what the API\n * treats as \"not mentioned\". Excess-property checking still applies, so a renamed or\n * dropped field is a compile error here - which is the point of generating these at all.\n */\ntype Loosen<B> = B extends object ? Partial<B> : B\n\n/**\n * The request body the API documents for this route. Response bodies are not in the\n * OpenAPI document yet (the endpoints return untyped `IResult`), so\n * callers name the response shape themselves from `views.ts`.\n */\nexport type BodyFor<P extends PathFor<M>, M extends HttpMethod> =\n Operation<P, M> extends { requestBody: { content: { 'application/json': infer B } } }\n ? Loosen<B>\n : Operation<P, M> extends { requestBody?: { content: { 'application/json': infer B } } }\n ? Loosen<B> | undefined\n : undefined\n\nexport interface RequestOptions<P extends PathFor<M>, M extends HttpMethod> {\n path?: Record<string, string>\n query?: Record<string, string | number | boolean | undefined>\n body?: BodyFor<P, M>\n}\n\nexport interface ClientOptions {\n baseUrl: string\n token: string\n fetch?: typeof fetch\n}\n\n/**\n * The whole HTTP surface of the CLI. Bearer credentials are not subject to the cookie\n * CSRF rule, so `X-Aictiq-Request` is deliberately absent: sending it on a bearer request\n * would be harmless but misleading about which transport authenticated the call.\n */\nexport class AictiqClient {\n readonly baseUrl: string\n private readonly token: string\n private readonly doFetch: typeof fetch\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.token = options.token\n this.doFetch = options.fetch ?? fetch\n }\n\n async request<T, P extends PathFor<M>, M extends HttpMethod = 'get'>(\n method: M,\n path: P,\n options: RequestOptions<P, M> = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + expand(path as string, options.path ?? {}))\n for (const [key, value] of Object.entries(options.query ?? {})) {\n if (value !== undefined && value !== '') url.searchParams.set(key, String(value))\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n Accept: 'application/json',\n 'User-Agent': 'aictiq-cli',\n }\n if (options.body !== undefined) headers['Content-Type'] = 'application/json'\n\n let response: Response\n try {\n response = await this.doFetch(url, {\n method: method.toUpperCase(),\n headers,\n ...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),\n })\n } catch (cause) {\n throw new CliError(\n `Cannot reach ${this.baseUrl}: ${cause instanceof Error ? cause.message : String(cause)}`,\n ExitCode.Error,\n )\n }\n\n if (response.status === 204) return undefined as T\n const text = await response.text()\n const payload: unknown = text.length === 0 ? undefined : safeJson(text)\n\n if (!response.ok) {\n const problem = isProblem(payload) ? payload : undefined\n throw new CliError(\n formatProblem(problem, `${response.status} ${response.statusText}`),\n exitCodeForStatus(response.status),\n problem,\n )\n }\n return payload as T\n }\n\n /**\n * Downloads an authenticated response without trying to interpret it as JSON. Attachments\n * deliberately use the normal API route (rather than a presigned object-store URL), so a\n * PAT's organization and project visibility checks remain in force.\n */\n async download<P extends PathFor<'get'>>(\n path: P,\n options: RequestOptions<P, 'get'> = {},\n ): Promise<Uint8Array> {\n const url = new URL(this.baseUrl + expand(path as string, options.path ?? {}))\n for (const [key, value] of Object.entries(options.query ?? {})) {\n if (value !== undefined && value !== '') url.searchParams.set(key, String(value))\n }\n let response: Response\n try {\n response = await this.doFetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.token}`,\n Accept: '*/*',\n 'User-Agent': 'aictiq-cli',\n },\n })\n } catch (cause) {\n throw new CliError(\n `Cannot reach ${this.baseUrl}: ${cause instanceof Error ? cause.message : String(cause)}`,\n ExitCode.Error,\n )\n }\n if (!response.ok) {\n const text = await response.text()\n const payload: unknown = text.length === 0 ? undefined : safeJson(text)\n const problem = isProblem(payload) ? payload : undefined\n throw new CliError(\n formatProblem(problem, `${response.status} ${response.statusText}`),\n exitCodeForStatus(response.status),\n problem,\n )\n }\n return new Uint8Array(await response.arrayBuffer())\n }\n}\n\n/** Fills `{name}` segments; a missing value is a programming error, not a user one. */\nfunction expand(template: string, values: Record<string, string>): string {\n return template.replace(/\\{(\\w+)\\}/g, (_match, name: string) => {\n const value = values[name]\n if (value === undefined) throw new Error(`Missing path parameter \"${name}\" for ${template}`)\n return encodeURIComponent(value)\n })\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return { title: text.slice(0, 500) }\n }\n}\n\nfunction isProblem(value: unknown): value is ProblemDetails {\n return typeof value === 'object' && value !== null\n}\n","import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\n/**\n * What `aictiq auth login` writes. The token is a personal access token - the same\n * credential the REST API and `/mcp` take - so the file is written 0600 and the\n * directory 0700. There is deliberately no OS keychain integration: keytar and its\n * successors ship prebuilt native binaries, and a CLI whose job is to hold a bearer\n * token should not widen its install surface that far. See docs/cli.md.\n */\nexport interface StoredConfig {\n url?: string\n token?: string\n org?: string\n}\n\nexport function configPath(env: NodeJS.ProcessEnv = process.env): string {\n const base = env.AICTIQ_CONFIG_HOME ?? env.XDG_CONFIG_HOME ?? join(homedir(), '.config')\n return join(base, 'aictiq', 'config.json')\n}\n\nexport function readConfig(path = configPath()): StoredConfig {\n if (!existsSync(path)) return {}\n try {\n const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n if (typeof parsed !== 'object' || parsed === null) return {}\n const { url, token, org } = parsed as Record<string, unknown>\n return {\n ...(typeof url === 'string' ? { url } : {}),\n ...(typeof token === 'string' ? { token } : {}),\n ...(typeof org === 'string' ? { org } : {}),\n }\n } catch {\n // A hand-edited or truncated file must not make every command fail; the caller\n // falls back to flags and environment, which is what an unconfigured host does.\n return {}\n }\n}\n\nexport function writeConfig(config: StoredConfig, path = configPath()): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n // The mode argument only applies when the file is created, so an existing file that\n // someone widened is narrowed again explicitly.\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 })\n chmodSync(path, 0o600)\n}\n\nexport function clearConfig(path = configPath()): void {\n rmSync(path, { force: true })\n}\n","import { AictiqClient } from './api/client.js'\nimport type { OrganizationSummary } from './api/views.js'\nimport { readConfig } from './config.js'\nimport type { StoredConfig } from './config.js'\nimport { CliError, ExitCode } from './errors.js'\n\nexport interface GlobalOptions {\n url?: string\n token?: string\n org?: string\n json?: boolean\n}\n\n/**\n * Flags beat environment beats config file - the precedence in 03-API-MCP-CLI.md §4.\n * CI sets `AICTIQ_URL`/`AICTIQ_TOKEN` and never writes a config file; a person logs in\n * once and passes neither.\n */\nexport function resolveSettings(\n options: GlobalOptions,\n env: NodeJS.ProcessEnv = process.env,\n stored: StoredConfig = readConfig(),\n): StoredConfig {\n return {\n url: options.url ?? env.AICTIQ_URL ?? stored.url,\n token: options.token ?? env.AICTIQ_TOKEN ?? stored.token,\n org: options.org ?? env.AICTIQ_ORG ?? stored.org,\n }\n}\n\nexport interface Context {\n client: AictiqClient\n /** The organization slug every scoped route needs; resolved lazily. */\n org(): Promise<string>\n json: boolean\n}\n\nexport function createContext(options: GlobalOptions): Context {\n const settings = resolveSettings(options)\n if (!settings.url) {\n throw new CliError('No Aictiq URL. Run `aictiq auth login --url <url>`.', ExitCode.Auth)\n }\n if (!settings.token) {\n throw new CliError('No personal access token. Run `aictiq auth login`.', ExitCode.Auth)\n }\n\n const client = new AictiqClient({ baseUrl: settings.url, token: settings.token })\n let resolved: Promise<string> | undefined\n\n return {\n client,\n json: options.json === true,\n org() {\n if (settings.org) return Promise.resolve(settings.org)\n // A token bound to one organization has exactly one answer here, which is why the\n // CLI can be run with no org configured at all. Anything else has to be told which.\n resolved ??= resolveOrg(client)\n return resolved\n },\n }\n}\n\nasync function resolveOrg(client: AictiqClient): Promise<string> {\n const orgs = await client.request<OrganizationSummary[], '/api/v1/orgs', 'get'>(\n 'get',\n '/api/v1/orgs',\n )\n if (orgs.length === 0) {\n throw new CliError('This account is not a member of any organization.', ExitCode.NotFound)\n }\n if (orgs.length > 1) {\n const slugs = orgs.map((o) => o.slug).join(', ')\n throw new CliError(\n `This token can see several organizations (${slugs}). Pass --org, set AICTIQ_ORG, or run \\`aictiq auth login --org <slug>\\`.`,\n ExitCode.Validation,\n )\n }\n return orgs[0]!.slug\n}\n","import { Command } from 'commander'\nimport { AictiqClient } from '../api/client.js'\nimport type { OrganizationSummary, SessionResponse } from '../api/views.js'\nimport { clearConfig, configPath, readConfig, writeConfig } from '../config.js'\nimport { resolveSettings } from '../context.js'\nimport type { GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { print, printJson, renderFields, renderTable } from '../output.js'\nimport { promptSecret } from '../prompt.js'\n\nexport function authCommand(globals: () => GlobalOptions): Command {\n const auth = new Command('auth').description(\n 'Sign in to a Aictiq instance and inspect the session',\n )\n\n auth\n .command('login')\n .description('Store a personal access token for an instance')\n .option('--url <url>', 'Base URL of the Aictiq instance')\n .option('--token <token>', 'Personal access token (aiq_…); read from stdin when omitted')\n .option('--org <slug>', 'Default organization slug for scoped commands')\n .action(async (options: { url?: string; token?: string; org?: string }) => {\n const global = globals()\n const url = options.url ?? global.url ?? process.env.AICTIQ_URL ?? readConfig().url\n if (!url)\n throw new CliError(\n 'Pass --url with the address of your Aictiq instance.',\n ExitCode.Validation,\n )\n\n const token =\n options.token ??\n global.token ??\n process.env.AICTIQ_TOKEN ??\n (await promptSecret('Personal access token: '))\n if (!token) throw new CliError('No token supplied.', ExitCode.Validation)\n\n // Verify before writing: a stored token that never worked is worse than no token,\n // because every later command fails somewhere far from the cause.\n const client = new AictiqClient({ baseUrl: url, token })\n const session = await client.request<SessionResponse, '/api/v1/auth/session', 'get'>(\n 'get',\n '/api/v1/auth/session',\n )\n const orgs = await client.request<OrganizationSummary[], '/api/v1/orgs', 'get'>(\n 'get',\n '/api/v1/orgs',\n )\n const org = options.org ?? global.org ?? (orgs.length === 1 ? orgs[0]!.slug : undefined)\n\n writeConfig({ url: url.replace(/\\/+$/, ''), token, ...(org ? { org } : {}) })\n\n if (global.json) {\n printJson({\n url,\n org: org ?? null,\n user: session,\n organizations: orgs,\n configPath: configPath(),\n })\n return\n }\n print(`Signed in to ${url} as ${session.email}.`)\n if (org) print(`Default organization: ${org}`)\n else if (orgs.length > 1)\n print(`Several organizations are visible; pass --org next time or set AICTIQ_ORG.`)\n print(`Token stored in ${configPath()} (0600).`)\n })\n\n auth\n .command('status')\n .description('Show the configured instance, identity and organizations')\n .action(async () => {\n const global = globals()\n const settings = resolveSettings(global)\n if (!settings.url || !settings.token) {\n if (global.json) {\n printJson({ authenticated: false, url: settings.url ?? null, configPath: configPath() })\n return\n }\n throw new CliError('Not signed in. Run `aictiq auth login --url <url>`.', ExitCode.Auth)\n }\n\n const client = new AictiqClient({ baseUrl: settings.url, token: settings.token })\n const session = await client.request<SessionResponse, '/api/v1/auth/session', 'get'>(\n 'get',\n '/api/v1/auth/session',\n )\n const orgs = await client.request<OrganizationSummary[], '/api/v1/orgs', 'get'>(\n 'get',\n '/api/v1/orgs',\n )\n\n if (global.json) {\n printJson({\n authenticated: true,\n url: settings.url,\n org: settings.org ?? null,\n user: session,\n organizations: orgs,\n configPath: configPath(),\n })\n return\n }\n print(\n renderFields([\n ['URL', settings.url],\n ['User', `${session.email} (${session.id})`],\n ['Organization', settings.org ?? '(not set)'],\n ['Config', configPath()],\n ]),\n )\n if (orgs.length > 0) {\n print('')\n print(\n renderTable(orgs, [\n { header: 'SLUG', value: (o) => o.slug },\n { header: 'NAME', value: (o) => o.name },\n { header: 'ROLE', value: (o) => o.role },\n ]),\n )\n }\n })\n\n auth\n .command('logout')\n .description('Delete the stored token')\n .action(() => {\n clearConfig()\n if (globals().json) printJson({ removed: configPath() })\n else print(`Removed ${configPath()}.`)\n })\n\n return auth\n}\n","export interface Column<T> {\n header: string\n value: (row: T) => string\n /** Right-align numeric columns so magnitudes line up. */\n align?: 'left' | 'right'\n}\n\n/**\n * Every command prints either `--json` (the machine contract) or a table (the human one).\n * The table is plain text with two spaces between columns: no colour, no box drawing, and\n * no truncation of the last column, so `| grep` and `| cut` stay useful.\n */\nexport function renderTable<T>(rows: readonly T[], columns: readonly Column<T>[]): string {\n const cells = rows.map((row) => columns.map((column) => column.value(row) ?? ''))\n const widths = columns.map((column, index) =>\n Math.max(column.header.length, ...cells.map((row) => row[index]?.length ?? 0), 0),\n )\n const line = (values: readonly string[]) =>\n values\n .map((value, index) =>\n index === values.length - 1\n ? columns[index]?.align === 'right'\n ? value.padStart(widths[index]!)\n : value\n : columns[index]?.align === 'right'\n ? value.padStart(widths[index]!)\n : value.padEnd(widths[index]!),\n )\n .join(' ')\n .trimEnd()\n\n return [line(columns.map((c) => c.header)), ...cells.map(line)].join('\\n')\n}\n\n/** Key/value block for a single record, used by the `view` commands. */\nexport function renderFields(fields: readonly (readonly [string, string | undefined])[]): string {\n const present = fields.filter((f): f is [string, string] => f[1] !== undefined && f[1] !== '')\n const width = Math.max(0, ...present.map(([label]) => label.length))\n return present.map(([label, value]) => `${label.padEnd(width)} ${value}`).join('\\n')\n}\n\nexport function print(text: string): void {\n process.stdout.write(text.endsWith('\\n') ? text : `${text}\\n`)\n}\n\nexport function printJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`)\n}\n\nexport function formatDate(value: string | null | undefined): string {\n if (!value) return ''\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? String(value) : date.toISOString().slice(0, 10)\n}\n\nexport function formatNumber(value: number | null | undefined): string {\n return value === null || value === undefined ? '' : String(value)\n}\n\n/** Date and time to the second, UTC - a run's timings are minutes apart, not days. */\nexport function formatDateTime(value: string | null | undefined): string {\n if (!value) return ''\n const date = new Date(value)\n return Number.isNaN(date.getTime())\n ? String(value)\n : `${date.toISOString().slice(0, 19).replace('T', ' ')}Z`\n}\n","import { createInterface } from 'node:readline'\n\n/**\n * Reads a secret from the terminal without echoing it, or from a pipe when stdin is not a\n * TTY (`echo $TOKEN | aictiq auth login`), which is how CI supplies one without putting\n * the token on a command line that `ps` would show.\n */\nexport async function promptSecret(question: string): Promise<string> {\n if (!process.stdin.isTTY) {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk))\n return Buffer.concat(chunks).toString('utf8').trim()\n }\n\n const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: true })\n try {\n process.stdout.write(question)\n const muted = rl as unknown as { output: NodeJS.WriteStream; _writeToOutput?: unknown }\n const original = muted.output.write.bind(muted.output)\n muted.output.write = (() => true) as typeof muted.output.write\n const answer = await new Promise<string>((resolve) => rl.question('', resolve))\n muted.output.write = original\n process.stdout.write('\\n')\n return answer.trim()\n } finally {\n rl.close()\n }\n}\n","import { Command, Option } from 'commander'\nimport type { CommentView, ItemLinkView, PagedResult, WorkItemView } from '../api/views.js'\nimport type { WorkItemPriority, WorkItemType } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { formatDate, formatNumber, print, printJson, renderFields, renderTable } from '../output.js'\nimport {\n branchName,\n findState,\n getItem,\n getLabels,\n getTeams,\n getWorkflow,\n normalizeItemKey,\n projectKeyOf,\n readBody,\n resolveLabelIds,\n} from '../resolve.js'\n\nconst types: WorkItemType[] = ['epic', 'feature', 'story', 'task', 'bug']\nconst priorities: WorkItemPriority[] = ['none', 'low', 'medium', 'high', 'urgent']\n\nexport function itemCommand(globals: () => GlobalOptions): Command {\n const item = new Command('item').description('Work items')\n\n item\n .command('list')\n .description('List work items in a project')\n .requiredOption('-p, --project <key>', 'Project key, e.g. ACME')\n .option(\n '-f, --filter <expression>',\n 'Item filter, e.g. \"state:active assignee:@me label:backend\"',\n )\n .option('-q, --query <text>', 'Full-text search within the project')\n .option('-s, --sort <field>', 'Sort expression accepted by the API')\n .option('--page <n>', 'Page number', '1')\n .option('--page-size <n>', 'Items per page (max 100)', '25')\n .action(\n async (options: {\n project: string\n filter?: string\n query?: string\n sort?: string\n page: string\n pageSize: string\n }) => {\n const ctx = createContext(globals())\n const page = await ctx.client.request<\n PagedResult<WorkItemView>,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items', {\n path: { orgSlug: await ctx.org(), projectKey: options.project.toUpperCase() },\n query: {\n filter: options.filter,\n q: options.query,\n sort: options.sort,\n page: options.page,\n pageSize: options.pageSize,\n },\n })\n\n if (ctx.json) return printJson(page)\n if (page.items.length === 0) return print('No items match.')\n print(\n renderTable(page.items, [\n { header: 'KEY', value: (i) => i.key },\n { header: 'TYPE', value: (i) => i.type },\n { header: 'STATE', value: (i) => i.stateCategory },\n { header: 'PRIORITY', value: (i) => i.priority },\n { header: 'PTS', value: (i) => formatNumber(i.points), align: 'right' },\n { header: 'TITLE', value: (i) => i.title },\n ]),\n )\n print('')\n print(`Page ${page.page} of ${Math.max(1, page.totalPages)} · ${page.totalCount} items`)\n },\n )\n\n item\n .command('view')\n .description('Show one work item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--comments', 'Include the comment thread')\n .option('--links', 'Include external links')\n .action(async (key: string, options: { comments?: boolean; links?: boolean }) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const itemKey = normalizeItemKey(key)\n const found = await getItem(ctx, itemKey)\n const comments = options.comments ? await listComments(ctx, orgSlug, itemKey) : undefined\n const links = options.links ? await listLinks(ctx, orgSlug, itemKey) : undefined\n\n if (ctx.json) {\n return printJson({\n ...found,\n ...(comments ? { comments } : {}),\n ...(links ? { links } : {}),\n })\n }\n\n const state = await stateName(ctx, found)\n print(`${found.key} ${found.title}`)\n print('')\n print(\n renderFields([\n ['Type', found.type],\n ['State', `${state} (${found.stateCategory})`],\n ['Priority', found.priority],\n ['Assignee', found.assigneeId ?? '(unassigned)'],\n ['Claimed by', found.claimedBy ?? undefined],\n ['Points', formatNumber(found.points)],\n ['Remaining hours', formatNumber(found.remainingHours)],\n ['Labels', found.labels.map((l) => l.name).join(', ')],\n ['Blocked', found.blocked ? 'yes' : ''],\n ['Updated', formatDate(found.updatedAt)],\n ['Version', String(found.version)],\n ]),\n )\n if (found.descriptionMarkdown.trim().length > 0) {\n print('')\n print(found.descriptionMarkdown.trim())\n }\n if (links && links.length > 0) {\n print('')\n print(\n renderTable(links, [\n { header: 'KIND', value: (l) => l.kind },\n { header: 'URL', value: (l) => l.url },\n { header: 'TITLE', value: (l) => l.title ?? '' },\n ]),\n )\n }\n if (comments) {\n print('')\n for (const comment of comments) {\n if (comment.deletedAt) continue\n print(\n `--- ${comment.author.displayName}${comment.author.isAgent ? ' [agent]' : ''} · ${formatDate(comment.createdAt)}`,\n )\n print(comment.bodyMarkdown.trim())\n print('')\n }\n }\n })\n\n item\n .command('create')\n .description('Create a work item')\n .requiredOption('-p, --project <key>', 'Project key, e.g. ACME')\n .addOption(new Option('-t, --type <type>', 'Item type').choices(types).default('task'))\n .requiredOption('--title <title>', 'Item title')\n .option('-m, --body <markdown>', 'Description in Markdown')\n .option('--body-file <path>', 'Read the description from a file, or - for stdin')\n .addOption(new Option('--priority <priority>', 'Priority').choices(priorities))\n .option('--parent <key>', 'Parent item key, e.g. ACME-100')\n .option('--team <key>', 'Team key or name')\n .option('--labels <names>', 'Comma-separated label names')\n .option('--points <n>', 'Story points')\n .option('--estimate <hours>', 'Original estimate in hours')\n .action(\n async (options: {\n project: string\n type: WorkItemType\n title: string\n body?: string\n bodyFile?: string\n priority?: WorkItemPriority\n parent?: string\n team?: string\n labels?: string\n points?: string\n estimate?: string\n }) => {\n const ctx = createContext(globals())\n const projectKey = options.project.toUpperCase()\n const description = await readBody(options.body, options.bodyFile)\n const parent = options.parent ? await getItem(ctx, options.parent) : undefined\n const teamId = options.team ? await resolveTeamId(ctx, projectKey, options.team) : undefined\n const labelIds = options.labels\n ? resolveLabelIds(options.labels, await getLabels(ctx, projectKey), [])\n : undefined\n\n const created = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items', {\n path: { orgSlug: await ctx.org(), projectKey },\n body: {\n type: options.type,\n title: options.title,\n ...(description === undefined ? {} : { descriptionMarkdown: description }),\n ...(options.priority ? { priority: options.priority } : {}),\n ...(parent ? { parentId: parent.id } : {}),\n ...(teamId ? { teamId } : {}),\n ...(labelIds ? { labelIds } : {}),\n ...(options.points ? { points: number(options.points, 'points') } : {}),\n ...(options.estimate ? { estimateHours: number(options.estimate, 'estimate') } : {}),\n },\n })\n\n if (ctx.json) return printJson(created)\n print(`${created.key} ${created.title}`)\n },\n )\n\n item\n .command('update')\n .description('Update a work item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--title <title>', 'New title')\n .option('-m, --body <markdown>', 'New description in Markdown')\n .option('--body-file <path>', 'Read the description from a file, or - for stdin')\n .addOption(new Option('--priority <priority>', 'Priority').choices(priorities))\n .addOption(new Option('--type <type>', 'Item type').choices(types))\n .option('--assignee <userId>', 'Assignee user id, or \"none\" to unassign')\n .option('--labels <names>', 'Label names: a plain list replaces, +name/-name adjusts')\n .option('--points <n>', 'Story points')\n .option('--estimate <hours>', 'Original estimate in hours')\n .option('--remaining <hours>', 'Remaining hours')\n .option('--version <n>', 'Expected version; read from the item when omitted')\n .action(\n async (\n key: string,\n options: {\n title?: string\n body?: string\n bodyFile?: string\n priority?: WorkItemPriority\n type?: WorkItemType\n assignee?: string\n labels?: string\n points?: string\n estimate?: string\n remaining?: string\n version?: string\n },\n ) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n const current = await getItem(ctx, itemKey)\n const description = await readBody(options.body, options.bodyFile)\n const labelIds = options.labels\n ? resolveLabelIds(\n options.labels,\n await getLabels(ctx, projectKeyOf(itemKey)),\n current.labels,\n )\n : undefined\n\n const updated = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}',\n 'patch'\n >('patch', '/api/v1/orgs/{orgSlug}/items/{itemKey}', {\n path: { orgSlug: await ctx.org(), itemKey },\n body: {\n // PATCH is an absolute assignment for the nullable fields - an omitted\n // `parentId` unparents the item, an omitted `assigneeId` unassigns it. So the\n // body starts from what the item currently holds and the flags overwrite it;\n // otherwise `--priority high` would quietly detach a story from its feature.\n type: current.type,\n title: current.title,\n descriptionMarkdown: current.descriptionMarkdown,\n stateId: current.stateId,\n priority: current.priority,\n assigneeId: current.assigneeId,\n teamId: current.teamId,\n parentId: current.parentId,\n points: current.points,\n estimateHours: current.estimateHours,\n remainingHours: current.remainingHours,\n completedHours: current.completedHours,\n dueDate: current.dueDate,\n version: options.version ? number(options.version, 'version') : current.version,\n ...(options.title === undefined ? {} : { title: options.title }),\n ...(description === undefined ? {} : { descriptionMarkdown: description }),\n ...(options.priority ? { priority: options.priority } : {}),\n ...(options.type ? { type: options.type } : {}),\n ...(options.assignee === undefined\n ? {}\n : { assigneeId: options.assignee === 'none' ? null : options.assignee }),\n ...(labelIds ? { labelIds } : {}),\n ...(options.points ? { points: number(options.points, 'points') } : {}),\n ...(options.estimate ? { estimateHours: number(options.estimate, 'estimate') } : {}),\n ...(options.remaining\n ? { remainingHours: number(options.remaining, 'remaining') }\n : {}),\n },\n })\n\n if (ctx.json) return printJson(updated)\n print(`${updated.key} updated (version ${updated.version}).`)\n },\n )\n\n item\n .command('move')\n .description('Move an item: to another workflow state, sprint, parent or backlog rank')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--state <name>', 'Workflow state to transition to, e.g. \"In Review\"')\n .option('--sprint <sprintId>', 'Sprint id, or \"none\" to return it to the backlog')\n .option('--parent <key>', 'New parent item key')\n .option('--after <key>', 'Rank it directly after this item')\n .option('--before <key>', 'Rank it directly before this item')\n .option('--version <n>', 'Expected version; read from the item when omitted')\n .action(\n async (\n key: string,\n options: {\n state?: string\n sprint?: string\n parent?: string\n after?: string\n before?: string\n version?: string\n },\n ) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const itemKey = normalizeItemKey(key)\n const current = await getItem(ctx, itemKey)\n const version = options.version ? number(options.version, 'version') : current.version\n const ranking =\n options.sprint !== undefined ||\n options.parent !== undefined ||\n options.after !== undefined ||\n options.before !== undefined\n\n if (!options.state && !ranking) {\n throw new CliError(\n 'Pass --state, or one of --sprint/--parent/--after/--before.',\n ExitCode.Validation,\n )\n }\n\n let result: WorkItemView = current\n if (options.state) {\n const workflow = await getWorkflow(ctx, projectKeyOf(itemKey))\n const state = findState(workflow, options.state)\n result = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/transition',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/transition', {\n path: { orgSlug, itemKey },\n body: { toStateId: state.id, version },\n })\n }\n if (ranking) {\n result = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/move',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/move', {\n path: { orgSlug, itemKey },\n body: {\n // The transition above already spent the version it read.\n version: options.state ? result.version : version,\n ...(options.sprint === undefined\n ? {}\n : options.sprint === 'none'\n ? { removeSprint: true }\n : { sprintId: options.sprint }),\n ...(options.parent === undefined\n ? {}\n : { parentKey: normalizeItemKey(options.parent) }),\n ...(options.after === undefined ? {} : { afterKey: normalizeItemKey(options.after) }),\n ...(options.before === undefined\n ? {}\n : { beforeKey: normalizeItemKey(options.before) }),\n },\n })\n }\n\n if (ctx.json) return printJson(result)\n print(`${result.key} moved (version ${result.version}).`)\n },\n )\n\n // Claim is the compare-and-swap: it needs the version it expects to find, so that two\n // agents racing for the same item produce one claim and one 409 (exit code 3). Release\n // and heartbeat act on the claim that already exists and carry no version.\n item\n .command('claim')\n .description('Claim an item for the authenticated identity (compare-and-swap)')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--version <n>', 'Expected version; read from the item when omitted')\n .action(async (key: string, options: { version?: string }) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n const version = options.version\n ? number(options.version, 'version')\n : (await getItem(ctx, itemKey)).version\n const result = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/claim',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/claim', {\n path: { orgSlug: await ctx.org(), itemKey },\n body: { version },\n })\n if (ctx.json) return printJson(result)\n print(`${itemKey} claimed.`)\n })\n\n item\n .command('release')\n .description('Release a claim you hold')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .action(async (key: string) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n // Release and heartbeat answer 204: they act on a claim that already exists and\n // have nothing to return, so --json reports what happened rather than an empty body.\n await ctx.client.request<void, '/api/v1/orgs/{orgSlug}/items/{itemKey}/release', 'post'>(\n 'post',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/release',\n { path: { orgSlug: await ctx.org(), itemKey } },\n )\n if (ctx.json) return printJson({ key: itemKey, released: true })\n print(`${itemKey} released.`)\n })\n\n item\n .command('heartbeat')\n .description('Refresh the claim heartbeat so the claim does not go stale')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .action(async (key: string) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n await ctx.client.request<void, '/api/v1/orgs/{orgSlug}/items/{itemKey}/heartbeat', 'post'>(\n 'post',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/heartbeat',\n { path: { orgSlug: await ctx.org(), itemKey } },\n )\n if (ctx.json) return printJson({ key: itemKey, heartbeat: new Date().toISOString() })\n print(`${itemKey} heartbeat sent.`)\n })\n\n item\n .command('comment')\n .description('Add a comment to an item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('-m, --body <markdown>', 'Comment body in Markdown')\n .option('--body-file <path>', 'Read the body from a file, or - for stdin')\n .action(async (key: string, options: { body?: string; bodyFile?: string }) => {\n const ctx = createContext(globals())\n const body = await readBody(options.body, options.bodyFile)\n if (!body || body.trim().length === 0) {\n throw new CliError('Pass -m \"text\" or --body-file <path>.', ExitCode.Validation)\n }\n const comment = await ctx.client.request<\n CommentView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments', {\n path: { orgSlug: await ctx.org(), itemKey: normalizeItemKey(key) },\n body: { bodyMarkdown: body },\n })\n\n if (ctx.json) return printJson(comment)\n print(`Comment added to ${normalizeItemKey(key)}.`)\n })\n\n item\n .command('subtask')\n .description('Create a child item under an existing one')\n .argument('<key>', 'Parent item key, e.g. ACME-123')\n .requiredOption('--title <title>', 'Subtask title')\n .addOption(new Option('-t, --type <type>', 'Item type').choices(types).default('task'))\n .option('-m, --body <markdown>', 'Description in Markdown')\n .option('--body-file <path>', 'Read the description from a file, or - for stdin')\n .option('--estimate <hours>', 'Original estimate in hours')\n .action(\n async (\n key: string,\n options: {\n title: string\n type: WorkItemType\n body?: string\n bodyFile?: string\n estimate?: string\n },\n ) => {\n const ctx = createContext(globals())\n const parentKey = normalizeItemKey(key)\n const parent = await getItem(ctx, parentKey)\n const description = await readBody(options.body, options.bodyFile)\n\n const created = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items', {\n path: { orgSlug: await ctx.org(), projectKey: projectKeyOf(parentKey) },\n body: {\n type: options.type,\n title: options.title,\n parentId: parent.id,\n ...(parent.teamId ? { teamId: parent.teamId } : {}),\n ...(description === undefined ? {} : { descriptionMarkdown: description }),\n ...(options.estimate ? { estimateHours: number(options.estimate, 'estimate') } : {}),\n },\n })\n\n if (ctx.json) return printJson(created)\n print(`${created.key} ${created.title}`)\n },\n )\n\n item\n .command('link')\n .description('Attach an external link to an item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--url <url>', 'Any public URL')\n .option('--pr <url>', 'Pull request URL (an alias for --url)')\n .action(async (key: string, options: { url?: string; pr?: string }) => {\n const ctx = createContext(globals())\n const url = options.url ?? options.pr\n if (!url) throw new CliError('Pass --url <url> or --pr <url>.', ExitCode.Validation)\n const link = await ctx.client.request<\n ItemLinkView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/links',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/links', {\n path: { orgSlug: await ctx.org(), itemKey: normalizeItemKey(key) },\n body: { url },\n })\n\n if (ctx.json) return printJson(link)\n print(`Linked ${link.url} to ${normalizeItemKey(key)}.`)\n })\n\n item\n .command('branch')\n .description('Print the branch name convention for an item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .action(async (key: string) => {\n const ctx = createContext(globals())\n const found = await getItem(ctx, key)\n const branch = branchName(found)\n if (ctx.json) return printJson({ key: found.key, branch })\n print(branch)\n })\n\n return item\n}\n\nasync function listComments(ctx: Context, orgSlug: string, itemKey: string) {\n const page = await ctx.client.request<\n PagedResult<CommentView>,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments', {\n path: { orgSlug, itemKey },\n query: { pageSize: 100 },\n })\n return page.items\n}\n\nasync function listLinks(ctx: Context, orgSlug: string, itemKey: string) {\n return ctx.client.request<ItemLinkView[], '/api/v1/orgs/{orgSlug}/items/{itemKey}/links', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/links',\n { path: { orgSlug, itemKey } },\n )\n}\n\nasync function stateName(ctx: Context, item: WorkItemView): Promise<string> {\n const workflow = await getWorkflow(ctx, projectKeyOf(item.key))\n return workflow.states.find((s) => s.id === item.stateId)?.name ?? item.stateCategory\n}\n\nasync function resolveTeamId(ctx: Context, projectKey: string, wanted: string): Promise<string> {\n const teams = await getTeams(ctx, projectKey)\n const needle = wanted.trim().toLowerCase()\n const team = teams.find(\n (t) => t.key.toLowerCase() === needle || t.name.toLowerCase() === needle || t.id === wanted,\n )\n if (!team) {\n throw new CliError(\n `No team \"${wanted}\" in ${projectKey}. Teams: ${teams.map((t) => t.key).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n return team.id\n}\n\nfunction number(raw: string, field: string): number {\n const parsed = Number(raw)\n if (!Number.isFinite(parsed)) {\n throw new CliError(`--${field} must be a number, got \"${raw}\".`, ExitCode.Validation)\n }\n return parsed\n}\n","import { readFileSync } from 'node:fs'\nimport type { Context } from './context.js'\nimport { CliError, ExitCode } from './errors.js'\nimport type {\n ItemLabelView,\n TeamView,\n WorkflowStateView,\n WorkflowView,\n WorkItemView,\n} from './api/views.js'\n\n/** `ACME-123` → `ACME`. Project keys are `^[A-Z][A-Z0-9]{1,9}$`, so the last dash splits. */\nexport function projectKeyOf(itemKey: string): string {\n const normalized = itemKey.trim().toUpperCase()\n const dash = normalized.lastIndexOf('-')\n if (dash <= 0) {\n throw new CliError(\n `\"${itemKey}\" is not a work item key (expected e.g. ACME-123).`,\n ExitCode.Validation,\n )\n }\n return normalized.slice(0, dash)\n}\n\nexport function normalizeItemKey(itemKey: string): string {\n return itemKey.trim().toUpperCase()\n}\n\nexport async function getWorkflow(ctx: Context, projectKey: string): Promise<WorkflowView> {\n const workflows = await ctx.client.request<\n WorkflowView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/workflows',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/workflows', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n const workflow = workflows.find((w) => w.isDefault) ?? workflows[0]\n if (!workflow) throw new CliError(`Project ${projectKey} has no workflow.`, ExitCode.NotFound)\n return workflow\n}\n\n/** Matches a state by name, case-insensitively; the error lists what was available. */\nexport function findState(workflow: WorkflowView, name: string): WorkflowStateView {\n const wanted = name.trim().toLowerCase()\n const state = workflow.states.find((s) => s.name.toLowerCase() === wanted)\n if (!state) {\n const names = workflow.states.map((s) => s.name).join(', ')\n throw new CliError(`No workflow state named \"${name}\". States: ${names}.`, ExitCode.Validation)\n }\n return state\n}\n\nexport async function getLabels(ctx: Context, projectKey: string): Promise<ItemLabelView[]> {\n return ctx.client.request<\n ItemLabelView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/labels',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/labels', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n}\n\nexport async function getTeams(ctx: Context, projectKey: string): Promise<TeamView[]> {\n return ctx.client.request<\n TeamView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/teams',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/teams', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n}\n\nexport async function getItem(ctx: Context, itemKey: string): Promise<WorkItemView> {\n return ctx.client.request<WorkItemView, '/api/v1/orgs/{orgSlug}/items/{itemKey}', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}',\n { path: { orgSlug: await ctx.org(), itemKey: normalizeItemKey(itemKey) } },\n )\n}\n\n/**\n * `--labels backend,+urgent,-stale`: a bare list replaces, `+`/`-` adjust. Mixing the two\n * is refused rather than guessed at, because \"did that clear the others?\" is not a\n * question a script should have to answer by reading the result back.\n */\nexport function resolveLabelIds(\n spec: string,\n available: readonly ItemLabelView[],\n current: readonly ItemLabelView[],\n): string[] {\n const tokens = spec\n .split(',')\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n const adjusting = tokens.some((t) => t.startsWith('+') || t.startsWith('-'))\n const replacing = tokens.some((t) => !t.startsWith('+') && !t.startsWith('-'))\n if (adjusting && replacing) {\n throw new CliError(\n 'Use either a plain label list (replaces all) or +/- adjustments, not both.',\n ExitCode.Validation,\n )\n }\n\n const byName = new Map(available.map((label) => [label.name.toLowerCase(), label]))\n const lookup = (name: string) => {\n const label = byName.get(name.toLowerCase())\n if (!label) {\n throw new CliError(\n `No label \"${name}\" in this project. Labels: ${available.map((l) => l.name).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n return label.id\n }\n\n if (!adjusting) return tokens.map(lookup)\n\n const ids = new Set(current.map((label) => label.id))\n for (const token of tokens) {\n const id = lookup(token.slice(1))\n if (token.startsWith('+')) ids.add(id)\n else ids.delete(id)\n }\n return [...ids]\n}\n\n/** `-m \"text\"` or `--body-file path` (`-` reads stdin). */\nexport async function readBody(\n message: string | undefined,\n file: string | undefined,\n): Promise<string | undefined> {\n if (message !== undefined && file !== undefined) {\n throw new CliError('Pass either -m or --body-file, not both.', ExitCode.Validation)\n }\n if (message !== undefined) return message\n if (file === undefined) return undefined\n if (file === '-') {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk))\n return Buffer.concat(chunks).toString('utf8')\n }\n try {\n return readFileSync(file, 'utf8')\n } catch (cause) {\n throw new CliError(\n `Cannot read ${file}: ${cause instanceof Error ? cause.message : String(cause)}`,\n ExitCode.Validation,\n )\n }\n}\n\n/**\n * `ACME-123` + \"Fix the login redirect\" → `acme-123-fix-the-login-redirect`.\n * The key stays first so a branch name is enough for commit linking to attach\n * the work back to the item.\n */\nexport function branchName(item: Pick<WorkItemView, 'key' | 'title'>, maxWords = 6): string {\n const slug = item.title\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[^\\da-z]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .filter((word) => word.length > 0)\n .slice(0, maxWords)\n .join('-')\n return slug ? `${item.key.toLowerCase()}-${slug}` : item.key.toLowerCase()\n}\n","import { Command } from 'commander'\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { resolveSettings } from '../context.js'\nimport { version } from '../version.js'\nimport type { GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\n\n/**\n * `aictiq mcp` is a stdio MCP server that forwards to the instance's Streamable HTTP\n * `/mcp` endpoint. Clients that only speak stdio (or that should not be handed a bearer\n * token in their configuration file) point at this instead: the token comes from the\n * CLI's own 0600 config, so an agent's `.mcp.json` can be committed.\n *\n * The bridge deliberately holds no catalogue of its own - every list and call is\n * forwarded, so a tool added to the API on Tuesday is reachable through an unchanged CLI\n * on Wednesday. Only `notifications/initialized` and the handshake are handled locally.\n */\nexport function mcpCommand(globals: () => GlobalOptions): Command {\n return new Command('mcp')\n .description('Run a stdio MCP server bridged to this instance (for Claude Code and friends)')\n .action(async () => {\n const settings = resolveSettings(globals())\n if (!settings.url || !settings.token) {\n throw new CliError(\n 'No instance configured. Run `aictiq auth login --url <url>` or set AICTIQ_URL and AICTIQ_TOKEN.',\n ExitCode.Auth,\n )\n }\n\n // The bridge itself offers no sampling, roots or elicitation: it forwards server\n // capabilities downstream and nothing upstream.\n const upstream = new Client({ name: 'aictiq-cli', version }, { capabilities: {} })\n try {\n await upstream.connect(\n new StreamableHTTPClientTransport(\n new URL('/mcp', `${settings.url.replace(/\\/+$/, '')}/`),\n { requestInit: { headers: { Authorization: `Bearer ${settings.token}` } } },\n ),\n )\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause)\n // `/mcp` needs more than a valid token: the `mcp` scope, and a token bound to one\n // organization. Both refusals arrive here as a bare 403, which on its own tells\n // nobody which of the two to fix.\n throw new CliError(\n detail.includes('403') || detail.includes('401')\n ? `${settings.url} refused the token for /mcp. It needs the \"mcp\" scope and must be bound to one organization - create it under Settings → Access tokens with an organization selected.`\n : `Cannot open an MCP session at ${settings.url}/mcp: ${detail}`,\n ExitCode.Auth,\n )\n }\n\n // Advertise exactly what the instance advertises: a client that sees `prompts` here\n // but gets \"method not found\" from upstream has been lied to by the bridge.\n const capabilities = upstream.getServerCapabilities() ?? {}\n const server = new Server(\n { name: 'aictiq', version },\n {\n capabilities: {\n ...(capabilities.tools ? { tools: capabilities.tools } : {}),\n ...(capabilities.resources ? { resources: capabilities.resources } : {}),\n ...(capabilities.prompts ? { prompts: capabilities.prompts } : {}),\n },\n },\n )\n\n if (capabilities.tools) {\n server.setRequestHandler(ListToolsRequestSchema, (request) =>\n upstream.listTools(request.params),\n )\n server.setRequestHandler(CallToolRequestSchema, (request) =>\n upstream.callTool(request.params),\n )\n }\n if (capabilities.resources) {\n server.setRequestHandler(ListResourcesRequestSchema, (request) =>\n upstream.listResources(request.params),\n )\n server.setRequestHandler(ListResourceTemplatesRequestSchema, (request) =>\n upstream.listResourceTemplates(request.params),\n )\n server.setRequestHandler(ReadResourceRequestSchema, (request) =>\n upstream.readResource(request.params),\n )\n }\n if (capabilities.prompts) {\n server.setRequestHandler(ListPromptsRequestSchema, (request) =>\n upstream.listPrompts(request.params),\n )\n server.setRequestHandler(GetPromptRequestSchema, (request) =>\n upstream.getPrompt(request.params),\n )\n }\n\n // stdout is the transport, so nothing else may be written to it while the bridge\n // runs; diagnostics go to stderr.\n await server.connect(new StdioServerTransport())\n\n const shutdown = async () => {\n await Promise.allSettled([server.close(), upstream.close()])\n process.exit(0)\n }\n process.on('SIGINT', () => void shutdown())\n process.on('SIGTERM', () => void shutdown())\n\n // Resolve only when stdin closes, which is how a stdio MCP client says goodbye.\n await new Promise<void>((resolve) => process.stdin.once('close', resolve))\n await shutdown()\n })\n}\n","import { createRequire } from 'node:module'\n\n// Read at runtime rather than baked in by the bundler, so `aictiq --version` and the MCP\n// handshake cannot drift from the version npm actually installed.\nconst manifest = createRequire(import.meta.url)('../package.json') as { version?: string }\n\nexport const version = manifest.version ?? '0.0.0'\n","import { Command } from 'commander'\nimport type { ProjectView } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { GlobalOptions } from '../context.js'\nimport { print, printJson, renderTable } from '../output.js'\n\nexport function projectCommand(globals: () => GlobalOptions): Command {\n const project = new Command('project').description('Projects in the organization')\n\n project\n .command('list')\n .description('List the projects you can see')\n .option('--archived', 'Include archived projects')\n .action(async (options: { archived?: boolean }) => {\n const ctx = createContext(globals())\n const projects = await ctx.client.request<\n ProjectView[],\n '/api/v1/orgs/{orgSlug}/projects',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects', {\n path: { orgSlug: await ctx.org() },\n query: { includeArchived: options.archived === true },\n })\n\n if (ctx.json) return printJson(projects)\n if (projects.length === 0) return print('No projects.')\n print(\n renderTable(projects, [\n { header: 'KEY', value: (p) => p.key },\n { header: 'NAME', value: (p) => p.name },\n { header: 'ROLE', value: (p) => p.role },\n { header: 'VISIBILITY', value: (p) => p.visibility },\n { header: 'STATUS', value: (p) => (p.isArchived ? 'archived' : 'active') },\n ]),\n )\n })\n\n return project\n}\n","import { Command } from 'commander'\nimport type {\n AgentView,\n PagedResult,\n PlaybookView,\n RunLogEntry,\n RunLogPage,\n RunStatus,\n RunView,\n} from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport {\n formatDateTime,\n formatNumber,\n print,\n printJson,\n renderFields,\n renderTable,\n} from '../output.js'\nimport { normalizeItemKey, projectKeyOf } from '../resolve.js'\n\nconst statuses: RunStatus[] = [\n 'queued',\n 'assigned',\n 'running',\n 'succeeded',\n 'failed',\n 'cancelled',\n 'timedOut',\n]\nconst terminal = new Set<RunStatus>(['succeeded', 'failed', 'cancelled', 'timedOut'])\n\n/** One page of the log per request; the API clamps at 1000. */\nconst logPageSize = 200\n\n/**\n * The server's \"log truncated\" marker sits at `int.MaxValue` (`RunLogChunk.TruncatedSeq`);\n * `truncated` on the page is the flag, so the marker row itself is not printed as output.\n */\nconst truncatedSeq = 2147483647\n\n/**\n * `--follow` polls rather than joining the hub: a CLI has no SignalR client and a poll every\n * two seconds is the right cost for a log that grows a few lines at a time. The interval is\n * an environment variable so a test does not spend two real seconds per iteration.\n */\nconst defaultPollMs = 2000\n\nexport function pollIntervalMs(env: NodeJS.ProcessEnv = process.env): number {\n const raw = env.AICTIQ_RUN_POLL_MS\n if (raw === undefined || raw === '') return defaultPollMs\n const parsed = Number(raw)\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : defaultPollMs\n}\n\nexport function runCommand(globals: () => GlobalOptions): Command {\n const run = new Command('run').description('Factory runs: hand an item to an agent and watch it')\n\n run\n .command('start')\n .description('Dispatch a run for a work item')\n .argument('<key>', 'Work item key, e.g. ACME-123')\n .option('--playbook <nameOrId>', \"One of the project's playbooks; the default when omitted\")\n .option(\n '--agent <nameOrId>',\n \"An agent of the project; the project's default agent when omitted\",\n )\n .action(async (key: string, options: { playbook?: string; agent?: string }) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const itemKey = normalizeItemKey(key)\n const playbookId = options.playbook\n ? await resolvePlaybookId(ctx, projectKeyOf(itemKey), options.playbook)\n : undefined\n const agentId = options.agent ? await resolveAgentId(ctx, options.agent) : undefined\n\n const started = await ctx.client.request<\n RunView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/runs',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/runs', {\n path: { orgSlug, itemKey },\n body: {\n ...(playbookId === undefined ? {} : { playbookId }),\n ...(agentId === undefined ? {} : { agentId }),\n },\n })\n\n if (ctx.json) return printJson(started)\n print(\n renderFields([\n ['Run', started.id],\n ['Item', started.itemKey],\n ['Status', started.status],\n ['Agent', started.agentName ?? started.agentId],\n ['Playbook', started.playbookName ?? started.playbookId],\n ]),\n )\n })\n\n run\n .command('list')\n .description('List runs, newest first')\n .option('-p, --project <key>', 'Only runs in this project')\n .option('--status <status>', `One of ${statuses.join(', ')}`)\n .option('--agent <id>', 'Only runs by this agent (user id)')\n .option('--item <key>', 'Only runs for this item')\n .option('--page <n>', 'Page number', '1')\n .option('--page-size <n>', 'Runs per page (max 100)', '25')\n .action(\n async (options: {\n project?: string\n status?: string\n agent?: string\n item?: string\n page: string\n pageSize: string\n }) => {\n const ctx = createContext(globals())\n if (options.status !== undefined && !statuses.includes(options.status as RunStatus)) {\n throw new CliError(\n `Unknown run status \"${options.status}\". Statuses: ${statuses.join(', ')}.`,\n ExitCode.Validation,\n )\n }\n const page = await ctx.client.request<\n PagedResult<RunView>,\n '/api/v1/orgs/{orgSlug}/runs',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/runs', {\n path: { orgSlug: await ctx.org() },\n query: {\n project: options.project?.toUpperCase(),\n status: options.status,\n agent: options.agent,\n item: options.item === undefined ? undefined : normalizeItemKey(options.item),\n page: options.page,\n pageSize: options.pageSize,\n },\n })\n\n if (ctx.json) return printJson(page)\n if (page.items.length === 0) return print('No runs match.')\n print(\n renderTable(page.items, [\n { header: 'ID', value: (r) => r.id },\n { header: 'ITEM', value: (r) => r.itemKey },\n { header: 'STATUS', value: (r) => r.status },\n { header: 'AGENT', value: (r) => r.agentName ?? r.agentId },\n { header: 'PLAYBOOK', value: (r) => r.playbookName ?? r.playbookId },\n { header: 'QUEUED', value: (r) => formatDateTime(r.queuedAt) },\n { header: 'FINISHED', value: (r) => formatDateTime(r.finishedAt) },\n { header: 'PR', value: (r) => r.pullRequestUrl ?? '' },\n ]),\n )\n print('')\n print(`Page ${page.page} of ${Math.max(1, page.totalPages)} · ${page.totalCount} runs`)\n },\n )\n\n run\n .command('view')\n .description('Show a run')\n .argument('<runId>', 'Run id')\n .action(async (runId: string) => {\n const ctx = createContext(globals())\n const found = await getRun(ctx, await ctx.org(), runId)\n if (ctx.json) return printJson(found)\n\n const cost =\n found.costUsd === null && found.inputTokens === null && found.outputTokens === null\n ? undefined\n : [\n found.costUsd === null ? undefined : `$${found.costUsd.toFixed(4)}`,\n found.inputTokens === null && found.outputTokens === null\n ? undefined\n : `${formatNumber(found.inputTokens) || '0'} in / ${formatNumber(found.outputTokens) || '0'} out tokens`,\n ]\n .filter((part) => part !== undefined)\n .join(' · ')\n\n print(\n renderFields([\n ['Run', found.id],\n ['Item', found.itemKey],\n ['Status', found.status],\n ['Agent', found.agentName ?? found.agentId],\n ['Playbook', found.playbookName ?? found.playbookId],\n ['Runner', found.runnerName ?? found.runnerId ?? undefined],\n ['Harness', found.harness],\n [\n 'Requested by',\n found.requestedBy ?? (found.ruleId ? `rule: ${found.ruleName ?? '(deleted)'}` : undefined),\n ],\n ['Max minutes', String(found.maxMinutes)],\n ['Queued', formatDateTime(found.queuedAt)],\n ['Assigned', formatDateTime(found.assignedAt)],\n ['Started', formatDateTime(found.startedAt)],\n ['Finished', formatDateTime(found.finishedAt)],\n ['Last heartbeat', formatDateTime(found.lastHeartbeatAt)],\n ['Cancel requested', found.cancelRequested ? 'yes' : undefined],\n ['Outcome', found.outcomeSummary ?? undefined],\n ['PR', found.pullRequestUrl ?? undefined],\n ['Exit code', found.exitCode === null ? undefined : String(found.exitCode)],\n ['Cost', cost],\n ['Failure', found.failureReason ?? undefined],\n ]),\n )\n })\n\n run\n .command('logs')\n .description(\"Print a run's log; --follow keeps polling until the run finishes\")\n .argument('<runId>', 'Run id')\n .option('-f, --follow', 'Poll for new output every 2 s until the run is finished')\n .action(async (runId: string, options: { follow?: boolean }) => {\n const ctx = createContext(globals())\n await streamLog(ctx, await ctx.org(), runId, options.follow === true, pollIntervalMs())\n })\n\n run\n .command('cancel')\n .description('Ask a run to stop; the runner ends the harness and the run records cancelled')\n .argument('<runId>', 'Run id')\n .action(async (runId: string) => {\n const ctx = createContext(globals())\n await ctx.client.request<undefined, '/api/v1/orgs/{orgSlug}/runs/{runId}/cancel', 'post'>(\n 'post',\n '/api/v1/orgs/{orgSlug}/runs/{runId}/cancel',\n { path: { orgSlug: await ctx.org(), runId } },\n )\n if (ctx.json) return printJson({ id: runId, cancelRequested: true })\n print(`Cancel requested for run ${runId}.`)\n })\n\n return run\n}\n\nasync function getRun(ctx: Context, orgSlug: string, runId: string): Promise<RunView> {\n return ctx.client.request<RunView, '/api/v1/orgs/{orgSlug}/runs/{runId}', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/runs/{runId}',\n { path: { orgSlug, runId } },\n )\n}\n\n/**\n * Prints the log from the start and, when following, keeps going until the run is in a\n * terminal state and one last page after that has been drained - the status is read\n * *before* each page, so output written between the last page and the finish is never\n * missed. A full page is followed by another request straight away; a short one waits.\n */\nasync function streamLog(\n ctx: Context,\n orgSlug: string,\n runId: string,\n follow: boolean,\n pollMs: number,\n): Promise<void> {\n let after = -1\n let notedTruncation = false\n for (;;) {\n const finished = follow ? terminal.has((await getRun(ctx, orgSlug, runId)).status) : true\n for (;;) {\n const page = await ctx.client.request<\n RunLogPage,\n '/api/v1/orgs/{orgSlug}/runs/{runId}/log',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/runs/{runId}/log', {\n path: { orgSlug, runId },\n query: { after, pageSize: logPageSize },\n })\n for (const entry of page.items) {\n after = Math.max(after, entry.seq)\n if (entry.seq !== truncatedSeq) print(formatLogEntry(entry))\n }\n if (page.truncated && !notedTruncation) {\n notedTruncation = true\n print('(log truncated)')\n }\n if (page.items.length < logPageSize) break\n }\n if (finished) return\n await new Promise<void>((resolve) => setTimeout(resolve, pollMs))\n }\n}\n\nexport function formatLogEntry(entry: RunLogEntry): string {\n const text = entry.text.endsWith('\\n') ? entry.text.slice(0, -1) : entry.text\n if (entry.stream === 'stdout') return text\n const prefix = entry.stream === 'stderr' ? '[stderr] ' : '[event] '\n return text\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n')\n}\n\nconst uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\n/** An id passes through; a name is matched case-insensitively against the project's playbooks. */\nasync function resolvePlaybookId(\n ctx: Context,\n projectKey: string,\n playbook: string,\n): Promise<string> {\n if (uuid.test(playbook)) return playbook\n const playbooks = await ctx.client.request<\n PlaybookView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/playbooks',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/playbooks', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n const wanted = playbook.trim().toLowerCase()\n const matches = playbooks.filter((p) => p.name.toLowerCase() === wanted)\n if (matches.length === 1) return matches[0]!.id\n if (matches.length === 0) {\n throw new CliError(\n `No playbook \"${playbook}\" in ${projectKey}. Playbooks: ${playbooks.map((p) => p.name).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n throw new CliError(\n `Several playbooks in ${projectKey} are named \"${playbook}\"; pass one by id: ${matches.map((p) => p.id).join(', ')}.`,\n ExitCode.Validation,\n )\n}\n\n/** An id passes through; a display name is matched case-insensitively against the organization's agents. */\nasync function resolveAgentId(ctx: Context, agent: string): Promise<string> {\n if (uuid.test(agent)) return agent\n const agents = await ctx.client.request<AgentView[], '/api/v1/orgs/{orgSlug}/agents', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/agents',\n { path: { orgSlug: await ctx.org() } },\n )\n const byId = agents.find((a) => a.userId === agent)\n if (byId) return byId.userId\n const wanted = agent.trim().toLowerCase()\n const matches = agents.filter((a) => a.displayName.toLowerCase() === wanted)\n if (matches.length === 1) return matches[0]!.userId\n if (matches.length === 0) {\n throw new CliError(\n `No agent \"${agent}\" in this organization. Agents: ${agents.map((a) => a.displayName).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n throw new CliError(\n `Several agents are named \"${agent}\"; pass one by id: ${matches.map((a) => a.userId).join(', ')}.`,\n ExitCode.Validation,\n )\n}\n","import { Command } from 'commander'\nimport { existsSync } from 'node:fs'\nimport { arch, platform } from 'node:os'\nimport { resolve } from 'node:path'\nimport type { GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { print, printJson, renderFields, renderTable } from '../output.js'\nimport { promptSecret } from '../prompt.js'\nimport { version } from '../version.js'\nimport { RunnerClient, RunnerHttpError } from '../runner/client.js'\nimport { readRunnerConfig, runnerConfigPath, writeRunnerConfig } from '../runner/config.js'\nimport type { RunnerConfig } from '../runner/config.js'\nimport { executeRun } from '../runner/execute.js'\nimport { harnesses, probeHarnesses } from '../runner/harness/index.js'\nimport { RunnerLoop, RunnerRevokedError } from '../runner/loop.js'\nimport type { RunnerCapabilities } from '../runner/types.js'\nimport { DefaultAttachmentMaxBytes, DefaultAttachmentMaxCount, defaultWorkspaceRoot } from '../runner/workspace.js'\n\n/**\n * `aictiq runner` - the worker on the factory floor. It authenticates with a\n * `jrn_` runner secret kept in its own `runner.json`, never with the person's PAT.\n */\nexport function runnerCommand(globals: () => GlobalOptions): Command {\n const runner = new Command('runner').description(\n 'Run agent work dispatched from a Aictiq instance on this machine',\n )\n\n runner\n .command('register')\n .description('Store a runner secret (jrn_…) from Factory → Runners and check it')\n // Not requiredOption: the root command defines --url and --token too, and commander hands\n // them to the root, so they are read from both places exactly as `auth login` does.\n .option('--url <url>', 'Base URL of the Aictiq instance')\n .option('--token <token>', 'Runner secret; read from stdin when omitted')\n .option('--name <name>', 'A local label for this runner (the instance keeps its own name)')\n .action(async (options: { url?: string; token?: string; name?: string }) => {\n const global = globals()\n const rawUrl = options.url ?? global.url\n if (!rawUrl) {\n throw new CliError(\n 'Pass --url with the address of your Aictiq instance.',\n ExitCode.Validation,\n )\n }\n const token =\n options.token ??\n global.token ??\n process.env.AICTIQ_RUNNER_TOKEN ??\n (await promptSecret('Runner secret: '))\n if (!token?.startsWith('jrn_')) {\n throw new CliError(\n 'A runner secret starts with jrn_. Create one under Factory → Runners.',\n ExitCode.Validation,\n )\n }\n const url = rawUrl.replace(/\\/+$/, '')\n\n // Verify before writing, as `auth login` does: a stored secret that never worked\n // turns into a service that restarts forever somewhere nobody is looking.\n const capabilities = await probe(1)\n const hello = await new RunnerClient({ baseUrl: url, token })\n .hello(capabilities)\n .catch((error: unknown) => {\n throw asCliError(error)\n })\n\n const existing = readRunnerConfig()\n const config: RunnerConfig = {\n url,\n token,\n ...(options.name ? { name: options.name } : existing?.name ? { name: existing.name } : {}),\n // Re-registering (a rotated secret) keeps the repository map someone built up.\n workspaces: existing?.workspaces ?? {},\n repoRoots: existing?.repoRoots ?? [],\n attachments: existing?.attachments ?? { maxCount: DefaultAttachmentMaxCount, maxBytes: DefaultAttachmentMaxBytes },\n }\n writeRunnerConfig(config)\n\n if (globals().json) {\n printJson({ url, runner: hello, capabilities, configPath: runnerConfigPath() })\n return\n }\n print(\n `Registered runner \"${hello.name}\" with ${url} (${hello.organizationSlug}).\\n` +\n `Harnesses: ${capabilities.harnesses.map((h) => h.name).join(', ') || 'none found on PATH'}\\n` +\n `Config written to ${runnerConfigPath()}. Start it with \\`aictiq runner start\\`.`,\n )\n })\n\n runner\n .command('map')\n .description(\n 'Map a project key to a local clone, for projects whose repository source is local',\n )\n .argument('<projectKey>', 'Project key, e.g. ACME')\n .argument('[path]', 'Path of the clone (default: the current directory); omit with --remove')\n .option('--remove', 'Remove the mapping')\n .action((projectKey: string, path: string | undefined, options: { remove?: boolean }) => {\n const config = requireConfig()\n const key = projectKey.toUpperCase()\n if (options.remove) {\n delete config.workspaces[key]\n } else {\n const absolute = resolve(path ?? '.')\n if (!existsSync(absolute))\n throw new CliError(`${absolute} does not exist.`, ExitCode.Validation)\n config.workspaces[key] = absolute\n }\n writeRunnerConfig(config)\n print(\n options.remove ? `Removed the mapping for ${key}.` : `${key} → ${config.workspaces[key]}`,\n )\n })\n\n runner\n .command('root')\n .description(\n \"Trust the web UI's path hint for local projects whose clone is under this directory\",\n )\n .argument('[path]', 'Directory that holds your clones (default: the current directory)')\n .option('--remove', 'Stop trusting path hints under this directory')\n .action((path: string | undefined, options: { remove?: boolean }) => {\n const config = requireConfig()\n const absolute = resolve(path ?? '.')\n if (options.remove) {\n config.repoRoots = config.repoRoots.filter((root) => resolve(root) !== absolute)\n } else {\n if (!existsSync(absolute))\n throw new CliError(`${absolute} does not exist.`, ExitCode.Validation)\n if (!config.repoRoots.some((root) => resolve(root) === absolute))\n config.repoRoots.push(absolute)\n }\n writeRunnerConfig(config)\n print(\n options.remove\n ? `Path hints under ${absolute} are no longer used.`\n : `Path hints under ${absolute} are used for projects without a mapping.`,\n )\n })\n\n runner\n .command('status')\n .description('Show the registration, detected harnesses and mapped repositories')\n .action(async () => {\n const config = requireConfig()\n const capabilities = await probe(1)\n let registration: unknown\n let registrationText: string\n try {\n const hello = await new RunnerClient({ baseUrl: config.url, token: config.token }).hello(\n capabilities,\n )\n registration = hello\n registrationText = `ok - \"${hello.name}\" in ${hello.organizationSlug}`\n } catch (error) {\n registration = { error: error instanceof Error ? error.message : String(error) }\n registrationText = `failing - ${error instanceof Error ? error.message : String(error)}`\n // A health check scripted around `status` must be able to tell a dead secret apart.\n if (error instanceof RunnerHttpError && error.revoked) process.exitCode = ExitCode.Auth\n }\n\n if (globals().json) {\n printJson({ url: config.url, registration, capabilities, workspaces: config.workspaces, repoRoots: config.repoRoots, attachments: config.attachments })\n return\n }\n print(\n renderFields([\n ['Instance', config.url],\n ['Registration', registrationText],\n ['Config', runnerConfigPath()],\n ['Workspaces', defaultWorkspaceRoot()],\n ['Attachments', `${config.attachments.maxCount} files / ${formatBytes(config.attachments.maxBytes)} per run`],\n ['CLI', `${version} (${capabilities.os}/${capabilities.arch})`],\n ]),\n )\n print('')\n print(\n capabilities.harnesses.length === 0\n ? 'No harness found on PATH (claude, codex, opencode).'\n : renderTable(capabilities.harnesses, [\n { header: 'HARNESS', value: (h) => h.name },\n { header: 'VERSION', value: (h) => h.version ?? '' },\n ]),\n )\n print('')\n const mapped = Object.entries(config.workspaces)\n print(\n mapped.length === 0\n ? 'No local repositories mapped (`aictiq runner map <KEY> <path>`).'\n : renderTable(mapped, [\n { header: 'PROJECT', value: ([key]) => key },\n { header: 'REPOSITORY', value: ([, path]) => path },\n ]),\n )\n print('')\n print(\n config.repoRoots.length === 0\n ? 'No repository roots; path hints from the web UI are not used (`aictiq runner root <path>`).'\n : renderTable(config.repoRoots, [{ header: 'REPOSITORY ROOT', value: (root) => root }]),\n )\n })\n\n runner\n .command('start')\n .description('Poll for runs and execute them until interrupted')\n .option('--parallel <n>', 'Runs executed at the same time', '1')\n .option('--keep-workspaces', 'Leave each run’s checkout on disk after it finishes')\n .option('--workspace-root <path>', 'Where run checkouts are created')\n .action(\n async (options: { parallel: string; keepWorkspaces?: boolean; workspaceRoot?: string }) => {\n const config = requireConfig()\n const parallel = Number.parseInt(options.parallel, 10)\n if (!Number.isInteger(parallel) || parallel < 1 || parallel > 16) {\n throw new CliError('--parallel is between 1 and 16.', ExitCode.Validation)\n }\n\n const client = new RunnerClient({ baseUrl: config.url, token: config.token })\n const local = (message: string) =>\n process.stderr.write(`${new Date().toISOString()} ${message}\\n`)\n const workspaceRoot = resolve(options.workspaceRoot ?? defaultWorkspaceRoot())\n const loop = new RunnerLoop({\n client,\n parallel,\n probe: () => probe(parallel),\n local,\n execute: (run, hello, shutdown) => {\n // Re-read per run, so a new mapping or root applies without restarting the\n // runner. The secret stays the one this process started with.\n const current = readRunnerConfig() ?? config\n return executeRun(run, {\n client,\n hello,\n adapters: harnesses,\n runnerToken: config.token,\n shutdown,\n local,\n workspace: {\n root: workspaceRoot,\n repositories: current.workspaces,\n repoRoots: current.repoRoots,\n keep: options.keepWorkspaces === true,\n mcpServer: mcpServerCommand(),\n attachmentMaxCount: current.attachments.maxCount,\n attachmentMaxBytes: current.attachments.maxBytes,\n },\n })\n },\n })\n\n let interrupts = 0\n const onSignal = (signal: NodeJS.Signals) => {\n interrupts++\n if (interrupts === 1 && loop.inFlight > 0) {\n local(\n `${signal}: finishing ${loop.inFlight} run(s) in flight; send it again to cancel them`,\n )\n loop.stop()\n } else if (interrupts === 1) {\n loop.stop()\n } else {\n local(`${signal}: cancelling runs in flight`)\n loop.abort()\n }\n }\n process.on('SIGINT', onSignal)\n process.on('SIGTERM', onSignal)\n try {\n await loop.run()\n } catch (error) {\n throw asCliError(error)\n } finally {\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n }\n },\n )\n\n runner\n .command('install-service')\n .description('Print a systemd user unit that keeps `aictiq runner start` running')\n .option('--parallel <n>', 'Runs executed at the same time', '1')\n .action((options: { parallel: string }) => {\n print(systemdUnit(process.execPath, cliEntry(), options.parallel))\n })\n\n return runner\n}\n\nexport function systemdUnit(node: string, entry: string, parallel: string): string {\n return `# Save as ~/.config/systemd/user/aictiq-runner.service, then:\n# systemctl --user daemon-reload\n# systemctl --user enable --now aictiq-runner\n# loginctl enable-linger \"$USER\" # keep it running after you log out\n#\n# The runner executes agents as this user, with this user's harness sign-ins and git\n# credentials: one runner is one trust domain. SIGTERM lets runs in flight finish;\n# TimeoutStopSec bounds how long systemd waits before it cancels them.\n[Unit]\nDescription=Aictiq runner\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nExecStart=${node} ${entry} runner start --parallel ${parallel}\nRestart=on-failure\nRestartSec=10\n# Exit 5 means the secret was revoked; restarting cannot fix that.\nRestartPreventExitStatus=5\nKillMode=mixed\nTimeoutStopSec=15min\nEnvironment=PATH=${process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin'}\n\n[Install]\nWantedBy=default.target\n`\n}\n\nasync function probe(maxParallel: number): Promise<RunnerCapabilities> {\n return {\n v: 1,\n harnesses: await probeHarnesses(),\n os: platform(),\n arch: arch(),\n cliVersion: version,\n maxParallel,\n }\n}\n\n/** The CLI that is running now, so the agent's MCP bridge is this exact version. */\nfunction cliEntry(): string {\n return resolve(process.argv[1] ?? 'aictiq')\n}\n\nfunction mcpServerCommand(): { command: string; args: string[] } {\n return { command: process.execPath, args: [cliEntry(), 'mcp'] }\n}\n\nfunction formatBytes(value: number): string {\n return value >= 1024 * 1024 ? `${(value / (1024 * 1024)).toFixed(1)} MiB` : `${value} bytes`\n}\n\nfunction requireConfig(): RunnerConfig {\n const config = readRunnerConfig()\n if (!config) {\n throw new CliError(\n `This machine is not registered as a runner (${runnerConfigPath()}). Run \\`aictiq runner register --url <url> --token <jrn_…>\\`.`,\n ExitCode.Auth,\n )\n }\n return config\n}\n\nfunction asCliError(error: unknown): unknown {\n if (error instanceof RunnerRevokedError) return new CliError(error.message, ExitCode.Auth)\n if (error instanceof RunnerHttpError) {\n return new CliError(\n error.status === 401\n ? `The instance refused the runner secret: ${error.message}`\n : error.message,\n error.status === 401 ? ExitCode.Auth : ExitCode.Error,\n )\n }\n return error\n}\n","import type { ProblemDetails } from '../errors.js'\nimport type {\n ClaimedRun,\n FinishReport,\n LogStream,\n RunAttachment,\n RunnerCapabilities,\n RunnerHello,\n} from './types.js'\n\nexport interface LogChunk {\n seq: number\n stream: LogStream\n text: string\n at: string\n}\n\n/** A refused request: the status and problem type are what the runner decides on. */\nexport class RunnerHttpError extends Error {\n readonly status: number\n readonly problem: ProblemDetails | undefined\n\n constructor(status: number, problem: ProblemDetails | undefined, message: string) {\n super(message)\n this.name = 'RunnerHttpError'\n this.status = status\n this.problem = problem\n }\n\n /** A disabled, deleted or rotated runner: retrying cannot help, so the process must stop. */\n get revoked(): boolean {\n return this.status === 401\n }\n}\n\n/** The instance could not be reached at all - the only failure worth a backoff and retry. */\nexport class RunnerNetworkError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'RunnerNetworkError'\n }\n}\n\nexport interface RunnerClientOptions {\n baseUrl: string\n token: string\n fetch?: typeof fetch\n}\n\n/**\n * The runner protocol (`/api/v1/runner/*`). Not the generated\n * `AictiqClient`: these routes take a `jrn_` secret that no person's command should ever\n * hold, and the item heartbeat below is the one call made with the run's agent token.\n */\nexport class RunnerClient {\n readonly baseUrl: string\n private readonly token: string\n private readonly doFetch: typeof fetch\n\n constructor(options: RunnerClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.token = options.token\n this.doFetch = options.fetch ?? fetch\n }\n\n hello(capabilities: RunnerCapabilities): Promise<RunnerHello> {\n return this.send<RunnerHello>('/runner/hello', { capabilities })\n }\n\n async heartbeat(capabilities: RunnerCapabilities): Promise<void> {\n await this.send('/runner/heartbeat', { capabilities })\n }\n\n /** Long-polls; null when the server had nothing within its poll timeout. */\n async claim(\n harnesses: string[],\n slots: number,\n signal?: AbortSignal,\n ): Promise<ClaimedRun | null> {\n return (await this.send<ClaimedRun>('/runner/runs/claim', { harnesses, slots }, signal)) ?? null\n }\n\n async started(runId: string): Promise<void> {\n await this.send(`/runner/runs/${runId}/started`)\n }\n\n async log(runId: string, chunks: LogChunk[]): Promise<void> {\n await this.send(`/runner/runs/${runId}/log`, { chunks })\n }\n\n async runHeartbeat(runId: string): Promise<{ cancelRequested: boolean }> {\n return this.send<{ cancelRequested: boolean }>(`/runner/runs/${runId}/heartbeat`)\n }\n\n async finish(runId: string, report: FinishReport): Promise<void> {\n await this.send(`/runner/runs/${runId}/finish`, report)\n }\n\n async repoToken(runId: string): Promise<string | null> {\n const response = await this.send<{ token: string | null }>(`/runner/runs/${runId}/repo-token`)\n return response?.token ?? null\n }\n\n /** Lists committed attachments on an item, including attachments posted in its comments. */\n listAttachments(run: ClaimedRun): Promise<RunAttachment[]> {\n return this.get<RunAttachment[]>(\n `/orgs/${encodeURIComponent(run.organizationSlug)}/items/${encodeURIComponent(run.itemKey)}/attachments?include=comments`,\n run.agentToken,\n )\n }\n\n /** Downloads attachment bytes using the short-lived agent credential, never the runner secret. */\n async downloadAttachment(run: ClaimedRun, attachmentId: string): Promise<Uint8Array> {\n const path = `/orgs/${encodeURIComponent(run.organizationSlug)}/attachments/${encodeURIComponent(attachmentId)}/download`\n const response = await this.request(path, 'GET', undefined, undefined, run.agentToken)\n if (!response.ok) throw await this.error(path, response)\n return new Uint8Array(await response.arrayBuffer())\n }\n\n /**\n * Keeps the item's claim fresh with the agent's own token. Without it the claim goes\n * stale after `Claims:StaleAfterMinutes` and another agent may take the item mid-run.\n */\n async itemHeartbeat(run: ClaimedRun): Promise<void> {\n await this.send(\n `/orgs/${encodeURIComponent(run.organizationSlug)}/items/${encodeURIComponent(run.itemKey)}/heartbeat`,\n undefined,\n undefined,\n run.agentToken,\n )\n }\n\n private async send<T>(\n path: string,\n body?: unknown,\n signal?: AbortSignal,\n token = this.token,\n ): Promise<T> {\n const response = await this.request(path, 'POST', body, signal, token)\n\n if (response.status === 204) return undefined as T\n if (!response.ok) throw await this.error(path, response)\n const text = await response.text()\n let payload: unknown\n try {\n payload = text.length === 0 ? undefined : JSON.parse(text)\n } catch {\n payload = undefined\n }\n return payload as T\n }\n\n private async get<T>(path: string, token: string): Promise<T> {\n const response = await this.request(path, 'GET', undefined, undefined, token)\n if (!response.ok) throw await this.error(path, response)\n return (await response.json()) as T\n }\n\n private async request(path: string, method: 'GET' | 'POST', body?: unknown, signal?: AbortSignal, token = this.token): Promise<Response> {\n try {\n return await this.doFetch(`${this.baseUrl}/api/v1${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n 'User-Agent': 'aictiq-runner',\n ...(body === undefined ? {} : { 'Content-Type': 'application/json' }),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n ...(signal ? { signal } : {}),\n })\n } catch (cause) {\n if (signal?.aborted) throw cause\n throw new RunnerNetworkError(`Cannot reach ${this.baseUrl}: ${cause instanceof Error ? cause.message : String(cause)}`)\n }\n }\n\n private async error(path: string, response: Response): Promise<RunnerHttpError | RunnerNetworkError> {\n // A gateway in front of the instance answering 502 is the network, not a verdict.\n if (response.status >= 502 && response.status <= 504) return new RunnerNetworkError(`${this.baseUrl} answered ${response.status}`)\n const text = await response.text()\n let payload: unknown\n try { payload = text.length === 0 ? undefined : JSON.parse(text) } catch { payload = undefined }\n const problem = typeof payload === 'object' && payload !== null ? (payload as ProblemDetails) : undefined\n return new RunnerHttpError(response.status, problem, `${path}: ${response.status} ${problem?.title ?? response.statusText}${problem?.detail ? ` - ${problem.detail}` : ''}`)\n }\n}\n","import { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { DefaultAttachmentMaxBytes, DefaultAttachmentMaxCount } from './workspace.js'\n\nexport interface RunnerAttachmentConfig {\n maxCount: number\n maxBytes: number\n}\n\n/**\n * What `aictiq runner register` writes. Deliberately a separate file from `config.json`:\n * a runner's credential is not a person's, and a machine that is both somebody's laptop\n * and a runner must not have one overwrite the other.\n */\nexport interface RunnerConfig {\n url: string\n token: string\n name?: string\n /** Project key → path of a local clone, for projects whose repository source is `local`. */\n workspaces: Record<string, string>\n /**\n * Directories under which a project's path hint (set in the web UI) is used when the\n * project has no `workspaces` entry. Absolute, or starting with `~/`.\n */\n repoRoots: string[]\n attachments: RunnerAttachmentConfig\n}\n\nexport function runnerConfigPath(env: NodeJS.ProcessEnv = process.env): string {\n const base = env.AICTIQ_CONFIG_HOME ?? env.XDG_CONFIG_HOME ?? join(homedir(), '.config')\n return join(base, 'aictiq', 'runner.json')\n}\n\nexport function readRunnerConfig(path = runnerConfigPath()): RunnerConfig | null {\n if (!existsSync(path)) return null\n let parsed: unknown\n try {\n parsed = JSON.parse(readFileSync(path, 'utf8'))\n } catch {\n return null\n }\n if (typeof parsed !== 'object' || parsed === null) return null\n const { url, token, name, workspaces, repoRoots, attachments } = parsed as Record<string, unknown>\n if (typeof url !== 'string' || typeof token !== 'string') return null\n\n const mapped: Record<string, string> = {}\n if (typeof workspaces === 'object' && workspaces !== null) {\n for (const [key, value] of Object.entries(workspaces)) {\n if (typeof value === 'string') mapped[key] = value\n }\n }\n const roots = Array.isArray(repoRoots)\n ? repoRoots.filter((root): root is string => typeof root === 'string' && root.trim() !== '')\n : []\n const rawLimits = typeof attachments === 'object' && attachments !== null ? attachments as Record<string, unknown> : {}\n return {\n url,\n token,\n ...(typeof name === 'string' ? { name } : {}),\n workspaces: mapped,\n repoRoots: roots,\n attachments: {\n maxCount: validLimit(rawLimits.maxCount, DefaultAttachmentMaxCount),\n maxBytes: validLimit(rawLimits.maxBytes, DefaultAttachmentMaxBytes),\n },\n }\n}\n\nexport function writeRunnerConfig(config: RunnerConfig, path = runnerConfigPath()): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 })\n // The mode argument only applies on creation; narrow a file someone widened.\n chmodSync(path, 0o600)\n}\n\nfunction validLimit(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : fallback\n}\n","import { spawn } from 'node:child_process'\nimport { chmodSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, relative, resolve } from 'node:path'\nimport { RunFailure, type ClaimedRun, type RunAttachment } from './types.js'\n\nexport const DefaultAttachmentMaxCount = 25\nexport const DefaultAttachmentMaxBytes = 25 * 1024 * 1024\n\n/** The runner's small agent-token-only view of item attachments. */\nexport interface AttachmentProvider {\n list(): Promise<RunAttachment[]>\n download(attachmentId: string): Promise<Uint8Array>\n}\n\n/**\n * Where a run's work happens. Everything the runner writes for a run lives in\n * `<root>/<runId>/`; the harness works in `repo/` below it. The prompt, the MCP config and\n * the askpass script sit beside the checkout rather than in it, so nothing the agent\n * commits can carry them.\n */\nexport interface WorkspaceOptions {\n root: string\n /** project key → local repository path, from runner.json `workspaces` */\n repositories: Record<string, string>\n /**\n * Directories, from runner.json `repoRoots`, under which the project's path hint is trusted\n * when the project has no explicit mapping. Empty means the hint is never used.\n */\n repoRoots?: string[]\n keep: boolean\n mcpServer: { command: string; args: string[] }\n /** runner milestones, streamed as `event` log chunks */\n event: (line: string) => void\n /** fetches a fresh GitHub installation token when the claimed one is missing/expired (POST /runner/runs/{id}/repo-token) */\n refreshCloneToken?: () => Promise<string | null>\n /** Where `github` repositories are cloned from; tests point it at a local bare repository. */\n githubBaseUrl?: string\n env?: NodeJS.ProcessEnv\n signal?: AbortSignal\n /** Optional because old instances do not yet expose the attachment list endpoint. */\n attachments?: AttachmentProvider\n /** Limits for files outside the checkout. Zero disables provisioning. */\n attachmentMaxCount?: number\n attachmentMaxBytes?: number\n}\n\nexport interface Workspace {\n runDir: string\n checkout: string\n branch: string\n promptFile: string\n mcpConfigFile: string\n attachmentsDir: string\n /** The source prompt plus the runner-generated attachment inventory. */\n prompt: string\n /** Extra environment for the harness process (the push credential for a `github` clone). */\n env: Record<string, string>\n /** removes the worktree (git worktree remove --force + prune in the source repo) or clone, then the run dir; no-op when keep; never throws */\n cleanup(): Promise<void>\n}\n\nexport function defaultWorkspaceRoot(env: NodeJS.ProcessEnv = process.env): string {\n const base = env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share')\n return join(base, 'aictiq', 'runner')\n}\n\nconst TOKEN_ENV = 'AICTIQ_GIT_TOKEN'\n\n// Answers only `get`: git also calls helpers with `store` after a successful push, and the\n// token must not end up anywhere but this process's environment.\nconst CREDENTIAL_HELPER = `!f() { test \"$1\" = get || return 0; echo username=x-access-token; echo \"password=$${TOKEN_ENV}\"; }; f`\n\nconst ASKPASS_SCRIPT = `#!/bin/sh\ncase \"$1\" in\n *[Uu]sername*) echo x-access-token ;;\n *) echo \"$${TOKEN_ENV}\" ;;\nesac\n`\n\nexport async function provisionWorkspace(\n run: ClaimedRun,\n options: WorkspaceOptions,\n): Promise<Workspace> {\n // The run id becomes a directory name; anything path-like in it is refused outright.\n if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(run.runId)) {\n throw new RunFailure(\n 'workspace-failed',\n `Refusing to create a workspace for run id \"${run.runId}\".`,\n )\n }\n\n const runDir = join(options.root, run.runId)\n const checkout = join(runDir, 'repo')\n const promptFile = join(runDir, 'prompt.md')\n const mcpConfigFile = join(runDir, 'mcp.json')\n const attachmentsDir = join(runDir, 'attachments')\n const env = options.env ?? process.env\n\n let source: string | null = null\n const cleanup = async (): Promise<void> => {\n if (options.keep) return\n if (source !== null) {\n await git(['worktree', 'remove', '--force', checkout], { cwd: source, env }).catch(\n () => undefined,\n )\n await git(['worktree', 'prune'], { cwd: source, env }).catch(() => undefined)\n }\n try {\n rmSync(runDir, { recursive: true, force: true })\n } catch {\n // Cleanup is best effort; a leftover directory is not a failed run.\n }\n }\n\n mkdirSync(options.root, { recursive: true, mode: 0o700 })\n // A leftover directory from an earlier attempt would make `worktree add` or `clone` refuse.\n rmSync(runDir, { recursive: true, force: true })\n mkdirSync(runDir, { mode: 0o700 })\n chmodSync(runDir, 0o700)\n\n try {\n const mcpConfig = {\n mcpServers: { aictiq: { command: options.mcpServer.command, args: options.mcpServer.args } },\n }\n writePrivate(mcpConfigFile, `${JSON.stringify(mcpConfig, null, 2)}\\n`)\n\n await assertRefName(run.branchName, 'branch', env)\n await assertRefName(run.defaultBranch, 'default branch', env)\n\n let harnessEnv: Record<string, string> = {}\n if (run.repo.source === 'local') {\n source = await provisionLocal(run, checkout, options, env)\n } else {\n harnessEnv = await provisionGithub(run, runDir, checkout, options, env)\n }\n\n const prompt = await provisionAttachments(run, attachmentsDir, options)\n writePrivate(promptFile, prompt)\n\n return {\n runDir,\n checkout,\n branch: run.branchName,\n promptFile,\n mcpConfigFile,\n attachmentsDir,\n prompt,\n env: harnessEnv,\n cleanup,\n }\n } catch (error) {\n await cleanup()\n throw error\n }\n}\n\nasync function provisionAttachments(run: ClaimedRun, attachmentsDir: string, options: WorkspaceOptions): Promise<string> {\n if (!options.attachments) return run.prompt\n const maxCount = limit(options.attachmentMaxCount, DefaultAttachmentMaxCount)\n const maxBytes = limit(options.attachmentMaxBytes, DefaultAttachmentMaxBytes)\n if (maxCount === 0 || maxBytes === 0) {\n options.event('Attachment provisioning is disabled by this runner configuration')\n return `${run.prompt}\\n\\n## Attachments\\n\\nAttachment provisioning is disabled on this runner. Use the attachment download URL from Aictiq if needed.\\n`\n }\n\n let attachments: RunAttachment[]\n try {\n attachments = await options.attachments.list()\n } catch (error) {\n // A missing list endpoint or a transient instance error must not prevent a code run.\n options.event(`Could not list item attachments: ${message(error)}`)\n return run.prompt\n }\n if (attachments.length === 0) return run.prompt\n\n mkdirSync(attachmentsDir, { recursive: true, mode: 0o700 })\n chmodSync(attachmentsDir, 0o700)\n let total = 0\n const names = new Set<string>()\n const provisioned: Array<RunAttachment & { localName: string }> = []\n\n for (const attachment of attachments) {\n if (provisioned.length >= maxCount) {\n options.event(`Skipped attachment \"${attachment.fileName}\" (limit: ${maxCount} files)`)\n continue\n }\n if (!Number.isSafeInteger(attachment.sizeBytes) || attachment.sizeBytes < 0 || total + attachment.sizeBytes > maxBytes) {\n options.event(`Skipped attachment \"${attachment.fileName}\" (would exceed ${formatBytes(maxBytes)} total)`)\n continue\n }\n try {\n const bytes = await options.attachments.download(attachment.id)\n if (bytes.byteLength > attachment.sizeBytes || total + bytes.byteLength > maxBytes) {\n options.event(`Skipped attachment \"${attachment.fileName}\" (download exceeds ${formatBytes(maxBytes)} total)`)\n continue\n }\n const name = uniqueFileName(sanitiseFileName(attachment.fileName, attachment.id), names)\n writePrivate(join(attachmentsDir, name), bytes)\n total += bytes.byteLength\n provisioned.push({ ...attachment, localName: name })\n } catch (error) {\n // One unavailable blob is useful information, but never a reason to fail the run.\n options.event(`Failed to download attachment \"${attachment.fileName}\": ${message(error)}`)\n }\n }\n\n if (provisioned.length === 0) return run.prompt\n options.event(`Provisioned ${provisioned.length} attachment${provisioned.length === 1 ? '' : 's'}: ${provisioned.map(x => x.localName).join(', ')}`)\n const inventory = provisioned.map((attachment) => {\n const source = attachment.commentId ? `comment ${attachment.commentId}` : 'item description'\n const url = `/api/v1/orgs/${encodeURIComponent(run.organizationSlug)}/attachments/${encodeURIComponent(attachment.id)}/download`\n return `- ${join(attachmentsDir, attachment.localName)} - original: ${attachment.fileName}; ${attachment.contentType}; ${formatBytes(attachment.sizeBytes)}; from ${source}; replaces ${url}`\n }).join('\\n')\n const images = provisioned.filter(attachment => attachment.contentType.startsWith('image/'))\n return `${run.prompt}\\n\\n## Attachments\\n\\nThese files are outside the git checkout at \\`${attachmentsDir}\\`; do not add or commit them. ${images.length > 0 ? 'Look at these images before planning.' : ''}\\n\\n${inventory}\\n`\n}\n\nfunction limit(value: number | undefined, fallback: number): number {\n return Number.isSafeInteger(value) && value !== undefined && value >= 0 ? value : fallback\n}\n\nfunction sanitiseFileName(value: string, id: string): string {\n const clean = value.replace(/[\\\\/\\p{Cc}]/gu, '_').trim().replace(/^\\.+$/, '')\n return (clean || `attachment-${id}`).slice(0, 200)\n}\n\nfunction uniqueFileName(value: string, existing: Set<string>): string {\n const extension = value.lastIndexOf('.') > 0 ? value.slice(value.lastIndexOf('.')) : ''\n const stem = extension ? value.slice(0, -extension.length) : value\n let candidate = value\n let sequence = 2\n while (existing.has(candidate.toLocaleLowerCase())) candidate = `${stem}-${sequence++}${extension}`\n existing.add(candidate.toLocaleLowerCase())\n return candidate\n}\n\nfunction formatBytes(value: number): string {\n return value >= 1024 * 1024 ? `${(value / (1024 * 1024)).toFixed(1)} MiB` : `${value} bytes`\n}\n\n/**\n * The clone a runner-local run works from: the explicit `workspaces` mapping, else the\n * project's path hint when it lies inside one of the runner's `repoRoots`. The hint comes\n * from the server, so it is only trusted inside directories this machine's operator named;\n * symlinks and `..` are resolved before that check. `root` is null for an explicit mapping.\n */\nfunction resolveLocalRepository(\n run: ClaimedRun,\n options: WorkspaceOptions,\n): { path: string; root: string | null } {\n const mapped = options.repositories[run.projectKey]\n if (mapped !== undefined) return { path: mapped, root: null }\n\n const hint = run.repo.localPathHint?.trim()\n const roots = options.repoRoots ?? []\n if (hint) {\n const expanded = expandHome(hint)\n if (isAbsolute(expanded)) {\n const real = realpathOrSelf(expanded)\n for (const configured of roots) {\n const expandedRoot = expandHome(configured)\n if (!isAbsolute(expandedRoot)) continue\n const root = realpathOrSelf(expandedRoot)\n if (isWithin(real, root)) return { path: real, root }\n }\n }\n }\n\n const example = `(\"${run.projectKey}\": \"/path/to/repository\")`\n const detail = !hint\n ? ` Add it to the \\`workspaces\\` map in runner.json ${example}, or set the project's path hint and list its parent directory in \\`repoRoots\\`.`\n : roots.length === 0\n ? ` The project suggests ${hint}. Add its parent directory to \\`repoRoots\\` in runner.json (\\`aictiq runner root <path>\\`), or map it in \\`workspaces\\` ${example}.`\n : ` The project suggests ${hint}, which is not under any of this runner's repoRoots (${roots.join(', ')}). Add a root that contains it, or map it in \\`workspaces\\` ${example}.`\n throw new RunFailure(\n 'no-local-repository',\n `No local repository is mapped for project ${run.projectKey}.${detail}`,\n )\n}\n\nfunction expandHome(path: string): string {\n if (path === '~') return homedir()\n return path.startsWith('~/') ? join(homedir(), path.slice(2)) : path\n}\n\n/** The canonical path; a path that does not exist yet is still normalised (`..`, `.`). */\nfunction realpathOrSelf(path: string): string {\n const normalised = resolve(path)\n try {\n return realpathSync(normalised)\n } catch {\n return normalised\n }\n}\n\n/** True when `path` is `root` itself or below it. Both should already be real paths. */\nfunction isWithin(path: string, root: string): boolean {\n const rel = relative(root, path)\n return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nasync function provisionLocal(\n run: ClaimedRun,\n checkout: string,\n options: WorkspaceOptions,\n env: NodeJS.ProcessEnv,\n): Promise<string> {\n const { path: mapped, root } = resolveLocalRepository(run, options)\n const origin = root === null ? 'mapped for project' : 'the path hint for project'\n\n const toplevel = await git(['rev-parse', '--show-toplevel'], {\n cwd: mapped,\n env,\n signal: options.signal,\n }).catch((error: unknown) => {\n if (isAbort(error)) throw error\n throw new RunFailure(\n 'no-local-repository',\n `${mapped}, ${origin} ${run.projectKey}, is not a git repository.`,\n )\n })\n // A hinted directory that is not a clone itself would otherwise resolve to whatever\n // repository encloses it, e.g. a dotfiles repository in the home directory.\n if (root !== null && !isWithin(realpathOrSelf(toplevel.trim()), root)) {\n throw new RunFailure(\n 'no-local-repository',\n `${mapped}, the path hint for project ${run.projectKey}, is not a git repository under ${root}.`,\n )\n }\n const repo = toplevel.trim()\n const call = (args: string[]) => gitStep(args, { cwd: repo, env, signal: options.signal })\n\n const hasOrigin = await git(['remote', 'get-url', 'origin'], {\n cwd: repo,\n env,\n signal: options.signal,\n }).then(\n () => true,\n (error: unknown) => {\n if (isAbort(error)) throw error\n return false\n },\n )\n let base = run.defaultBranch\n if (hasOrigin) {\n options.event(`Fetching origin in ${repo}`)\n await call(['fetch', 'origin'])\n base = `origin/${run.defaultBranch}`\n }\n\n const branchExists = await git(\n ['rev-parse', '--verify', '--quiet', `refs/heads/${run.branchName}`],\n {\n cwd: repo,\n env,\n signal: options.signal,\n },\n ).then(\n () => true,\n (error: unknown) => {\n if (isAbort(error)) throw error\n return false\n },\n )\n\n if (branchExists) {\n // A retried run: its branch may already carry the previous attempt's commits.\n await call(['worktree', 'add', checkout, run.branchName])\n options.event(`Created worktree ${checkout} on existing branch ${run.branchName}`)\n } else {\n // --no-track: the new branch must not have the default branch as its upstream, or a bare\n // `git push` from the agent could land on it.\n await call(['worktree', 'add', '--no-track', '-b', run.branchName, checkout, base])\n options.event(`Created worktree ${checkout} on branch ${run.branchName} from ${base}`)\n }\n return repo\n}\n\nasync function provisionGithub(\n run: ClaimedRun,\n runDir: string,\n checkout: string,\n options: WorkspaceOptions,\n env: NodeJS.ProcessEnv,\n): Promise<Record<string, string>> {\n const full = run.repo.repoFullName\n if (!full || !/^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/.test(full)) {\n throw new RunFailure(\n 'workspace-failed',\n `The run names no valid GitHub repository (${full ?? 'none'}).`,\n )\n }\n\n const token = run.repo.cloneToken ?? (await options.refreshCloneToken?.()) ?? null\n if (!token) {\n throw new RunFailure(\n 'repository-token-unavailable',\n `No GitHub installation token is available to clone ${full}. Check that the GitHub App is still installed on the repository.`,\n )\n }\n\n // The token reaches git only through the environment: the askpass script prints it when\n // asked, so it is never in argv (readable through /proc), the remote URL or .git/config.\n const askpass = join(runDir, 'askpass.sh')\n writeFileSync(askpass, ASKPASS_SCRIPT, { mode: 0o700 })\n chmodSync(askpass, 0o700)\n const secretEnv: Record<string, string> = { GIT_ASKPASS: askpass, [TOKEN_ENV]: token }\n const cloneEnv = { ...env, ...secretEnv }\n\n const base = (options.githubBaseUrl ?? 'https://github.com').replace(/\\/+$/, '')\n const url = `${base}/${full}.git`\n await gitStep(\n // An empty credential.helper resets the user's own helpers, so a global `store` helper\n // cannot write the token to ~/.git-credentials after the clone succeeds.\n [\n '-c',\n 'credential.helper=',\n 'clone',\n '--depth',\n '50',\n '--branch',\n run.defaultBranch,\n url,\n checkout,\n ],\n { cwd: runDir, env: cloneEnv, signal: options.signal },\n token,\n )\n options.event(`Cloned ${full} (depth 50)`)\n\n const call = (args: string[]) =>\n gitStep(args, { cwd: checkout, env, signal: options.signal }, token)\n await call(['checkout', '-b', run.branchName])\n options.event(`Created branch ${run.branchName} from ${run.defaultBranch}`)\n\n // So the agent can push: a helper that reads the token from the harness's environment.\n await call(['config', '--local', '--replace-all', 'credential.helper', ''])\n await call(['config', '--local', '--add', 'credential.helper', CREDENTIAL_HELPER])\n\n return { [TOKEN_ENV]: token }\n}\n\nfunction writePrivate(path: string, content: string | Uint8Array): void {\n writeFileSync(path, content, { mode: 0o600 })\n chmodSync(path, 0o600)\n}\n\nasync function assertRefName(name: string, what: string, env: NodeJS.ProcessEnv): Promise<void> {\n // Also refuses names starting with `-`, which git would otherwise read as an option.\n const valid = await git(['check-ref-format', '--branch', name], { cwd: process.cwd(), env }).then(\n () => true,\n () => false,\n )\n if (!valid)\n throw new RunFailure(\n 'workspace-failed',\n `The run's ${what} \"${name}\" is not a valid git branch name.`,\n )\n}\n\ninterface GitOptions {\n cwd: string\n env: NodeJS.ProcessEnv\n signal?: AbortSignal | undefined\n}\n\nclass GitError extends Error {\n readonly stderr: string\n constructor(args: string[], code: number | null, stderr: string) {\n super(\n `git ${args[0] === '-c' ? (args[2] ?? '') : (args[0] ?? '')} exited with ${code ?? 'a signal'}`,\n )\n this.stderr = stderr\n }\n}\n\n/** A step whose failure fails the run, with git's own words in the message. */\nasync function gitStep(args: string[], options: GitOptions, secret?: string): Promise<string> {\n try {\n return await git(args, options)\n } catch (error) {\n if (error instanceof GitError) {\n const tail = error.stderr.trim().split('\\n').slice(-20).join('\\n')\n let message = tail ? `${error.message}:\\n${tail}` : error.message\n if (secret) message = message.replaceAll(secret, '***')\n throw new RunFailure('workspace-failed', message)\n }\n throw error\n }\n}\n\nfunction git(args: string[], options: GitOptions): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('git', args, {\n cwd: options.cwd,\n env: { ...options.env, GIT_TERMINAL_PROMPT: '0' },\n stdio: ['ignore', 'pipe', 'pipe'],\n signal: options.signal,\n })\n let stdout = ''\n let stderr = ''\n child.stdout.setEncoding('utf8').on('data', (chunk: string) => (stdout += chunk))\n child.stderr.setEncoding('utf8').on('data', (chunk: string) => {\n // Only the tail is ever reported; a long fetch must not grow this without bound.\n stderr = (stderr + chunk).slice(-16_384)\n })\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) resolve(stdout)\n else reject(new GitError(args, code, stderr))\n })\n })\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n","/**\n * The runner's shared vocabulary: what the instance hands over on a claim\n * (`RunnerRunClaimed`), what the runner reports about itself (`RunnerCapabilities`, v1),\n * and the seams between the poll loop, the workspace and the harness adapters.\n */\n\nexport type HarnessName = 'claude' | 'codex' | 'opencode'\n\nexport interface HarnessInfo {\n name: string\n version: string | null\n}\n\n/** `RunnerCapabilities` on the server - a versioned contract, not an implementation detail. */\nexport interface RunnerCapabilities {\n v: 1\n harnesses: HarnessInfo[]\n os: string | null\n arch: string | null\n cliVersion: string | null\n maxParallel: number\n}\n\nexport interface RunnerHello {\n runnerId: string\n name: string\n organizationSlug: string\n heartbeatIntervalSeconds: number\n pollTimeoutSeconds: number\n maxLogBytes: number\n maxLogBatchBytes: number\n maxRunMinutes: number\n}\n\nexport interface RunRepo {\n /** `github` when the project has a binding, `local` when the runner finds the working copy. */\n source: 'github' | 'local'\n repoFullName: string | null\n cloneToken: string | null\n localPathHint: string | null\n}\n\n/** Metadata for an item attachment which the runner can make available beside its checkout. */\nexport interface RunAttachment {\n id: string\n fileName: string\n contentType: string\n sizeBytes: number\n /** Undefined for an attachment on the item description itself. */\n commentId?: string | null\n}\n\nexport interface ClaimedRun {\n runId: string\n itemId: string\n itemKey: string\n projectId: string\n projectKey: string\n organizationSlug: string\n harness: string\n prompt: string\n playbookRevisionId: string | null\n repo: RunRepo\n defaultBranch: string\n branchName: string\n maxMinutes: number\n aictiqUrl: string | null\n agentToken: string\n agentTokenDisplay: string | null\n heartbeatIntervalSeconds: number\n}\n\nexport type LogStream = 'stdout' | 'stderr' | 'event'\n\nexport type RunnerOutcome = 'succeeded' | 'failed' | 'cancelled'\n\nexport interface FinishReport {\n outcome: RunnerOutcome\n exitCode?: number | null\n summary?: string | null\n pullRequestUrl?: string | null\n costUsd?: number | null\n inputTokens?: number | null\n outputTokens?: number | null\n failureReason?: string | null\n}\n\n/** One stdout line of a harness, as the adapter reads it. */\nexport interface ParsedLine {\n /** What goes into the run log; null drops the line (e.g. a noisy init event). */\n log: string | null\n progress?: string\n costUsd?: number\n inputTokens?: number\n outputTokens?: number\n /** The cost and token counts are this step's alone, to add to the run's total rather than replace it. */\n accumulate?: boolean\n /** A final answer the harness produced, used as the success summary. */\n result?: string\n}\n\nexport interface HarnessInvocation {\n command: string\n args: string[]\n /** Written to the child's stdin and then closed, when the harness reads its prompt there. */\n stdin?: string\n env?: Record<string, string>\n}\n\nexport interface HarnessOutcome {\n outcome: 'succeeded' | 'failed'\n summary: string | null\n failureReason: string | null\n}\n\n/** Everything an adapter may need to start a harness for one run. */\nexport interface InvocationContext {\n prompt: string\n promptFile: string\n /** The git checkout the harness works in (its cwd). */\n workspace: string\n /** Read-only, per-run files that live beside the checkout and must never be committed. */\n attachmentsDir: string\n /**\n * A Claude-style MCP config (`{ mcpServers: { aictiq: { command, args } } }`) written\n * outside the checkout, so nothing the agent might commit carries it.\n */\n mcpConfigFile: string\n /** The same server as a command line, for harnesses configured by flags or their own file. */\n mcpServer: { command: string; args: string[] }\n}\n\nexport interface HarnessAdapter {\n readonly name: HarnessName\n /** The executable's `--version`, or null when it is not on PATH. */\n available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null>\n /**\n * How to start the harness. The prompt is already in `promptFile` (0600, outside the\n * checkout): adapters pass it on stdin or by path rather than in argv, which has a length\n * limit and is readable by every user through /proc.\n */\n invocation(context: InvocationContext): HarnessInvocation\n parse(line: string): ParsedLine\n outcome(exitCode: number | null, lastLines: string[], lastResult: string | null): HarnessOutcome\n}\n\n/** A failure the runner reports as the run's `failureReason` rather than crashing on. */\nexport class RunFailure extends Error {\n readonly reason: string\n constructor(reason: string, message: string) {\n super(message)\n this.name = 'RunFailure'\n this.reason = reason\n }\n}\n","import { execFile } from 'node:child_process'\nimport { stripVTControlCharacters } from 'node:util'\nimport { RunnerHttpError, RunnerNetworkError } from './client.js'\nimport type { RunnerClient } from './client.js'\nimport { LogStreamer } from './log.js'\nimport { spawnSupervised } from './process.js'\nimport type { SupervisedProcess } from './process.js'\nimport { RunFailure } from './types.js'\nimport type { ClaimedRun, FinishReport, HarnessAdapter, RunnerHello } from './types.js'\nimport { provisionWorkspace } from './workspace.js'\nimport type { Workspace, WorkspaceOptions } from './workspace.js'\n\nconst MaxSummary = 4000\nconst MaxFailureReason = 500\nconst PullRequestUrl = /https:\\/\\/github\\.com\\/[\\w.-]+\\/[\\w.-]+\\/pull\\/\\d+/g\n\nexport interface ExecuteOptions {\n client: RunnerClient\n hello: RunnerHello\n adapters: Partial<Record<string, HarnessAdapter>>\n /** Workspace settings shared by every run; the per-run hooks are filled in here. */\n workspace: Omit<WorkspaceOptions, 'event' | 'refreshCloneToken' | 'signal'>\n /** The runner's own secret, redacted from the log like the run's tokens. */\n runnerToken: string\n /** The runner is shutting down and will not wait: stop the harness and report `cancelled`. */\n shutdown?: AbortSignal\n /** Runner-side messages for the operator's terminal (never sent to the instance). */\n local?: (message: string) => void\n provision?: (run: ClaimedRun, options: WorkspaceOptions) => Promise<Workspace>\n findPullRequest?: (\n checkout: string,\n branch: string,\n env: NodeJS.ProcessEnv,\n ) => Promise<string | null>\n heartbeatMs?: number\n graceMs?: number\n flushIntervalMs?: number\n}\n\n/**\n * Executes one claimed run from `started` to `finish`. The runner decides nothing about\n * the item - transitions, the outcome comment and the claim release are the server's\n * business once `finish` lands. What it does own: a workspace, a harness process,\n * the log, the heartbeat, and killing the process when told to or when time runs out.\n *\n * Returns the report it sent, or null when the server had already closed the run (a\n * sweeper's verdict, or a finish that was refused as a duplicate) and there was nothing\n * left to report.\n */\nexport async function executeRun(\n run: ClaimedRun,\n options: ExecuteOptions,\n): Promise<FinishReport | null> {\n const { client } = options\n const local = options.local ?? (() => {})\n const log = new LogStreamer({\n send: (chunks) => client.log(run.runId, chunks),\n secrets: [run.agentToken, options.runnerToken, run.repo.cloneToken ?? ''],\n maxBatchBytes: options.hello.maxLogBatchBytes,\n flushIntervalMs: options.flushIntervalMs ?? 1000,\n local: (message) => local(`${run.itemKey}: ${message}`),\n })\n const event = (line: string) => log.push('event', line)\n\n let harness: SupervisedProcess | undefined\n let stopReason: 'cancelled' | 'timed-out' | 'shutdown' | 'closed' | undefined\n const abort = new AbortController()\n const stop = (reason: NonNullable<typeof stopReason>) => {\n if (stopReason) return\n stopReason = reason\n abort.abort()\n void harness?.stop(options.graceMs ?? 10_000)\n }\n\n const onShutdown = () => stop('shutdown')\n options.shutdown?.addEventListener('abort', onShutdown, { once: true })\n if (options.shutdown?.aborted) onShutdown()\n\n let workspace: Workspace | undefined\n let revoked: RunnerHttpError | undefined\n let heartbeat: NodeJS.Timeout | undefined\n let beating: Promise<void> = Promise.resolve()\n let deadline: NodeJS.Timeout | undefined\n\n const report = await (async (): Promise<FinishReport | null> => {\n try {\n await client.started(run.runId)\n } catch (error) {\n // 409: the run was cancelled or swept between the claim and now. Nothing to execute.\n if (error instanceof RunnerHttpError && (error.status === 409 || error.status === 404)) {\n local(`${run.itemKey}: the instance closed run ${run.runId} before it started`)\n return null\n }\n throw error\n }\n event(`Runner picked up ${run.itemKey} with ${run.harness}`)\n\n // The heartbeat starts before anything slow: the item's claim was taken at dispatch and\n // goes stale if nobody refreshes it while the workspace is being cloned.\n const beat = async () => {\n try {\n const { cancelRequested } = await client.runHeartbeat(run.runId)\n if (cancelRequested) {\n event('Cancel requested; stopping the harness')\n stop('cancelled')\n }\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) {\n // The runner's secret is dead, so no finish can land either: stop now and let the\n // loop exit rather than run the harness on until the next runner heartbeat.\n revoked ??= error\n stop('closed')\n return\n }\n if (error instanceof RunnerHttpError && (error.status === 409 || error.status === 404)) {\n local(`${run.itemKey}: the instance closed run ${run.runId}; stopping it here`)\n stop('closed')\n return\n }\n local(`${run.itemKey}: run heartbeat failed: ${message(error)}`)\n }\n try {\n await client.itemHeartbeat(run)\n } catch (error) {\n local(`${run.itemKey}: item heartbeat failed: ${message(error)}`)\n }\n }\n const tick = () => {\n beating = beat()\n }\n tick()\n heartbeat = setInterval(\n tick,\n options.heartbeatMs ?? run.heartbeatIntervalSeconds * 1000,\n )\n deadline = setTimeout(() => {\n event(`The run reached its limit of ${run.maxMinutes} minutes; stopping the harness`)\n stop('timed-out')\n }, run.maxMinutes * 60_000)\n\n const adapter = options.adapters[run.harness]\n const info = adapter ? await adapter.available() : null\n if (!adapter || !info) {\n event(`Harness \"${run.harness}\" is not installed on this runner`)\n return failed(\n 'harness-unavailable',\n `This runner has no working \"${run.harness}\" on its PATH.`,\n )\n }\n event(`Using ${run.harness} ${info.version ?? ''}`.trim())\n\n try {\n workspace = await (options.provision ?? provisionWorkspace)(run, {\n ...options.workspace,\n event,\n refreshCloneToken: () => client.repoToken(run.runId),\n attachments: {\n list: () => client.listAttachments(run),\n download: (attachmentId) => client.downloadAttachment(run, attachmentId),\n },\n signal: abort.signal,\n })\n } catch (error) {\n if (stopReason) return stopped(null, [])\n if (error instanceof RunFailure) {\n event(error.message)\n return failed(error.reason, error.message)\n }\n event(`Workspace provisioning failed: ${message(error)}`)\n return failed('workspace-failed', message(error))\n }\n if (stopReason) return stopped(null, [])\n\n const invocation = adapter.invocation({\n prompt: workspace.prompt,\n promptFile: workspace.promptFile,\n workspace: workspace.checkout,\n attachmentsDir: workspace.attachmentsDir,\n mcpConfigFile: workspace.mcpConfigFile,\n mcpServer: options.workspace.mcpServer,\n })\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n ...invocation.env,\n ...workspace.env,\n // The agent reaches the instance as itself, never as the runner: `aictiq mcp` and the\n // CLI both read these, and they exist only in this process tree.\n AICTIQ_URL: run.aictiqUrl ?? client.baseUrl,\n AICTIQ_TOKEN: run.agentToken,\n AICTIQ_ORG: run.organizationSlug,\n AICTIQ_ITEM: run.itemKey,\n AICTIQ_RUN: run.runId,\n }\n\n const lastLines: string[] = []\n let lastResult: string | null = null\n let pullRequestUrl: string | null = null\n let costUsd: number | undefined\n let inputTokens: number | undefined\n let outputTokens: number | undefined\n const remember = (line: string) => {\n lastLines.push(line)\n if (lastLines.length > 20) lastLines.shift()\n }\n\n event(`Starting ${invocation.command} in ${workspace.checkout}`)\n harness = spawnSupervised({\n command: invocation.command,\n args: invocation.args,\n cwd: workspace.checkout,\n env,\n ...(invocation.stdin === undefined ? {} : { stdin: invocation.stdin }),\n onLine: (stream, raw) => {\n // Harnesses colour their errors even into a pipe; the log view and the summary\n // are plain text.\n const line = stripVTControlCharacters(raw)\n for (const match of line.matchAll(PullRequestUrl)) pullRequestUrl = match[0]\n if (stream === 'stderr') {\n log.push('stderr', line)\n remember(line)\n return\n }\n const parsed = adapter.parse(line)\n const tally = (total: number | undefined, value: number | undefined) =>\n value === undefined ? total : parsed.accumulate ? (total ?? 0) + value : value\n costUsd = tally(costUsd, parsed.costUsd)\n inputTokens = tally(inputTokens, parsed.inputTokens)\n outputTokens = tally(outputTokens, parsed.outputTokens)\n if (parsed.result !== undefined) lastResult = parsed.result\n if (parsed.log !== null) {\n log.push('stdout', parsed.log)\n remember(parsed.log)\n }\n },\n })\n // A stop requested while the process was being spawned must still reach it.\n if (stopReason) void harness.stop(options.graceMs ?? 10_000)\n\n const exitCode = await harness.exited\n event(exitCode === null ? 'Harness was killed' : `Harness exited with code ${exitCode}`)\n const usage = { costUsd, inputTokens, outputTokens, exitCode }\n if (stopReason) return stopped(exitCode, lastLines, usage)\n\n const verdict = adapter.outcome(exitCode, lastLines, lastResult)\n if (verdict.outcome === 'succeeded' && !pullRequestUrl) {\n pullRequestUrl = await (options.findPullRequest ?? findPullRequest)(\n workspace.checkout,\n run.branchName,\n env,\n )\n }\n if (pullRequestUrl) event(`Pull request: ${pullRequestUrl}`)\n return {\n outcome: verdict.outcome,\n exitCode,\n summary: truncate(verdict.summary, MaxSummary),\n pullRequestUrl,\n failureReason:\n verdict.outcome === 'failed'\n ? truncate(verdict.failureReason ?? 'harness-failed', MaxFailureReason)\n : null,\n costUsd: costUsd ?? null,\n inputTokens: inputTokens ?? null,\n outputTokens: outputTokens ?? null,\n }\n })()\n .catch((error: unknown): FinishReport | null => {\n if (error instanceof RunnerHttpError && error.revoked) throw error\n local(`${run.itemKey}: ${message(error)}`)\n event(`Runner error: ${message(error)}`)\n return failed('runner-error', message(error))\n })\n .finally(() => {\n clearInterval(heartbeat)\n clearTimeout(deadline)\n options.shutdown?.removeEventListener('abort', onShutdown)\n })\n\n if (report?.outcome === 'failed' && report.failureReason)\n event(`Run failed: ${report.failureReason}`)\n // A beat still in flight would otherwise reach the instance after the finish, and its\n // item heartbeat with a token the finish just revoked.\n await beating\n await log.close()\n await workspace?.cleanup()\n if (revoked) throw revoked\n if (!report) return null\n return (await sendFinish(client, run, report, local)) ? report : null\n\n function failed(reason: string, detail: string): FinishReport {\n return {\n outcome: 'failed',\n failureReason: truncate(reason, MaxFailureReason),\n summary: truncate(detail, MaxSummary),\n }\n }\n\n function stopped(\n exitCode: number | null,\n lines: string[],\n usage: Partial<FinishReport> = {},\n ): FinishReport | null {\n const tail = lines.length > 0 ? lines.join('\\n') : null\n switch (stopReason) {\n case 'closed':\n return null\n case 'timed-out':\n // `timed_out` is the server's verdict alone (its sweeper would reach it too); the\n // runner reports a failure whose reason says the same thing.\n return {\n ...usage,\n outcome: 'failed',\n exitCode,\n failureReason: 'timed-out',\n summary: truncate(tail, MaxSummary),\n }\n case 'shutdown':\n return {\n ...usage,\n outcome: 'cancelled',\n exitCode,\n failureReason: 'runner-shutdown',\n summary: 'The runner was stopped before the run finished.',\n }\n default:\n return { ...usage, outcome: 'cancelled', exitCode, summary: truncate(tail, MaxSummary) }\n }\n }\n}\n\n/** Reports the outcome, retrying while the instance is unreachable; false if it was refused. */\nasync function sendFinish(\n client: RunnerClient,\n run: ClaimedRun,\n report: FinishReport,\n local: (message: string) => void,\n): Promise<boolean> {\n for (let attempt = 0; ; attempt++) {\n try {\n await client.finish(run.runId, report)\n local(\n `${run.itemKey}: ${report.outcome}${report.failureReason ? ` (${report.failureReason})` : ''}`,\n )\n return true\n } catch (error) {\n if (error instanceof RunnerNetworkError && attempt < 30) {\n await new Promise((resolve) => setTimeout(resolve, Math.min(30_000, 1000 * 2 ** attempt)))\n continue\n }\n if (error instanceof RunnerHttpError && error.revoked) throw error\n // 409: already finished (a sweeper got there first). Anything else: the server's\n // sweepers will close the run; looping here would only hold the slot.\n local(`${run.itemKey}: could not report the outcome: ${message(error)}`)\n return false\n }\n }\n}\n\n/** `gh pr view <branch>`, when `gh` is installed and signed in; null otherwise. */\nexport function findPullRequest(\n checkout: string,\n branch: string,\n env: NodeJS.ProcessEnv,\n): Promise<string | null> {\n return new Promise((resolve) => {\n execFile(\n 'gh',\n ['pr', 'view', branch, '--json', 'url', '--jq', '.url'],\n { cwd: checkout, env, timeout: 15_000 },\n (error, stdout) => {\n const url = error ? '' : stdout.trim()\n resolve(/^https:\\/\\/\\S+\\/pull\\/\\d+$/.test(url) ? url : null)\n },\n )\n })\n}\n\nfunction truncate(value: string | null | undefined, max: number): string | null {\n if (!value) return null\n return value.length <= max ? value : `${value.slice(0, max - 1)}…`\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","import { RunnerHttpError } from './client.js'\nimport type { LogChunk } from './client.js'\nimport type { LogStream } from './types.js'\n\n/** The server's per-chunk text limit (`RunLogChunk.MaxTextLength`) and per-batch count. */\nconst MaxChunkChars = 65_536\nconst MaxChunksPerBatch = 512\n\nexport interface LogStreamerOptions {\n send: (chunks: LogChunk[]) => Promise<void>\n /** Secrets to blank out of every line before it leaves the machine. */\n secrets: string[]\n maxBatchBytes: number\n flushIntervalMs?: number\n /** Where the runner says something about the log itself (the cap was hit). */\n local?: (message: string) => void\n now?: () => Date\n retryDelayMs?: (attempt: number) => number\n}\n\n/**\n * Replaces each secret with a marker. Longest first, so a secret that contains another\n * (an installation token that happens to share a prefix) is not half-redacted.\n */\nexport function redact(text: string, secrets: readonly string[]): string {\n let result = text\n for (const secret of [...secrets]\n .filter((s) => s.length >= 8)\n .sort((a, b) => b.length - a.length)) {\n result = result.split(secret).join('[redacted]')\n }\n return result\n}\n\n/**\n * Batches log lines for `POST /runner/runs/{id}/log`: every second or when a batch reaches\n * the server's byte limit, whichever comes first. Each line gets its own `seq`, assigned\n * when it is queued, so a failed batch is re-sent with the same numbers and the server's\n * `ON CONFLICT DO NOTHING` makes the overlap harmless. Sends are strictly sequential.\n */\nexport class LogStreamer {\n private readonly options: LogStreamerOptions\n private readonly queue: LogChunk[] = []\n private seq = 0\n private timer: NodeJS.Timeout | undefined\n private sending: Promise<void> = Promise.resolve()\n private capped = false\n private closed = false\n private closing = false\n\n constructor(options: LogStreamerOptions) {\n this.options = options\n }\n\n /** True once the server refused the log for exceeding its cap; later lines are dropped. */\n get truncated(): boolean {\n return this.capped\n }\n\n push(stream: LogStream, line: string): void {\n if (this.capped || this.closed) return\n const text = redact(line, this.options.secrets)\n const at = (this.options.now?.() ?? new Date()).toISOString()\n // A line longer than one chunk may hold (or than one batch may carry) is split, so a\n // minified bundle printed by a build step cannot wedge the stream on a 400.\n for (const piece of splitByBytes(text, Math.min(this.options.maxBatchBytes, MaxChunkChars))) {\n this.queue.push({ seq: this.seq++, stream, text: piece, at })\n }\n\n if (this.queuedBytes() >= this.options.maxBatchBytes) {\n void this.flush()\n } else {\n this.timer ??= setTimeout(() => {\n this.timer = undefined\n void this.flush()\n }, this.options.flushIntervalMs ?? 1000)\n }\n }\n\n /** Sends everything queued so far; resolves once it is stored or the log is capped. */\n flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = undefined\n }\n this.sending = this.sending.then(() => this.drain())\n return this.sending\n }\n\n /** Flushes and stops accepting lines. */\n async close(): Promise<void> {\n this.closing = true\n await this.flush()\n this.closed = true\n }\n\n private async drain(): Promise<void> {\n while (this.queue.length > 0 && !this.capped) {\n const batch = this.takeBatch()\n let attempt = 0\n while (true) {\n try {\n await this.options.send(batch)\n this.queue.splice(0, batch.length)\n break\n } catch (error) {\n if (error instanceof RunnerHttpError && error.status === 413) {\n this.capped = true\n this.queue.length = 0\n this.options.local?.(\n 'The instance capped this run log; further output is kept out of it.',\n )\n return\n }\n // 409: the run is finished server-side, so its log is closed for good. Any\n // other refusal is a bug worth not looping on; only the network is retried.\n if (error instanceof RunnerHttpError) {\n this.queue.length = 0\n this.capped = true\n this.options.local?.(`The instance refused the run log: ${error.message}`)\n return\n }\n attempt++\n // While running, the network may come back and the log should survive it; at\n // close the run has to be reported, and a log that cannot be sent must not block it.\n if (attempt > 8 && this.closing) {\n this.queue.length = 0\n return\n }\n await delay(this.options.retryDelayMs?.(attempt) ?? Math.min(30_000, 500 * 2 ** attempt))\n }\n }\n }\n }\n\n private takeBatch(): LogChunk[] {\n const batch: LogChunk[] = []\n let bytes = 0\n for (const chunk of this.queue) {\n const size = Buffer.byteLength(chunk.text, 'utf8')\n if (\n batch.length > 0 &&\n (bytes + size > this.options.maxBatchBytes || batch.length >= MaxChunksPerBatch)\n )\n break\n batch.push(chunk)\n bytes += size\n }\n return batch\n }\n\n private queuedBytes(): number {\n let bytes = 0\n for (const chunk of this.queue) bytes += Buffer.byteLength(chunk.text, 'utf8')\n return bytes\n }\n}\n\n/** Splits on code-point boundaries so that each piece is at most `maxBytes` of UTF-8. */\nexport function splitByBytes(text: string, maxBytes: number): string[] {\n if (Buffer.byteLength(text, 'utf8') <= maxBytes) return [text]\n const pieces: string[] = []\n let current = ''\n let bytes = 0\n for (const char of text) {\n const size = Buffer.byteLength(char, 'utf8')\n if (bytes + size > maxBytes) {\n pieces.push(current)\n current = ''\n bytes = 0\n }\n current += char\n bytes += size\n }\n pieces.push(current)\n return pieces\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import { spawn } from 'node:child_process'\nimport type { ChildProcess } from 'node:child_process'\nimport { StringDecoder } from 'node:string_decoder'\n\nexport interface SupervisedProcess {\n readonly pid: number | undefined\n /** Resolves with the exit code, or null when a signal ended it. */\n readonly exited: Promise<number | null>\n /** SIGTERM to the whole process group, then SIGKILL after `graceMs` if it is still there. */\n stop(graceMs?: number): Promise<number | null>\n}\n\nexport interface SpawnOptions {\n command: string\n args: string[]\n cwd: string\n env: NodeJS.ProcessEnv\n stdin?: string\n onLine: (stream: 'stdout' | 'stderr', line: string) => void\n}\n\n/**\n * Starts a harness in its own process group (`detached`), so that stopping it stops what it\n * started too: a coding agent routinely leaves a dev server or a test watcher behind, and\n * signalling only the harness's pid would orphan them on the runner.\n */\nexport function spawnSupervised(options: SpawnOptions): SupervisedProcess {\n const child = spawn(options.command, options.args, {\n cwd: options.cwd,\n env: options.env,\n detached: process.platform !== 'win32',\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n const exited = new Promise<number | null>((resolve) => {\n let settled = false\n const settle = (code: number | null) => {\n if (settled) return\n settled = true\n resolve(code)\n }\n // A missing executable arrives as 'error' with no 'close'; 127 is the shell's answer.\n child.on('error', (error: NodeJS.ErrnoException) => {\n options.onLine('stderr', `Could not start ${options.command}: ${error.message}`)\n settle(error.code === 'ENOENT' ? 127 : 1)\n })\n child.on('close', (code) => {\n settle(code)\n signal(child, 'SIGKILL')\n })\n // 'close' waits for stdout to close, which a background process the harness left\n // behind keeps open indefinitely. Its exit is the verdict; the stragglers get two\n // seconds to flush and then go with the group.\n child.on('exit', (code) => {\n setTimeout(() => {\n settle(code)\n signal(child, 'SIGKILL')\n }, 2000)\n })\n })\n\n splitLines(child, 'stdout', options.onLine)\n splitLines(child, 'stderr', options.onLine)\n child.stdin?.on('error', () => {\n // The harness may exit before reading its prompt; EPIPE is not the runner's failure.\n })\n child.stdin?.end(options.stdin ?? '')\n\n return {\n pid: child.pid,\n exited,\n async stop(graceMs = 10_000) {\n signal(child, 'SIGTERM')\n const timer = setTimeout(() => signal(child, 'SIGKILL'), graceMs)\n try {\n return await exited\n } finally {\n clearTimeout(timer)\n // The harness may be gone while its children linger; the group goes with it.\n signal(child, 'SIGKILL')\n }\n },\n }\n}\n\nfunction signal(child: ChildProcess, name: NodeJS.Signals): void {\n if (child.pid === undefined) return\n try {\n if (process.platform === 'win32') child.kill(name)\n else process.kill(-child.pid, name)\n } catch {\n // ESRCH: already gone.\n }\n}\n\nfunction splitLines(\n child: ChildProcess,\n stream: 'stdout' | 'stderr',\n onLine: (stream: 'stdout' | 'stderr', line: string) => void,\n): void {\n const source = child[stream]\n if (!source) return\n const decoder = new StringDecoder('utf8')\n let buffer = ''\n source.on('data', (data: Buffer) => {\n buffer += decoder.write(data)\n let index: number\n while ((index = buffer.indexOf('\\n')) >= 0) {\n onLine(stream, buffer.slice(0, index).replace(/\\r$/, ''))\n buffer = buffer.slice(index + 1)\n }\n })\n source.on('end', () => {\n buffer += decoder.end()\n if (buffer.length > 0) onLine(stream, buffer)\n buffer = ''\n })\n}\n","import { execFile } from 'node:child_process'\nimport type { HarnessAdapter, HarnessInfo, ParsedLine } from '../types.js'\n\nconst limit = (value: string, length: number) =>\n value.length > length ? `${value.slice(0, Math.max(0, length - 1))}…` : value\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null\n\n/** Reads only the first line: some CLIs add build information after their version. */\nexport function versionOf(\n command: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<string | null> {\n return new Promise((resolve) => {\n execFile(command, ['--version'], { env, timeout: 5_000 }, (error, stdout, stderr) => {\n if (error) return resolve(null)\n const output = String(stdout || stderr).trim()\n const firstLine = output.split(/\\r?\\n/)[0]?.slice(0, 100) ?? ''\n resolve(firstLine || null)\n })\n })\n}\n\nfunction failedOutcome(exitCode: number | null, lastLines: string[]) {\n return {\n outcome: 'failed' as const,\n failureReason: exitCode === null ? 'harness-killed' : `harness-exit-${exitCode}`,\n summary: limit(lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n}\n\nexport const claude: HarnessAdapter = {\n name: 'claude',\n\n async available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null> {\n const version = await versionOf('claude', env)\n return version === null ? null : { name: 'claude', version }\n },\n\n invocation(context) {\n return {\n command: 'claude',\n args: [\n '-p',\n '--output-format',\n 'stream-json',\n '--verbose',\n '--permission-mode',\n 'bypassPermissions',\n '--mcp-config',\n context.mcpConfigFile,\n // Claude's working directory remains the checkout. Attachments are deliberately\n // beside it, so grant this one read-only run directory explicitly.\n '--add-dir',\n context.attachmentsDir,\n ],\n // Claude's -p mode consumes stdin when there is no positional prompt.\n stdin: context.prompt,\n }\n },\n\n parse(line): ParsedLine {\n let event: Record<string, unknown>\n try {\n const parsed = JSON.parse(line) as unknown\n event =\n recordOf(parsed) ??\n (() => {\n throw new Error('not an object')\n })()\n } catch {\n return { log: line }\n }\n\n if (event.type === 'system' && event.subtype === 'init') {\n return { log: `[init] model ${typeof event.model === 'string' ? event.model : 'unknown'}` }\n }\n\n if (event.type === 'assistant') {\n const message = recordOf(event.message)\n const content = Array.isArray(message?.content) ? message.content : []\n const logs = content.flatMap((block) => {\n const part = recordOf(block)\n if (!part || part.type === 'thinking') return []\n if (part.type === 'text' && typeof part.text === 'string') return [part.text]\n if (part.type === 'tool_use') {\n const name = typeof part.name === 'string' ? part.name : 'tool'\n const input = limit(JSON.stringify(part.input ?? {}), 200)\n return [`→ ${name} ${input}`]\n }\n return []\n })\n return { log: logs.length > 0 ? logs.join('\\n') : null }\n }\n\n if (event.type === 'user') {\n const message = recordOf(event.message)\n const content = Array.isArray(message?.content) ? message.content[0] : message?.content\n const result = recordOf(content)\n if (result?.type !== 'tool_result') return { log: null }\n const text =\n typeof result.content === 'string' ? result.content : JSON.stringify(result.content ?? '')\n const error = result.is_error === true ? '[error] ' : ''\n return { log: `← ${error}${limit(text.split(/\\r?\\n/)[0] ?? '', 200)}` }\n }\n\n if (event.type === 'result') {\n const usage = recordOf(event.usage)\n const input =\n numberOf(usage?.input_tokens) +\n numberOf(usage?.cache_creation_input_tokens) +\n numberOf(usage?.cache_read_input_tokens)\n return {\n // The marker is what `outcome` reads: the runner keeps the logged lines, not the raw JSON.\n log: `[result] ${typeof event.subtype === 'string' ? event.subtype : 'unknown'}${event.is_error === true ? ' (error)' : ''} in ${numberOf(event.duration_ms)}ms`,\n costUsd: numberOrUndefined(event.total_cost_usd),\n inputTokens: input || undefined,\n outputTokens: numberOrUndefined(usage?.output_tokens),\n result: typeof event.result === 'string' ? event.result : undefined,\n }\n }\n\n return { log: null }\n },\n\n outcome(exitCode, lastLines, lastResult) {\n if (exitCode !== 0) return failedOutcome(exitCode, lastLines)\n // An error result (a refused prompt, an exhausted budget) can still exit 0; the result\n // line `parse` logged is what says so.\n if (lastLines.some((line) => /^\\[result\\] .*\\(error\\)/.test(line))) {\n return { ...failedOutcome(exitCode, lastLines), failureReason: 'harness-error' }\n }\n return {\n outcome: 'succeeded',\n failureReason: null,\n summary: limit(lastResult ?? lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n },\n}\n\nfunction numberOf(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { HarnessAdapter, HarnessInfo, ParsedLine } from '../types.js'\nimport { versionOf } from './claude.js'\n\nconst limit = (value: string, length: number) =>\n value.length > length ? `${value.slice(0, Math.max(0, length - 1))}…` : value\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null\n\nconst MCP_ENV = ['AICTIQ_URL', 'AICTIQ_TOKEN', 'AICTIQ_ORG', 'AICTIQ_ITEM', 'AICTIQ_RUN']\n\nexport const codex: HarnessAdapter = {\n name: 'codex',\n\n async available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null> {\n const version = await versionOf('codex', env)\n return version === null ? null : { name: 'codex', version }\n },\n\n invocation(context) {\n return {\n command: 'codex',\n args: [\n 'exec',\n '--json',\n // 0.154.0 removed --full-auto. The runner is the ticket's explicit trust boundary:\n // the agent needs unrestricted network access for the MCP server and git push.\n '--dangerously-bypass-approvals-and-sandbox',\n // This mode also permits the absolute attachment paths named in prompt.md outside\n // the checkout. The runner itself remains the trust boundary for those files.\n '--skip-git-repo-check',\n '-C',\n context.workspace,\n '-c',\n `mcp_servers.aictiq.command=${JSON.stringify(context.mcpServer.command)}`,\n '-c',\n `mcp_servers.aictiq.args=${JSON.stringify(context.mcpServer.args)}`,\n // Codex starts MCP servers with a scrubbed environment; without this the bridge\n // never sees the run's credential and the handshake fails. Names only - the values\n // stay in the process environment, out of argv.\n '-c',\n `mcp_servers.aictiq.env_vars=${JSON.stringify(MCP_ENV)}`,\n '-',\n ],\n stdin: context.prompt,\n }\n },\n\n parse(line): ParsedLine {\n let event: Record<string, unknown>\n try {\n const parsed = JSON.parse(line) as unknown\n event =\n recordOf(parsed) ??\n (() => {\n throw new Error('not an object')\n })()\n } catch {\n return { log: line }\n }\n\n const item = recordOf(event.item)\n if ((event.type === 'item.completed' || event.type === 'item.started') && item) {\n if (item.type === 'agent_message' && typeof item.text === 'string') {\n return { log: item.text, result: item.text }\n }\n // A command arrives twice, started and completed; log it once, when it starts.\n if (item.type === 'command_execution') {\n if (event.type === 'item.completed') return { log: null }\n const command =\n typeof item.command === 'string' ? item.command : JSON.stringify(item.command ?? '')\n return { log: `→ command ${limit(command, 200)}` }\n }\n if (item.type === 'file_change') {\n const changes = Array.isArray(item.changes) ? item.changes : []\n const paths = changes\n .map((change) => recordOf(change)?.path)\n .filter((path): path is string => typeof path === 'string')\n return { log: paths.length > 0 ? `→ file_change ${limit(paths.join(', '), 200)}` : null }\n }\n }\n\n const usage = usageOf(event)\n if (usage) {\n const input =\n numberOf(usage.input_tokens) +\n numberOf(usage.cached_input_tokens) +\n numberOf(usage.cache_write_input_tokens)\n return {\n log: null,\n inputTokens: input || undefined,\n outputTokens: numberOrUndefined(usage.output_tokens),\n }\n }\n return { log: null }\n },\n\n outcome(exitCode, lastLines, lastResult) {\n if (exitCode !== 0) return failedOutcome(exitCode, lastLines)\n return {\n outcome: 'succeeded',\n failureReason: null,\n summary: limit(lastResult ?? lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n },\n}\n\nfunction usageOf(event: Record<string, unknown>): Record<string, unknown> | null {\n if (event.type === 'turn.completed') return recordOf(event.usage)\n if (event.type === 'token_count') return recordOf(event.usage) ?? recordOf(event.info)\n const payload = recordOf(event.payload)\n if (payload?.type === 'token_count') {\n return recordOf(payload.usage) ?? recordOf(recordOf(payload.info)?.total_token_usage)\n }\n return null\n}\n\nfunction failedOutcome(exitCode: number | null, lastLines: string[]) {\n return {\n outcome: 'failed' as const,\n failureReason: exitCode === null ? 'harness-killed' : `harness-exit-${exitCode}`,\n summary: limit(lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n}\n\nfunction numberOf(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { HarnessAdapter, HarnessInfo, ParsedLine } from '../types.js'\nimport { versionOf } from './claude.js'\n\nconst limit = (value: string, length: number) =>\n value.length > length ? `${value.slice(0, Math.max(0, length - 1))}…` : value\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null\n\nexport const opencode: HarnessAdapter = {\n name: 'opencode',\n\n async available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null> {\n const version = await versionOf('opencode', env)\n return version === null ? null : { name: 'opencode', version }\n },\n\n invocation(context) {\n return {\n command: 'opencode',\n // `--file` is a variadic option: anything after it is taken as another file to\n // attach, so the message goes first and the prompt file last.\n args: [\n 'run',\n 'Follow the instructions in the attached file.',\n '--format',\n 'json',\n '--dir',\n context.workspace,\n '--file',\n context.promptFile,\n context.attachmentsDir,\n ],\n env: {\n OPENCODE_CONFIG_CONTENT: JSON.stringify({\n $schema: 'https://opencode.ai/config.json',\n mcp: {\n aictiq: {\n type: 'local',\n command: [context.mcpServer.command, ...context.mcpServer.args],\n enabled: true,\n },\n },\n }),\n },\n }\n },\n\n parse(line): ParsedLine {\n let event: Record<string, unknown>\n try {\n const parsed = JSON.parse(line) as unknown\n event =\n recordOf(parsed) ??\n (() => {\n throw new Error('not an object')\n })()\n } catch {\n return { log: line }\n }\n\n const part = recordOf(event.part)\n if (!part) return { log: null }\n if (event.type === 'text' && typeof part.text === 'string') {\n // Returning each text part as result lets the runner retain the final one per run.\n return { log: part.text, result: part.text }\n }\n if (event.type === 'tool_use') {\n const tool =\n typeof part.tool === 'string'\n ? part.tool\n : typeof part.name === 'string'\n ? part.name\n : 'tool'\n const state = recordOf(part.state)\n return { log: `→ ${tool} ${limit(JSON.stringify(state?.input ?? part.input ?? {}), 200)}` }\n }\n // Each step reports its own usage, so the runner adds them up. Cache reads and writes\n // are input the model processed, as the Codex adapter counts them; reasoning is output.\n if (event.type === 'step_finish') {\n const tokens = recordOf(part.tokens)\n const cache = recordOf(tokens?.cache)\n return {\n log: null,\n accumulate: true,\n costUsd: numberOrUndefined(part.cost),\n inputTokens: sumOf(tokens?.input, cache?.read, cache?.write),\n outputTokens: sumOf(tokens?.output, tokens?.reasoning),\n }\n }\n return { log: null }\n },\n\n outcome(exitCode, lastLines, lastResult) {\n if (exitCode !== 0) return failedOutcome(exitCode, lastLines)\n return {\n outcome: 'succeeded',\n failureReason: null,\n summary: limit(lastResult ?? lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n },\n}\n\nfunction failedOutcome(exitCode: number | null, lastLines: string[]) {\n return {\n outcome: 'failed' as const,\n failureReason: exitCode === null ? 'harness-killed' : `harness-exit-${exitCode}`,\n summary: limit(lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n}\n\nfunction sumOf(...values: unknown[]): number | undefined {\n const numbers = values.filter(\n (value): value is number => typeof value === 'number' && Number.isFinite(value),\n )\n return numbers.length === 0 ? undefined : numbers.reduce((total, value) => total + value, 0)\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { HarnessAdapter, HarnessInfo, HarnessName } from '../types.js'\nimport { claude } from './claude.js'\nimport { codex } from './codex.js'\nimport { opencode } from './opencode.js'\n\nexport { versionOf } from './claude.js'\n\nexport const harnesses: Record<HarnessName, HarnessAdapter> = { claude, codex, opencode }\n\nexport async function probeHarnesses(env?: NodeJS.ProcessEnv): Promise<HarnessInfo[]> {\n const found = await Promise.all(Object.values(harnesses).map((harness) => harness.available(env)))\n return found.filter((info): info is HarnessInfo => info !== null)\n}\n","import { RunnerHttpError, RunnerNetworkError } from './client.js'\nimport type { RunnerClient } from './client.js'\nimport type { ClaimedRun, RunnerCapabilities, RunnerHello } from './types.js'\n\n/** Every harness the CLI has an adapter for, offered when none is detected (see below). */\nexport const KnownHarnesses = ['claude', 'codex', 'opencode'] as const\n\nexport interface RunnerLoopOptions {\n client: RunnerClient\n parallel: number\n probe: () => Promise<RunnerCapabilities>\n execute: (run: ClaimedRun, hello: RunnerHello, shutdown: AbortSignal) => Promise<unknown>\n local: (message: string) => void\n backoffMs?: (attempt: number) => number\n}\n\nexport class RunnerRevokedError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'RunnerRevokedError'\n }\n}\n\n/**\n * The runner's life: `hello`, then claim → execute in up to `parallel` slots, heartbeating\n * the runner alongside. `stop()` is the first Ctrl-C: claim nothing more and let the runs\n * in flight finish. `abort()` is the second: stop the harnesses and report them cancelled.\n */\nexport class RunnerLoop {\n private readonly options: RunnerLoopOptions\n private readonly active = new Set<Promise<void>>()\n private readonly claimAbort = new AbortController()\n private readonly shutdown = new AbortController()\n private stopping = false\n private revoked: RunnerRevokedError | undefined\n private wake: (() => void) | undefined\n\n constructor(options: RunnerLoopOptions) {\n this.options = options\n }\n\n get inFlight(): number {\n return this.active.size\n }\n\n stop(): void {\n this.stopping = true\n this.claimAbort.abort()\n this.wake?.()\n }\n\n abort(): void {\n this.stop()\n this.shutdown.abort()\n }\n\n /** Resolves when the loop has stopped and every run it took is reported. */\n async run(): Promise<void> {\n const { client, local } = this.options\n let capabilities = await this.options.probe()\n const hello = await this.retrying(() => client.hello(capabilities))\n if (!hello) return\n local(\n `Runner \"${hello.name}\" connected to ${client.baseUrl} (${hello.organizationSlug}); harnesses: ${\n capabilities.harnesses.map((h) => h.name).join(', ') || 'none detected'\n }`,\n )\n\n const heartbeat = setInterval(() => {\n void (async () => {\n try {\n capabilities = await this.options.probe()\n await client.heartbeat(capabilities)\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) this.revoke(error)\n else local(`Heartbeat failed: ${error instanceof Error ? error.message : String(error)}`)\n }\n })()\n }, hello.heartbeatIntervalSeconds * 1000)\n\n try {\n let attempt = 0\n while (!this.stopping) {\n const free = this.options.parallel - this.active.size\n if (free <= 0) {\n await this.waitForSlot()\n continue\n }\n\n // With no harness detected the runner still offers every one it knows, so a run\n // dispatched to a misconfigured machine fails at once with `harness-unavailable`\n // instead of waiting in the queue with no explanation.\n const detected = capabilities.harnesses.map((h) => h.name)\n const offered = detected.length > 0 ? detected : [...KnownHarnesses]\n let claimed: ClaimedRun | null\n try {\n claimed = await client.claim(offered, free, this.claimAbort.signal)\n attempt = 0\n } catch (error) {\n if (this.stopping) break\n if (error instanceof RunnerHttpError && error.revoked) {\n this.revoke(error)\n break\n }\n attempt++\n const wait =\n this.options.backoffMs?.(attempt) ?? Math.min(60_000, 1000 * 2 ** (attempt - 1))\n local(\n `Claim failed (${error instanceof Error ? error.message : String(error)}); retrying in ${Math.round(wait / 1000)}s`,\n )\n await this.sleep(wait)\n continue\n }\n if (!claimed) continue\n\n local(`Claimed ${claimed.itemKey} (run ${claimed.runId}, ${claimed.harness})`)\n const execution = this.options\n .execute(claimed, hello, this.shutdown.signal)\n .then(() => undefined)\n .catch((error: unknown) => {\n if (error instanceof RunnerHttpError && error.revoked) this.revoke(error)\n else\n local(\n `Run ${claimed.runId} ended with an error: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n .finally(() => {\n this.active.delete(execution)\n this.wake?.()\n })\n this.active.add(execution)\n }\n\n if (this.active.size > 0) local(`Waiting for ${this.active.size} run(s) to finish…`)\n await Promise.all([...this.active])\n } finally {\n clearInterval(heartbeat)\n }\n\n if (this.revoked) throw this.revoked\n }\n\n private revoke(error: RunnerHttpError): void {\n this.revoked ??= new RunnerRevokedError(\n error.problem?.type?.endsWith('token-revoked')\n ? 'This runner was disabled, deleted or rotated. Register it again with `aictiq runner register`.'\n : `The instance refused the runner secret (${error.message}). Register it again with \\`aictiq runner register\\`.`,\n )\n this.abort()\n }\n\n /** Retries network failures until stopped; a refusal is thrown. */\n private async retrying<T>(action: () => Promise<T>): Promise<T | null> {\n for (let attempt = 1; !this.stopping; attempt++) {\n try {\n return await action()\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) {\n this.revoke(error)\n throw this.revoked\n }\n if (!(error instanceof RunnerNetworkError)) throw error\n const wait =\n this.options.backoffMs?.(attempt) ?? Math.min(60_000, 1000 * 2 ** (attempt - 1))\n this.options.local(`${error.message}; retrying in ${Math.round(wait / 1000)}s`)\n await this.sleep(wait)\n }\n }\n return null\n }\n\n private waitForSlot(): Promise<void> {\n return new Promise((resolve) => {\n this.wake = () => {\n this.wake = undefined\n resolve()\n }\n })\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(done, ms)\n this.wake = done\n function done() {\n clearTimeout(timer)\n resolve()\n }\n })\n }\n}\n","import { Command } from 'commander'\nimport type { SprintView, TeamView } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { formatNumber, print, printJson, renderFields, renderTable } from '../output.js'\nimport { getTeams } from '../resolve.js'\n\ninterface TaskboardCell {\n key: string\n name: string\n remainingHours: number\n tasks: { key: string; title: string; assigneeId: string | null }[]\n}\n\ninterface TaskboardView {\n sprintId: string\n rows: { parentKey: string | null; name: string; remainingHours: number; cells: TaskboardCell[] }[]\n unparentedTasks: TaskboardCell[]\n}\n\nexport function sprintCommand(globals: () => GlobalOptions): Command {\n const sprint = new Command('sprint').description('Sprints')\n\n sprint\n .command('list')\n .description(\"List a team's sprints, newest first\")\n .requiredOption('-t, --team <key>', 'Team key, name or id')\n .option('-p, --project <key>', 'Project key; required when the team is named, not an id')\n .action(async (options: { team: string; project?: string }) => {\n const ctx = createContext(globals())\n const teamId = await resolveTeamId(ctx, options.team, options.project)\n const sprints = await ctx.client.request<\n SprintView[],\n '/api/v1/orgs/{orgSlug}/teams/{teamId}/sprints',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/teams/{teamId}/sprints', {\n path: { orgSlug: await ctx.org(), teamId },\n })\n\n if (ctx.json) return printJson(sprints)\n if (sprints.length === 0) return print('No sprints.')\n print(\n renderTable(sprints, [\n { header: 'ID', value: (s) => s.id },\n { header: 'NAME', value: (s) => s.name },\n { header: 'STATE', value: (s) => s.state },\n { header: 'STARTS', value: (s) => s.startsOn },\n { header: 'ENDS', value: (s) => s.endsOn },\n {\n header: 'DONE',\n value: (s) => `${s.progress.completedItems}/${s.progress.totalItems}`,\n align: 'right',\n },\n ]),\n )\n })\n\n sprint\n .command('view')\n .description('Show a sprint and its taskboard')\n .argument('<sprintId>', 'Sprint id')\n .option('--taskboard', 'Include the taskboard rows')\n .action(async (sprintId: string, options: { taskboard?: boolean }) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const found = await ctx.client.request<\n SprintView,\n '/api/v1/orgs/{orgSlug}/sprints/{sprintId}',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/sprints/{sprintId}', { path: { orgSlug, sprintId } })\n const taskboard = options.taskboard\n ? await ctx.client.request<\n TaskboardView,\n '/api/v1/orgs/{orgSlug}/sprints/{sprintId}/taskboard',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/sprints/{sprintId}/taskboard', {\n path: { orgSlug, sprintId },\n })\n : undefined\n\n if (ctx.json) return printJson({ ...found, ...(taskboard ? { taskboard } : {}) })\n\n print(\n renderFields([\n ['Sprint', found.name],\n ['Goal', found.goal],\n ['State', found.state],\n ['Dates', `${found.startsOn} → ${found.endsOn}`],\n ['Days left', String(found.daysLeft)],\n ['Items', `${found.progress.completedItems}/${found.progress.totalItems}`],\n [\n 'Points',\n `${formatNumber(found.progress.pointsDone)}/${formatNumber(found.progress.pointsTotal)}`,\n ],\n ['Remaining hours', formatNumber(found.progress.remainingHours)],\n ]),\n )\n if (taskboard) {\n for (const row of taskboard.rows) {\n print('')\n print(`${row.parentKey ?? '(no parent)'} ${row.name}`)\n for (const cell of row.cells) {\n for (const task of cell.tasks) {\n print(` [${cell.name}] ${task.key} ${task.title}`)\n }\n }\n }\n }\n })\n\n return sprint\n}\n\n/** A team id passes through; a key or name needs the project whose teams to search. */\nasync function resolveTeamId(ctx: Context, team: string, projectKey?: string): Promise<string> {\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(team)) return team\n if (!projectKey) {\n throw new CliError(\n 'Pass -p <projectKey> alongside a team key or name, or give the team id.',\n ExitCode.Validation,\n )\n }\n const teams: TeamView[] = await getTeams(ctx, projectKey.toUpperCase())\n const needle = team.trim().toLowerCase()\n const found = teams.find((t) => t.key.toLowerCase() === needle || t.name.toLowerCase() === needle)\n if (!found) {\n throw new CliError(\n `No team \"${team}\" in ${projectKey}. Teams: ${teams.map((t) => t.key).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n return found.id\n}\n","import { Command } from 'commander'\nimport type { WikiPageView, WikiTreePageView } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { print, printJson, renderTable } from '../output.js'\nimport { readBody } from '../resolve.js'\n\nexport function wikiCommand(globals: () => GlobalOptions): Command {\n const wiki = new Command('wiki').description('Project wiki pages')\n\n wiki\n .command('tree')\n .description('List the page tree of a project')\n .requiredOption('-p, --project <key>', 'Project key, e.g. ACME')\n .action(async (options: { project: string }) => {\n const ctx = createContext(globals())\n const pages = await fetchTree(ctx, options.project.toUpperCase())\n if (ctx.json) return printJson(pages)\n if (pages.length === 0) return print('No wiki pages.')\n const paths = pathsOf(pages)\n print(\n renderTable(pages, [\n { header: 'PATH', value: (p) => paths.get(p.id) ?? p.slug },\n { header: 'TITLE', value: (p) => p.title },\n ]),\n )\n })\n\n wiki\n .command('get')\n .description('Print a wiki page as Markdown')\n .argument('<project>', 'Project key, e.g. ACME')\n .argument('<path>', 'Slug path, e.g. specs/login')\n .action(async (project: string, path: string) => {\n const ctx = createContext(globals())\n const pages = await fetchTree(ctx, project.toUpperCase())\n const page = findByPath(pages, path)\n if (!page) throw new CliError(`No wiki page at \"${path}\" in ${project}.`, ExitCode.NotFound)\n const full = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}', {\n path: { orgSlug: await ctx.org(), pageId: page.id },\n })\n if (ctx.json) return printJson(full)\n print(full.contentMarkdown)\n })\n\n wiki\n .command('put')\n .description('Create or replace a wiki page from Markdown')\n .argument('<project>', 'Project key, e.g. ACME')\n .argument('<path>', 'Slug path, e.g. specs/login')\n .option('--file <path>', 'Markdown file, or - for stdin', '-')\n .option('-m, --body <markdown>', 'Markdown body given inline')\n .option('--title <title>', 'Page title; defaults to the last path segment')\n .option('--summary <text>', 'Revision summary recorded in the history')\n .action(\n async (\n project: string,\n path: string,\n options: { file?: string; body?: string; title?: string; summary?: string },\n ) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const projectKey = project.toUpperCase()\n const content = await readBody(\n options.body,\n options.body ? undefined : (options.file ?? '-'),\n )\n if (content === undefined || content.trim().length === 0) {\n throw new CliError('The page body is empty.', ExitCode.Validation)\n }\n\n const pages = await fetchTree(ctx, projectKey)\n const existing = findByPath(pages, path)\n if (existing) {\n // The version comes from the page we are about to replace, so a concurrent edit\n // 409s (exit 3) instead of silently winning.\n const current = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}', {\n path: { orgSlug, pageId: existing.id },\n })\n const updated = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}',\n 'patch'\n >('patch', '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}', {\n path: { orgSlug, pageId: existing.id },\n body: {\n contentMd: content,\n version: current.version,\n ...(options.title ? { title: options.title } : {}),\n ...(options.summary ? { summary: options.summary } : {}),\n },\n })\n if (ctx.json) return printJson(updated)\n return print(`Updated ${path} (revision ${updated.revisionNumber}).`)\n }\n\n const segments = path.split('/').filter((s) => s.length > 0)\n const parentPath = segments.slice(0, -1).join('/')\n const parent = parentPath ? findByPath(pages, parentPath) : undefined\n if (parentPath && !parent) {\n throw new CliError(\n `The parent page \"${parentPath}\" does not exist; create it first.`,\n ExitCode.NotFound,\n )\n }\n const created = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/pages',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/pages', {\n path: { orgSlug, projectKey },\n body: {\n title: options.title ?? titleFrom(segments.at(-1) ?? path),\n contentMd: content,\n ...(parent ? { parentId: parent.id } : {}),\n },\n })\n if (ctx.json) return printJson(created)\n // The API derives the slug from the title, so the page may not sit at the path\n // that was asked for. Saying where it landed beats a silent surprise next `get`.\n print(`Created ${created.slug} (${created.title}).`)\n },\n )\n\n return wiki\n}\n\nasync function fetchTree(ctx: Context, projectKey: string): Promise<WikiTreePageView[]> {\n return ctx.client.request<\n WikiTreePageView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/tree',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/tree', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n}\n\n/** Slugs are unique per parent, so a page is addressed by the path of slugs to it. */\nfunction pathsOf(pages: readonly WikiTreePageView[]): Map<string, string> {\n const byId = new Map(pages.map((page) => [page.id, page]))\n const paths = new Map<string, string>()\n const walk = (page: WikiTreePageView): string => {\n const cached = paths.get(page.id)\n if (cached) return cached\n const parent = page.parentId ? byId.get(page.parentId) : undefined\n const path = parent ? `${walk(parent)}/${page.slug}` : page.slug\n paths.set(page.id, path)\n return path\n }\n for (const page of pages) walk(page)\n return paths\n}\n\nfunction findByPath(\n pages: readonly WikiTreePageView[],\n path: string,\n): WikiTreePageView | undefined {\n const wanted = path\n .split('/')\n .filter((s) => s.length > 0)\n .join('/')\n .toLowerCase()\n const paths = pathsOf(pages)\n return pages.find((page) => paths.get(page.id)?.toLowerCase() === wanted)\n}\n\nfunction titleFrom(slug: string): string {\n const words = slug.replace(/[-_]+/g, ' ').trim()\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n","import { CliError, ExitCode } from './errors.js'\nimport { createProgram } from './program.js'\n\nasync function main(): Promise<void> {\n const program = createProgram()\n // Commander's own failures (unknown command, missing required option) are usage errors,\n // which is the same class as a rejected request body: exit 2.\n program.exitOverride((error) => {\n if (error.code === 'commander.helpDisplayed' || error.code === 'commander.version') {\n process.exit(ExitCode.Ok)\n }\n process.exit(error.exitCode === 0 ? ExitCode.Ok : ExitCode.Validation)\n })\n await program.parseAsync(process.argv)\n}\n\nmain().catch((error: unknown) => {\n if (error instanceof CliError) {\n // The message already carries the problem's title and field errors.\n process.stderr.write(`${error.message}\\n`)\n process.exit(error.exitCode)\n }\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(ExitCode.Error)\n})\n"],"mappings":"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","names":["message","Command","Command","resolve","Command","Command","readFileSync","message","readFileSync","Command","version","Command","Command","resolve","Command","Command","Command","Command","resolve","Command","existsSync","resolve","message","harnesses","signal","chmodSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","chmodSync","mkdirSync","rmSync","writeFileSync","homedir","join","message","join","homedir","rmSync","mkdirSync","chmodSync","writeFileSync","message","resolve","join","homedir","existsSync","readFileSync","mkdirSync","dirname","writeFileSync","chmodSync","resolve","spawn","resolve","message","resolve","execFile","limit","resolve","version","message","limit","recordOf","version","numberOf","numberOrUndefined","failedOutcome","limit","recordOf","version","numberOrUndefined","failedOutcome","message","resolve","Command","resolve","existsSync","formatBytes","message","signal","Command","Command","resolveTeamId","Command","Command","Command"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/program.ts","../src/commands/attachment.ts","../src/api/client.ts","../src/config.ts","../src/context.ts","../src/commands/auth.ts","../src/output.ts","../src/prompt.ts","../src/commands/item.ts","../src/resolve.ts","../src/commands/mcp.ts","../src/version.ts","../src/commands/project.ts","../src/commands/run.ts","../src/commands/runner.ts","../src/runner/client.ts","../src/runner/config.ts","../src/runner/workspace.ts","../src/runner/types.ts","../src/runner/execute.ts","../src/runner/log.ts","../src/runner/process.ts","../src/runner/harness/claude.ts","../src/runner/harness/codex.ts","../src/runner/harness/opencode.ts","../src/runner/harness/index.ts","../src/runner/service.ts","../src/runner/loop.ts","../src/runner/floor.ts","../src/runner/supervisor.ts","../src/commands/sprint.ts","../src/commands/wiki.ts","../src/index.ts"],"sourcesContent":["/**\n * Exit codes are part of the CLI's contract (03-API-MCP-CLI.md §4): a script or an agent\n * decides what to do next from the code alone, without parsing prose. 3 (conflict) is the\n * one worth acting on - refetch and retry with the fresh version - which is why it is\n * distinct from 2 (the request was wrong and retrying it will fail again).\n */\nexport const ExitCode = {\n Ok: 0,\n Error: 1,\n Validation: 2,\n Conflict: 3,\n NotFound: 4,\n Auth: 5,\n} as const\n\nexport type ExitCodeValue = (typeof ExitCode)[keyof typeof ExitCode]\n\n/** RFC 9457 problem+json, as the API emits it. */\nexport interface ProblemDetails {\n type?: string\n title?: string\n status?: number\n detail?: string\n errors?: Record<string, string[]>\n}\n\nexport class CliError extends Error {\n readonly exitCode: ExitCodeValue\n readonly problem: ProblemDetails | undefined\n\n constructor(message: string, exitCode: ExitCodeValue = ExitCode.Error, problem?: ProblemDetails) {\n super(message)\n this.name = 'CliError'\n this.exitCode = exitCode\n this.problem = problem\n }\n}\n\nexport function exitCodeForStatus(status: number): ExitCodeValue {\n if (status === 401) return ExitCode.Auth\n if (status === 403) return ExitCode.Auth\n if (status === 404) return ExitCode.NotFound\n if (status === 409) return ExitCode.Conflict\n if (status >= 400 && status < 500) return ExitCode.Validation\n return ExitCode.Error\n}\n\n/** The human rendering of a failure: the problem title, then each field error. */\nexport function formatProblem(problem: ProblemDetails | undefined, fallback: string): string {\n const lines: string[] = [problem?.title?.trim() || fallback]\n if (problem?.detail && problem.detail !== problem.title) lines.push(problem.detail)\n for (const [field, messages] of Object.entries(problem?.errors ?? {})) {\n for (const message of messages) lines.push(` ${field}: ${message}`)\n }\n return lines.join('\\n')\n}\n","import { Command } from 'commander'\nimport { attachmentCommand } from './commands/attachment.js'\nimport { authCommand } from './commands/auth.js'\nimport { itemCommand } from './commands/item.js'\nimport { mcpCommand } from './commands/mcp.js'\nimport { projectCommand } from './commands/project.js'\nimport { runCommand } from './commands/run.js'\nimport { runnerCommand } from './commands/runner.js'\nimport { sprintCommand } from './commands/sprint.js'\nimport { wikiCommand } from './commands/wiki.js'\nimport type { GlobalOptions } from './context.js'\nimport { version } from './version.js'\n\nexport function createProgram(): Command {\n const program = new Command('aictiq')\n .description('Aictiq from the command line, for people and for agents')\n .version(version, '-v, --version')\n .option('--url <url>', 'Aictiq base URL (overrides AICTIQ_URL and the config file)')\n .option('--token <token>', 'Personal access token (overrides AICTIQ_TOKEN)')\n .option('--org <slug>', 'Organization slug (overrides AICTIQ_ORG)')\n .option('--json', 'Print machine-readable JSON instead of a table')\n // Subcommands read the globals lazily: commander parses the root options before it\n // hands control to the subcommand's action, so this closure always sees them.\n .showHelpAfterError()\n\n const globals = () => program.opts<GlobalOptions>()\n\n program.addCommand(authCommand(globals))\n program.addCommand(attachmentCommand(globals))\n program.addCommand(projectCommand(globals))\n program.addCommand(itemCommand(globals))\n program.addCommand(sprintCommand(globals))\n program.addCommand(wikiCommand(globals))\n program.addCommand(runCommand(globals))\n program.addCommand(mcpCommand(globals))\n program.addCommand(runnerCommand(globals))\n\n return program\n}\n","import { writeFile } from 'node:fs/promises'\nimport { Command } from 'commander'\nimport { createContext } from '../context.js'\nimport type { GlobalOptions } from '../context.js'\n\n/** Attachment bytes are intentionally written verbatim: agents may fetch screenshots, logs,\n * PDFs or archives, and formatting them would corrupt every type except text. */\nexport function attachmentCommand(globals: () => GlobalOptions): Command {\n const attachment = new Command('attachment').description('Download an attachment')\n attachment\n .command('get')\n .description('Write an attachment to stdout, or to --output')\n .argument('<id>', 'Attachment UUID')\n .option('-o, --output <path>', 'Write to this path instead of stdout')\n .action(async (id: string, options: { output?: string }) => {\n const ctx = createContext(globals())\n const bytes = await ctx.client.download(\n '/api/v1/orgs/{orgSlug}/attachments/{attachmentId}/download',\n { path: { orgSlug: await ctx.org(), attachmentId: id } },\n )\n if (options.output) {\n await writeFile(options.output, bytes, { mode: 0o600 })\n return\n }\n process.stdout.write(bytes)\n })\n return attachment\n}\n","import { CliError, ExitCode, exitCodeForStatus, formatProblem } from '../errors.js'\nimport type { ProblemDetails } from '../errors.js'\nimport type { paths } from './schema.js'\n\nexport type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete'\n\n/** The documented routes that support a given method - a typo in a path is a type error. */\nexport type PathFor<M extends HttpMethod> = {\n [P in keyof paths]: paths[P] extends { [K in M]: object } ? P : never\n}[keyof paths]\n\ntype Operation<P extends keyof paths, M extends HttpMethod> = paths[P] extends {\n [K in M]: infer O\n}\n ? O\n : never\n\n/**\n * A C# record's optional members are nullable rather than absent, and the OpenAPI document\n * says nothing about which are required, so every documented property comes through as\n * required-and-nullable. `Partial` is the honest reading: omitting a field is what the API\n * treats as \"not mentioned\". Excess-property checking still applies, so a renamed or\n * dropped field is a compile error here - which is the point of generating these at all.\n */\ntype Loosen<B> = B extends object ? Partial<B> : B\n\n/**\n * The request body the API documents for this route. Response bodies are not in the\n * OpenAPI document yet (the endpoints return untyped `IResult`), so\n * callers name the response shape themselves from `views.ts`.\n */\nexport type BodyFor<P extends PathFor<M>, M extends HttpMethod> =\n Operation<P, M> extends { requestBody: { content: { 'application/json': infer B } } }\n ? Loosen<B>\n : Operation<P, M> extends { requestBody?: { content: { 'application/json': infer B } } }\n ? Loosen<B> | undefined\n : undefined\n\nexport interface RequestOptions<P extends PathFor<M>, M extends HttpMethod> {\n path?: Record<string, string>\n query?: Record<string, string | number | boolean | undefined>\n body?: BodyFor<P, M>\n}\n\nexport interface ClientOptions {\n baseUrl: string\n token: string\n fetch?: typeof fetch\n}\n\n/**\n * The whole HTTP surface of the CLI. Bearer credentials are not subject to the cookie\n * CSRF rule, so `X-Aictiq-Request` is deliberately absent: sending it on a bearer request\n * would be harmless but misleading about which transport authenticated the call.\n */\nexport class AictiqClient {\n readonly baseUrl: string\n private readonly token: string\n private readonly doFetch: typeof fetch\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.token = options.token\n this.doFetch = options.fetch ?? fetch\n }\n\n async request<T, P extends PathFor<M>, M extends HttpMethod = 'get'>(\n method: M,\n path: P,\n options: RequestOptions<P, M> = {},\n ): Promise<T> {\n const url = new URL(this.baseUrl + expand(path as string, options.path ?? {}))\n for (const [key, value] of Object.entries(options.query ?? {})) {\n if (value !== undefined && value !== '') url.searchParams.set(key, String(value))\n }\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.token}`,\n Accept: 'application/json',\n 'User-Agent': 'aictiq-cli',\n }\n if (options.body !== undefined) headers['Content-Type'] = 'application/json'\n\n let response: Response\n try {\n response = await this.doFetch(url, {\n method: method.toUpperCase(),\n headers,\n ...(options.body === undefined ? {} : { body: JSON.stringify(options.body) }),\n })\n } catch (cause) {\n throw new CliError(\n `Cannot reach ${this.baseUrl}: ${cause instanceof Error ? cause.message : String(cause)}`,\n ExitCode.Error,\n )\n }\n\n if (response.status === 204) return undefined as T\n const text = await response.text()\n const payload: unknown = text.length === 0 ? undefined : safeJson(text)\n\n if (!response.ok) {\n const problem = isProblem(payload) ? payload : undefined\n throw new CliError(\n formatProblem(problem, `${response.status} ${response.statusText}`),\n exitCodeForStatus(response.status),\n problem,\n )\n }\n return payload as T\n }\n\n /**\n * Downloads an authenticated response without trying to interpret it as JSON. Attachments\n * deliberately use the normal API route (rather than a presigned object-store URL), so a\n * PAT's organization and project visibility checks remain in force.\n */\n async download<P extends PathFor<'get'>>(\n path: P,\n options: RequestOptions<P, 'get'> = {},\n ): Promise<Uint8Array> {\n const url = new URL(this.baseUrl + expand(path as string, options.path ?? {}))\n for (const [key, value] of Object.entries(options.query ?? {})) {\n if (value !== undefined && value !== '') url.searchParams.set(key, String(value))\n }\n let response: Response\n try {\n response = await this.doFetch(url, {\n method: 'GET',\n headers: {\n Authorization: `Bearer ${this.token}`,\n Accept: '*/*',\n 'User-Agent': 'aictiq-cli',\n },\n })\n } catch (cause) {\n throw new CliError(\n `Cannot reach ${this.baseUrl}: ${cause instanceof Error ? cause.message : String(cause)}`,\n ExitCode.Error,\n )\n }\n if (!response.ok) {\n const text = await response.text()\n const payload: unknown = text.length === 0 ? undefined : safeJson(text)\n const problem = isProblem(payload) ? payload : undefined\n throw new CliError(\n formatProblem(problem, `${response.status} ${response.statusText}`),\n exitCodeForStatus(response.status),\n problem,\n )\n }\n return new Uint8Array(await response.arrayBuffer())\n }\n}\n\n/** Fills `{name}` segments; a missing value is a programming error, not a user one. */\nfunction expand(template: string, values: Record<string, string>): string {\n return template.replace(/\\{(\\w+)\\}/g, (_match, name: string) => {\n const value = values[name]\n if (value === undefined) throw new Error(`Missing path parameter \"${name}\" for ${template}`)\n return encodeURIComponent(value)\n })\n}\n\nfunction safeJson(text: string): unknown {\n try {\n return JSON.parse(text)\n } catch {\n return { title: text.slice(0, 500) }\n }\n}\n\nfunction isProblem(value: unknown): value is ProblemDetails {\n return typeof value === 'object' && value !== null\n}\n","import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\n\n/**\n * What `aictiq auth login` writes. The token is a personal access token - the same\n * credential the REST API and `/mcp` take - so the file is written 0600 and the\n * directory 0700. There is deliberately no OS keychain integration: keytar and its\n * successors ship prebuilt native binaries, and a CLI whose job is to hold a bearer\n * token should not widen its install surface that far. See docs/cli.md.\n */\nexport interface StoredConfig {\n url?: string\n token?: string\n org?: string\n}\n\nexport function configPath(env: NodeJS.ProcessEnv = process.env): string {\n const base = env.AICTIQ_CONFIG_HOME ?? env.XDG_CONFIG_HOME ?? join(homedir(), '.config')\n return join(base, 'aictiq', 'config.json')\n}\n\nexport function readConfig(path = configPath()): StoredConfig {\n if (!existsSync(path)) return {}\n try {\n const parsed: unknown = JSON.parse(readFileSync(path, 'utf8'))\n if (typeof parsed !== 'object' || parsed === null) return {}\n const { url, token, org } = parsed as Record<string, unknown>\n return {\n ...(typeof url === 'string' ? { url } : {}),\n ...(typeof token === 'string' ? { token } : {}),\n ...(typeof org === 'string' ? { org } : {}),\n }\n } catch {\n // A hand-edited or truncated file must not make every command fail; the caller\n // falls back to flags and environment, which is what an unconfigured host does.\n return {}\n }\n}\n\nexport function writeConfig(config: StoredConfig, path = configPath()): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n // The mode argument only applies when the file is created, so an existing file that\n // someone widened is narrowed again explicitly.\n writeFileSync(path, `${JSON.stringify(config, null, 2)}\\n`, { mode: 0o600 })\n chmodSync(path, 0o600)\n}\n\nexport function clearConfig(path = configPath()): void {\n rmSync(path, { force: true })\n}\n","import { AictiqClient } from './api/client.js'\nimport type { OrganizationSummary } from './api/views.js'\nimport { readConfig } from './config.js'\nimport type { StoredConfig } from './config.js'\nimport { CliError, ExitCode } from './errors.js'\n\nexport interface GlobalOptions {\n url?: string\n token?: string\n org?: string\n json?: boolean\n}\n\n/**\n * Flags beat environment beats config file - the precedence in 03-API-MCP-CLI.md §4.\n * CI sets `AICTIQ_URL`/`AICTIQ_TOKEN` and never writes a config file; a person logs in\n * once and passes neither.\n */\nexport function resolveSettings(\n options: GlobalOptions,\n env: NodeJS.ProcessEnv = process.env,\n stored: StoredConfig = readConfig(),\n): StoredConfig {\n return {\n url: options.url ?? env.AICTIQ_URL ?? stored.url,\n token: options.token ?? env.AICTIQ_TOKEN ?? stored.token,\n org: options.org ?? env.AICTIQ_ORG ?? stored.org,\n }\n}\n\nexport interface Context {\n client: AictiqClient\n /** The organization slug every scoped route needs; resolved lazily. */\n org(): Promise<string>\n json: boolean\n}\n\nexport function createContext(options: GlobalOptions): Context {\n const settings = resolveSettings(options)\n if (!settings.url) {\n throw new CliError('No Aictiq URL. Run `aictiq auth login --url <url>`.', ExitCode.Auth)\n }\n if (!settings.token) {\n throw new CliError('No personal access token. Run `aictiq auth login`.', ExitCode.Auth)\n }\n\n const client = new AictiqClient({ baseUrl: settings.url, token: settings.token })\n let resolved: Promise<string> | undefined\n\n return {\n client,\n json: options.json === true,\n org() {\n if (settings.org) return Promise.resolve(settings.org)\n // A token bound to one organization has exactly one answer here, which is why the\n // CLI can be run with no org configured at all. Anything else has to be told which.\n resolved ??= resolveOrg(client)\n return resolved\n },\n }\n}\n\nasync function resolveOrg(client: AictiqClient): Promise<string> {\n const orgs = await client.request<OrganizationSummary[], '/api/v1/orgs', 'get'>(\n 'get',\n '/api/v1/orgs',\n )\n if (orgs.length === 0) {\n throw new CliError('This account is not a member of any organization.', ExitCode.NotFound)\n }\n if (orgs.length > 1) {\n const slugs = orgs.map((o) => o.slug).join(', ')\n throw new CliError(\n `This token can see several organizations (${slugs}). Pass --org, set AICTIQ_ORG, or run \\`aictiq auth login --org <slug>\\`.`,\n ExitCode.Validation,\n )\n }\n return orgs[0]!.slug\n}\n","import { Command } from 'commander'\nimport { AictiqClient } from '../api/client.js'\nimport type { OrganizationSummary, SessionResponse } from '../api/views.js'\nimport { clearConfig, configPath, readConfig, writeConfig } from '../config.js'\nimport { resolveSettings } from '../context.js'\nimport type { GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { print, printJson, renderFields, renderTable } from '../output.js'\nimport { promptSecret } from '../prompt.js'\n\nexport function authCommand(globals: () => GlobalOptions): Command {\n const auth = new Command('auth').description(\n 'Sign in to a Aictiq instance and inspect the session',\n )\n\n auth\n .command('login')\n .description('Store a personal access token for an instance')\n .option('--url <url>', 'Base URL of the Aictiq instance')\n .option('--token <token>', 'Personal access token (aiq_…); read from stdin when omitted')\n .option('--org <slug>', 'Default organization slug for scoped commands')\n .action(async (options: { url?: string; token?: string; org?: string }) => {\n const global = globals()\n const url = options.url ?? global.url ?? process.env.AICTIQ_URL ?? readConfig().url\n if (!url)\n throw new CliError(\n 'Pass --url with the address of your Aictiq instance.',\n ExitCode.Validation,\n )\n\n const token =\n options.token ??\n global.token ??\n process.env.AICTIQ_TOKEN ??\n (await promptSecret('Personal access token: '))\n if (!token) throw new CliError('No token supplied.', ExitCode.Validation)\n\n // Verify before writing: a stored token that never worked is worse than no token,\n // because every later command fails somewhere far from the cause.\n const client = new AictiqClient({ baseUrl: url, token })\n const session = await client.request<SessionResponse, '/api/v1/auth/session', 'get'>(\n 'get',\n '/api/v1/auth/session',\n )\n const orgs = await client.request<OrganizationSummary[], '/api/v1/orgs', 'get'>(\n 'get',\n '/api/v1/orgs',\n )\n const org = options.org ?? global.org ?? (orgs.length === 1 ? orgs[0]!.slug : undefined)\n\n writeConfig({ url: url.replace(/\\/+$/, ''), token, ...(org ? { org } : {}) })\n\n if (global.json) {\n printJson({\n url,\n org: org ?? null,\n user: session,\n organizations: orgs,\n configPath: configPath(),\n })\n return\n }\n print(`Signed in to ${url} as ${session.email}.`)\n if (org) print(`Default organization: ${org}`)\n else if (orgs.length > 1)\n print(`Several organizations are visible; pass --org next time or set AICTIQ_ORG.`)\n print(`Token stored in ${configPath()} (0600).`)\n })\n\n auth\n .command('status')\n .description('Show the configured instance, identity and organizations')\n .action(async () => {\n const global = globals()\n const settings = resolveSettings(global)\n if (!settings.url || !settings.token) {\n if (global.json) {\n printJson({ authenticated: false, url: settings.url ?? null, configPath: configPath() })\n return\n }\n throw new CliError('Not signed in. Run `aictiq auth login --url <url>`.', ExitCode.Auth)\n }\n\n const client = new AictiqClient({ baseUrl: settings.url, token: settings.token })\n const session = await client.request<SessionResponse, '/api/v1/auth/session', 'get'>(\n 'get',\n '/api/v1/auth/session',\n )\n const orgs = await client.request<OrganizationSummary[], '/api/v1/orgs', 'get'>(\n 'get',\n '/api/v1/orgs',\n )\n\n if (global.json) {\n printJson({\n authenticated: true,\n url: settings.url,\n org: settings.org ?? null,\n user: session,\n organizations: orgs,\n configPath: configPath(),\n })\n return\n }\n print(\n renderFields([\n ['URL', settings.url],\n ['User', `${session.email} (${session.id})`],\n ['Organization', settings.org ?? '(not set)'],\n ['Config', configPath()],\n ]),\n )\n if (orgs.length > 0) {\n print('')\n print(\n renderTable(orgs, [\n { header: 'SLUG', value: (o) => o.slug },\n { header: 'NAME', value: (o) => o.name },\n { header: 'ROLE', value: (o) => o.role },\n ]),\n )\n }\n })\n\n auth\n .command('logout')\n .description('Delete the stored token')\n .action(() => {\n clearConfig()\n if (globals().json) printJson({ removed: configPath() })\n else print(`Removed ${configPath()}.`)\n })\n\n return auth\n}\n","export interface Column<T> {\n header: string\n value: (row: T) => string\n /** Right-align numeric columns so magnitudes line up. */\n align?: 'left' | 'right'\n}\n\n/**\n * Every command prints either `--json` (the machine contract) or a table (the human one).\n * The table is plain text with two spaces between columns: no colour, no box drawing, and\n * no truncation of the last column, so `| grep` and `| cut` stay useful.\n */\nexport function renderTable<T>(rows: readonly T[], columns: readonly Column<T>[]): string {\n const cells = rows.map((row) => columns.map((column) => column.value(row) ?? ''))\n const widths = columns.map((column, index) =>\n Math.max(column.header.length, ...cells.map((row) => row[index]?.length ?? 0), 0),\n )\n const line = (values: readonly string[]) =>\n values\n .map((value, index) =>\n index === values.length - 1\n ? columns[index]?.align === 'right'\n ? value.padStart(widths[index]!)\n : value\n : columns[index]?.align === 'right'\n ? value.padStart(widths[index]!)\n : value.padEnd(widths[index]!),\n )\n .join(' ')\n .trimEnd()\n\n return [line(columns.map((c) => c.header)), ...cells.map(line)].join('\\n')\n}\n\n/** Key/value block for a single record, used by the `view` commands. */\nexport function renderFields(fields: readonly (readonly [string, string | undefined])[]): string {\n const present = fields.filter((f): f is [string, string] => f[1] !== undefined && f[1] !== '')\n const width = Math.max(0, ...present.map(([label]) => label.length))\n return present.map(([label, value]) => `${label.padEnd(width)} ${value}`).join('\\n')\n}\n\nexport function print(text: string): void {\n process.stdout.write(text.endsWith('\\n') ? text : `${text}\\n`)\n}\n\nexport function printJson(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`)\n}\n\nexport function formatDate(value: string | null | undefined): string {\n if (!value) return ''\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? String(value) : date.toISOString().slice(0, 10)\n}\n\nexport function formatNumber(value: number | null | undefined): string {\n return value === null || value === undefined ? '' : String(value)\n}\n\n/** Date and time to the second, UTC - a run's timings are minutes apart, not days. */\nexport function formatDateTime(value: string | null | undefined): string {\n if (!value) return ''\n const date = new Date(value)\n return Number.isNaN(date.getTime())\n ? String(value)\n : `${date.toISOString().slice(0, 19).replace('T', ' ')}Z`\n}\n","import { createInterface } from 'node:readline'\n\n/**\n * Reads a secret from the terminal without echoing it, or from a pipe when stdin is not a\n * TTY (`echo $TOKEN | aictiq auth login`), which is how CI supplies one without putting\n * the token on a command line that `ps` would show.\n */\nexport async function promptSecret(question: string): Promise<string> {\n if (!process.stdin.isTTY) {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk))\n return Buffer.concat(chunks).toString('utf8').trim()\n }\n\n const rl = createInterface({ input: process.stdin, output: process.stdout, terminal: true })\n try {\n process.stdout.write(question)\n const muted = rl as unknown as { output: NodeJS.WriteStream; _writeToOutput?: unknown }\n const original = muted.output.write.bind(muted.output)\n muted.output.write = (() => true) as typeof muted.output.write\n const answer = await new Promise<string>((resolve) => rl.question('', resolve))\n muted.output.write = original\n process.stdout.write('\\n')\n return answer.trim()\n } finally {\n rl.close()\n }\n}\n","import { Command, Option } from 'commander'\nimport type { CommentView, ItemLinkView, PagedResult, WorkItemView } from '../api/views.js'\nimport type { WorkItemPriority, WorkItemType } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { formatDate, formatNumber, print, printJson, renderFields, renderTable } from '../output.js'\nimport {\n branchName,\n findState,\n getItem,\n getLabels,\n getTeams,\n getWorkflow,\n normalizeItemKey,\n projectKeyOf,\n readBody,\n resolveLabelIds,\n} from '../resolve.js'\n\nconst types: WorkItemType[] = ['epic', 'feature', 'story', 'task', 'bug']\nconst priorities: WorkItemPriority[] = ['none', 'low', 'medium', 'high', 'urgent']\n\nexport function itemCommand(globals: () => GlobalOptions): Command {\n const item = new Command('item').description('Work items')\n\n item\n .command('list')\n .description('List work items in a project')\n .requiredOption('-p, --project <key>', 'Project key, e.g. ACME')\n .option(\n '-f, --filter <expression>',\n 'Item filter, e.g. \"state:active assignee:@me label:backend\"',\n )\n .option('-q, --query <text>', 'Full-text search within the project')\n .option('-s, --sort <field>', 'Sort expression accepted by the API')\n .option('--page <n>', 'Page number', '1')\n .option('--page-size <n>', 'Items per page (max 100)', '25')\n .action(\n async (options: {\n project: string\n filter?: string\n query?: string\n sort?: string\n page: string\n pageSize: string\n }) => {\n const ctx = createContext(globals())\n const page = await ctx.client.request<\n PagedResult<WorkItemView>,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items', {\n path: { orgSlug: await ctx.org(), projectKey: options.project.toUpperCase() },\n query: {\n filter: options.filter,\n q: options.query,\n sort: options.sort,\n page: options.page,\n pageSize: options.pageSize,\n },\n })\n\n if (ctx.json) return printJson(page)\n if (page.items.length === 0) return print('No items match.')\n print(\n renderTable(page.items, [\n { header: 'KEY', value: (i) => i.key },\n { header: 'TYPE', value: (i) => i.type },\n { header: 'STATE', value: (i) => i.stateCategory },\n { header: 'PRIORITY', value: (i) => i.priority },\n { header: 'PTS', value: (i) => formatNumber(i.points), align: 'right' },\n { header: 'TITLE', value: (i) => i.title },\n ]),\n )\n print('')\n print(`Page ${page.page} of ${Math.max(1, page.totalPages)} · ${page.totalCount} items`)\n },\n )\n\n item\n .command('view')\n .description('Show one work item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--comments', 'Include the comment thread')\n .option('--links', 'Include external links')\n .action(async (key: string, options: { comments?: boolean; links?: boolean }) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const itemKey = normalizeItemKey(key)\n const found = await getItem(ctx, itemKey)\n const comments = options.comments ? await listComments(ctx, orgSlug, itemKey) : undefined\n const links = options.links ? await listLinks(ctx, orgSlug, itemKey) : undefined\n\n if (ctx.json) {\n return printJson({\n ...found,\n ...(comments ? { comments } : {}),\n ...(links ? { links } : {}),\n })\n }\n\n const state = await stateName(ctx, found)\n print(`${found.key} ${found.title}`)\n print('')\n print(\n renderFields([\n ['Type', found.type],\n ['State', `${state} (${found.stateCategory})`],\n ['Priority', found.priority],\n ['Assignee', found.assigneeId ?? '(unassigned)'],\n ['Claimed by', found.claimedBy ?? undefined],\n ['Points', formatNumber(found.points)],\n ['Remaining hours', formatNumber(found.remainingHours)],\n ['Labels', found.labels.map((l) => l.name).join(', ')],\n ['Blocked', found.blocked ? 'yes' : ''],\n ['Updated', formatDate(found.updatedAt)],\n ['Version', String(found.version)],\n ]),\n )\n if (found.descriptionMarkdown.trim().length > 0) {\n print('')\n print(found.descriptionMarkdown.trim())\n }\n if (links && links.length > 0) {\n print('')\n print(\n renderTable(links, [\n { header: 'KIND', value: (l) => l.kind },\n { header: 'URL', value: (l) => l.url },\n { header: 'TITLE', value: (l) => l.title ?? '' },\n ]),\n )\n }\n if (comments) {\n print('')\n for (const comment of comments) {\n if (comment.deletedAt) continue\n print(\n `--- ${comment.author.displayName}${comment.author.isAgent ? ' [agent]' : ''} · ${formatDate(comment.createdAt)}`,\n )\n print(comment.bodyMarkdown.trim())\n print('')\n }\n }\n })\n\n item\n .command('create')\n .description('Create a work item')\n .requiredOption('-p, --project <key>', 'Project key, e.g. ACME')\n .addOption(new Option('-t, --type <type>', 'Item type').choices(types).default('task'))\n .requiredOption('--title <title>', 'Item title')\n .option('-m, --body <markdown>', 'Description in Markdown')\n .option('--body-file <path>', 'Read the description from a file, or - for stdin')\n .addOption(new Option('--priority <priority>', 'Priority').choices(priorities))\n .option('--parent <key>', 'Parent item key, e.g. ACME-100')\n .option('--team <key>', 'Team key or name')\n .option('--labels <names>', 'Comma-separated label names')\n .option('--points <n>', 'Story points')\n .option('--estimate <hours>', 'Original estimate in hours')\n .action(\n async (options: {\n project: string\n type: WorkItemType\n title: string\n body?: string\n bodyFile?: string\n priority?: WorkItemPriority\n parent?: string\n team?: string\n labels?: string\n points?: string\n estimate?: string\n }) => {\n const ctx = createContext(globals())\n const projectKey = options.project.toUpperCase()\n const description = await readBody(options.body, options.bodyFile)\n const parent = options.parent ? await getItem(ctx, options.parent) : undefined\n const teamId = options.team ? await resolveTeamId(ctx, projectKey, options.team) : undefined\n const labelIds = options.labels\n ? resolveLabelIds(options.labels, await getLabels(ctx, projectKey), [])\n : undefined\n\n const created = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items', {\n path: { orgSlug: await ctx.org(), projectKey },\n body: {\n type: options.type,\n title: options.title,\n ...(description === undefined ? {} : { descriptionMarkdown: description }),\n ...(options.priority ? { priority: options.priority } : {}),\n ...(parent ? { parentId: parent.id } : {}),\n ...(teamId ? { teamId } : {}),\n ...(labelIds ? { labelIds } : {}),\n ...(options.points ? { points: number(options.points, 'points') } : {}),\n ...(options.estimate ? { estimateHours: number(options.estimate, 'estimate') } : {}),\n },\n })\n\n if (ctx.json) return printJson(created)\n print(`${created.key} ${created.title}`)\n },\n )\n\n item\n .command('update')\n .description('Update a work item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--title <title>', 'New title')\n .option('-m, --body <markdown>', 'New description in Markdown')\n .option('--body-file <path>', 'Read the description from a file, or - for stdin')\n .addOption(new Option('--priority <priority>', 'Priority').choices(priorities))\n .addOption(new Option('--type <type>', 'Item type').choices(types))\n .option('--assignee <userId>', 'Assignee user id, or \"none\" to unassign')\n .option('--labels <names>', 'Label names: a plain list replaces, +name/-name adjusts')\n .option('--points <n>', 'Story points')\n .option('--estimate <hours>', 'Original estimate in hours')\n .option('--remaining <hours>', 'Remaining hours')\n .option('--version <n>', 'Expected version; read from the item when omitted')\n .action(\n async (\n key: string,\n options: {\n title?: string\n body?: string\n bodyFile?: string\n priority?: WorkItemPriority\n type?: WorkItemType\n assignee?: string\n labels?: string\n points?: string\n estimate?: string\n remaining?: string\n version?: string\n },\n ) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n const current = await getItem(ctx, itemKey)\n const description = await readBody(options.body, options.bodyFile)\n const labelIds = options.labels\n ? resolveLabelIds(\n options.labels,\n await getLabels(ctx, projectKeyOf(itemKey)),\n current.labels,\n )\n : undefined\n\n const updated = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}',\n 'patch'\n >('patch', '/api/v1/orgs/{orgSlug}/items/{itemKey}', {\n path: { orgSlug: await ctx.org(), itemKey },\n body: {\n // PATCH is an absolute assignment for the nullable fields - an omitted\n // `parentId` unparents the item, an omitted `assigneeId` unassigns it. So the\n // body starts from what the item currently holds and the flags overwrite it;\n // otherwise `--priority high` would quietly detach a story from its feature.\n type: current.type,\n title: current.title,\n descriptionMarkdown: current.descriptionMarkdown,\n stateId: current.stateId,\n priority: current.priority,\n assigneeId: current.assigneeId,\n teamId: current.teamId,\n parentId: current.parentId,\n points: current.points,\n estimateHours: current.estimateHours,\n remainingHours: current.remainingHours,\n completedHours: current.completedHours,\n dueDate: current.dueDate,\n version: options.version ? number(options.version, 'version') : current.version,\n ...(options.title === undefined ? {} : { title: options.title }),\n ...(description === undefined ? {} : { descriptionMarkdown: description }),\n ...(options.priority ? { priority: options.priority } : {}),\n ...(options.type ? { type: options.type } : {}),\n ...(options.assignee === undefined\n ? {}\n : { assigneeId: options.assignee === 'none' ? null : options.assignee }),\n ...(labelIds ? { labelIds } : {}),\n ...(options.points ? { points: number(options.points, 'points') } : {}),\n ...(options.estimate ? { estimateHours: number(options.estimate, 'estimate') } : {}),\n ...(options.remaining\n ? { remainingHours: number(options.remaining, 'remaining') }\n : {}),\n },\n })\n\n if (ctx.json) return printJson(updated)\n print(`${updated.key} updated (version ${updated.version}).`)\n },\n )\n\n item\n .command('move')\n .description('Move an item: to another workflow state, sprint, parent or backlog rank')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--state <name>', 'Workflow state to transition to, e.g. \"In Review\"')\n .option('--sprint <sprintId>', 'Sprint id, or \"none\" to return it to the backlog')\n .option('--parent <key>', 'New parent item key')\n .option('--after <key>', 'Rank it directly after this item')\n .option('--before <key>', 'Rank it directly before this item')\n .option('--version <n>', 'Expected version; read from the item when omitted')\n .action(\n async (\n key: string,\n options: {\n state?: string\n sprint?: string\n parent?: string\n after?: string\n before?: string\n version?: string\n },\n ) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const itemKey = normalizeItemKey(key)\n const current = await getItem(ctx, itemKey)\n const version = options.version ? number(options.version, 'version') : current.version\n const ranking =\n options.sprint !== undefined ||\n options.parent !== undefined ||\n options.after !== undefined ||\n options.before !== undefined\n\n if (!options.state && !ranking) {\n throw new CliError(\n 'Pass --state, or one of --sprint/--parent/--after/--before.',\n ExitCode.Validation,\n )\n }\n\n let result: WorkItemView = current\n if (options.state) {\n const workflow = await getWorkflow(ctx, projectKeyOf(itemKey))\n const state = findState(workflow, options.state)\n result = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/transition',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/transition', {\n path: { orgSlug, itemKey },\n body: { toStateId: state.id, version },\n })\n }\n if (ranking) {\n result = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/move',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/move', {\n path: { orgSlug, itemKey },\n body: {\n // The transition above already spent the version it read.\n version: options.state ? result.version : version,\n ...(options.sprint === undefined\n ? {}\n : options.sprint === 'none'\n ? { removeSprint: true }\n : { sprintId: options.sprint }),\n ...(options.parent === undefined\n ? {}\n : { parentKey: normalizeItemKey(options.parent) }),\n ...(options.after === undefined ? {} : { afterKey: normalizeItemKey(options.after) }),\n ...(options.before === undefined\n ? {}\n : { beforeKey: normalizeItemKey(options.before) }),\n },\n })\n }\n\n if (ctx.json) return printJson(result)\n print(`${result.key} moved (version ${result.version}).`)\n },\n )\n\n // Claim is the compare-and-swap: it needs the version it expects to find, so that two\n // agents racing for the same item produce one claim and one 409 (exit code 3). Release\n // and heartbeat act on the claim that already exists and carry no version.\n item\n .command('claim')\n .description('Claim an item for the authenticated identity (compare-and-swap)')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--version <n>', 'Expected version; read from the item when omitted')\n .action(async (key: string, options: { version?: string }) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n const version = options.version\n ? number(options.version, 'version')\n : (await getItem(ctx, itemKey)).version\n const result = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/claim',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/claim', {\n path: { orgSlug: await ctx.org(), itemKey },\n body: { version },\n })\n if (ctx.json) return printJson(result)\n print(`${itemKey} claimed.`)\n })\n\n item\n .command('release')\n .description('Release a claim you hold')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .action(async (key: string) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n // Release and heartbeat answer 204: they act on a claim that already exists and\n // have nothing to return, so --json reports what happened rather than an empty body.\n await ctx.client.request<void, '/api/v1/orgs/{orgSlug}/items/{itemKey}/release', 'post'>(\n 'post',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/release',\n { path: { orgSlug: await ctx.org(), itemKey } },\n )\n if (ctx.json) return printJson({ key: itemKey, released: true })\n print(`${itemKey} released.`)\n })\n\n item\n .command('heartbeat')\n .description('Refresh the claim heartbeat so the claim does not go stale')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .action(async (key: string) => {\n const ctx = createContext(globals())\n const itemKey = normalizeItemKey(key)\n await ctx.client.request<void, '/api/v1/orgs/{orgSlug}/items/{itemKey}/heartbeat', 'post'>(\n 'post',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/heartbeat',\n { path: { orgSlug: await ctx.org(), itemKey } },\n )\n if (ctx.json) return printJson({ key: itemKey, heartbeat: new Date().toISOString() })\n print(`${itemKey} heartbeat sent.`)\n })\n\n item\n .command('comment')\n .description('Add a comment to an item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('-m, --body <markdown>', 'Comment body in Markdown')\n .option('--body-file <path>', 'Read the body from a file, or - for stdin')\n .action(async (key: string, options: { body?: string; bodyFile?: string }) => {\n const ctx = createContext(globals())\n const body = await readBody(options.body, options.bodyFile)\n if (!body || body.trim().length === 0) {\n throw new CliError('Pass -m \"text\" or --body-file <path>.', ExitCode.Validation)\n }\n const comment = await ctx.client.request<\n CommentView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments', {\n path: { orgSlug: await ctx.org(), itemKey: normalizeItemKey(key) },\n body: { bodyMarkdown: body },\n })\n\n if (ctx.json) return printJson(comment)\n print(`Comment added to ${normalizeItemKey(key)}.`)\n })\n\n item\n .command('subtask')\n .description('Create a child item under an existing one')\n .argument('<key>', 'Parent item key, e.g. ACME-123')\n .requiredOption('--title <title>', 'Subtask title')\n .addOption(new Option('-t, --type <type>', 'Item type').choices(types).default('task'))\n .option('-m, --body <markdown>', 'Description in Markdown')\n .option('--body-file <path>', 'Read the description from a file, or - for stdin')\n .option('--estimate <hours>', 'Original estimate in hours')\n .action(\n async (\n key: string,\n options: {\n title: string\n type: WorkItemType\n body?: string\n bodyFile?: string\n estimate?: string\n },\n ) => {\n const ctx = createContext(globals())\n const parentKey = normalizeItemKey(key)\n const parent = await getItem(ctx, parentKey)\n const description = await readBody(options.body, options.bodyFile)\n\n const created = await ctx.client.request<\n WorkItemView,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/items', {\n path: { orgSlug: await ctx.org(), projectKey: projectKeyOf(parentKey) },\n body: {\n type: options.type,\n title: options.title,\n parentId: parent.id,\n ...(parent.teamId ? { teamId: parent.teamId } : {}),\n ...(description === undefined ? {} : { descriptionMarkdown: description }),\n ...(options.estimate ? { estimateHours: number(options.estimate, 'estimate') } : {}),\n },\n })\n\n if (ctx.json) return printJson(created)\n print(`${created.key} ${created.title}`)\n },\n )\n\n item\n .command('link')\n .description('Attach an external link to an item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .option('--url <url>', 'Any public URL')\n .option('--pr <url>', 'Pull request URL (an alias for --url)')\n .action(async (key: string, options: { url?: string; pr?: string }) => {\n const ctx = createContext(globals())\n const url = options.url ?? options.pr\n if (!url) throw new CliError('Pass --url <url> or --pr <url>.', ExitCode.Validation)\n const link = await ctx.client.request<\n ItemLinkView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/links',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/links', {\n path: { orgSlug: await ctx.org(), itemKey: normalizeItemKey(key) },\n body: { url },\n })\n\n if (ctx.json) return printJson(link)\n print(`Linked ${link.url} to ${normalizeItemKey(key)}.`)\n })\n\n item\n .command('branch')\n .description('Print the branch name convention for an item')\n .argument('<key>', 'Item key, e.g. ACME-123')\n .action(async (key: string) => {\n const ctx = createContext(globals())\n const found = await getItem(ctx, key)\n const branch = branchName(found)\n if (ctx.json) return printJson({ key: found.key, branch })\n print(branch)\n })\n\n return item\n}\n\nasync function listComments(ctx: Context, orgSlug: string, itemKey: string) {\n const page = await ctx.client.request<\n PagedResult<CommentView>,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/items/{itemKey}/comments', {\n path: { orgSlug, itemKey },\n query: { pageSize: 100 },\n })\n return page.items\n}\n\nasync function listLinks(ctx: Context, orgSlug: string, itemKey: string) {\n return ctx.client.request<ItemLinkView[], '/api/v1/orgs/{orgSlug}/items/{itemKey}/links', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/links',\n { path: { orgSlug, itemKey } },\n )\n}\n\nasync function stateName(ctx: Context, item: WorkItemView): Promise<string> {\n const workflow = await getWorkflow(ctx, projectKeyOf(item.key))\n return workflow.states.find((s) => s.id === item.stateId)?.name ?? item.stateCategory\n}\n\nasync function resolveTeamId(ctx: Context, projectKey: string, wanted: string): Promise<string> {\n const teams = await getTeams(ctx, projectKey)\n const needle = wanted.trim().toLowerCase()\n const team = teams.find(\n (t) => t.key.toLowerCase() === needle || t.name.toLowerCase() === needle || t.id === wanted,\n )\n if (!team) {\n throw new CliError(\n `No team \"${wanted}\" in ${projectKey}. Teams: ${teams.map((t) => t.key).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n return team.id\n}\n\nfunction number(raw: string, field: string): number {\n const parsed = Number(raw)\n if (!Number.isFinite(parsed)) {\n throw new CliError(`--${field} must be a number, got \"${raw}\".`, ExitCode.Validation)\n }\n return parsed\n}\n","import { readFileSync } from 'node:fs'\nimport type { Context } from './context.js'\nimport { CliError, ExitCode } from './errors.js'\nimport type {\n ItemLabelView,\n TeamView,\n WorkflowStateView,\n WorkflowView,\n WorkItemView,\n} from './api/views.js'\n\n/** `ACME-123` → `ACME`. Project keys are `^[A-Z][A-Z0-9]{1,9}$`, so the last dash splits. */\nexport function projectKeyOf(itemKey: string): string {\n const normalized = itemKey.trim().toUpperCase()\n const dash = normalized.lastIndexOf('-')\n if (dash <= 0) {\n throw new CliError(\n `\"${itemKey}\" is not a work item key (expected e.g. ACME-123).`,\n ExitCode.Validation,\n )\n }\n return normalized.slice(0, dash)\n}\n\nexport function normalizeItemKey(itemKey: string): string {\n return itemKey.trim().toUpperCase()\n}\n\nexport async function getWorkflow(ctx: Context, projectKey: string): Promise<WorkflowView> {\n const workflows = await ctx.client.request<\n WorkflowView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/workflows',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/workflows', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n const workflow = workflows.find((w) => w.isDefault) ?? workflows[0]\n if (!workflow) throw new CliError(`Project ${projectKey} has no workflow.`, ExitCode.NotFound)\n return workflow\n}\n\n/** Matches a state by name, case-insensitively; the error lists what was available. */\nexport function findState(workflow: WorkflowView, name: string): WorkflowStateView {\n const wanted = name.trim().toLowerCase()\n const state = workflow.states.find((s) => s.name.toLowerCase() === wanted)\n if (!state) {\n const names = workflow.states.map((s) => s.name).join(', ')\n throw new CliError(`No workflow state named \"${name}\". States: ${names}.`, ExitCode.Validation)\n }\n return state\n}\n\nexport async function getLabels(ctx: Context, projectKey: string): Promise<ItemLabelView[]> {\n return ctx.client.request<\n ItemLabelView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/labels',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/labels', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n}\n\nexport async function getTeams(ctx: Context, projectKey: string): Promise<TeamView[]> {\n return ctx.client.request<\n TeamView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/teams',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/teams', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n}\n\nexport async function getItem(ctx: Context, itemKey: string): Promise<WorkItemView> {\n return ctx.client.request<WorkItemView, '/api/v1/orgs/{orgSlug}/items/{itemKey}', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/items/{itemKey}',\n { path: { orgSlug: await ctx.org(), itemKey: normalizeItemKey(itemKey) } },\n )\n}\n\n/**\n * `--labels backend,+urgent,-stale`: a bare list replaces, `+`/`-` adjust. Mixing the two\n * is refused rather than guessed at, because \"did that clear the others?\" is not a\n * question a script should have to answer by reading the result back.\n */\nexport function resolveLabelIds(\n spec: string,\n available: readonly ItemLabelView[],\n current: readonly ItemLabelView[],\n): string[] {\n const tokens = spec\n .split(',')\n .map((t) => t.trim())\n .filter((t) => t.length > 0)\n const adjusting = tokens.some((t) => t.startsWith('+') || t.startsWith('-'))\n const replacing = tokens.some((t) => !t.startsWith('+') && !t.startsWith('-'))\n if (adjusting && replacing) {\n throw new CliError(\n 'Use either a plain label list (replaces all) or +/- adjustments, not both.',\n ExitCode.Validation,\n )\n }\n\n const byName = new Map(available.map((label) => [label.name.toLowerCase(), label]))\n const lookup = (name: string) => {\n const label = byName.get(name.toLowerCase())\n if (!label) {\n throw new CliError(\n `No label \"${name}\" in this project. Labels: ${available.map((l) => l.name).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n return label.id\n }\n\n if (!adjusting) return tokens.map(lookup)\n\n const ids = new Set(current.map((label) => label.id))\n for (const token of tokens) {\n const id = lookup(token.slice(1))\n if (token.startsWith('+')) ids.add(id)\n else ids.delete(id)\n }\n return [...ids]\n}\n\n/** `-m \"text\"` or `--body-file path` (`-` reads stdin). */\nexport async function readBody(\n message: string | undefined,\n file: string | undefined,\n): Promise<string | undefined> {\n if (message !== undefined && file !== undefined) {\n throw new CliError('Pass either -m or --body-file, not both.', ExitCode.Validation)\n }\n if (message !== undefined) return message\n if (file === undefined) return undefined\n if (file === '-') {\n const chunks: Buffer[] = []\n for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk))\n return Buffer.concat(chunks).toString('utf8')\n }\n try {\n return readFileSync(file, 'utf8')\n } catch (cause) {\n throw new CliError(\n `Cannot read ${file}: ${cause instanceof Error ? cause.message : String(cause)}`,\n ExitCode.Validation,\n )\n }\n}\n\n/**\n * `ACME-123` + \"Fix the login redirect\" → `acme-123-fix-the-login-redirect`.\n * The key stays first so a branch name is enough for commit linking to attach\n * the work back to the item.\n */\nexport function branchName(item: Pick<WorkItemView, 'key' | 'title'>, maxWords = 6): string {\n const slug = item.title\n .toLowerCase()\n .normalize('NFKD')\n .replace(/[^\\da-z]+/g, ' ')\n .trim()\n .split(/\\s+/)\n .filter((word) => word.length > 0)\n .slice(0, maxWords)\n .join('-')\n return slug ? `${item.key.toLowerCase()}-${slug}` : item.key.toLowerCase()\n}\n","import { Command } from 'commander'\nimport { Client } from '@modelcontextprotocol/sdk/client/index.js'\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n CallToolRequestSchema,\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n ListResourceTemplatesRequestSchema,\n ListResourcesRequestSchema,\n ListToolsRequestSchema,\n ReadResourceRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js'\nimport { resolveSettings } from '../context.js'\nimport { version } from '../version.js'\nimport type { GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\n\n/**\n * `aictiq mcp` is a stdio MCP server that forwards to the instance's Streamable HTTP\n * `/mcp` endpoint. Clients that only speak stdio (or that should not be handed a bearer\n * token in their configuration file) point at this instead: the token comes from the\n * CLI's own 0600 config, so an agent's `.mcp.json` can be committed.\n *\n * The bridge deliberately holds no catalogue of its own - every list and call is\n * forwarded, so a tool added to the API on Tuesday is reachable through an unchanged CLI\n * on Wednesday. Only `notifications/initialized` and the handshake are handled locally.\n */\nexport function mcpCommand(globals: () => GlobalOptions): Command {\n return new Command('mcp')\n .description('Run a stdio MCP server bridged to this instance (for Claude Code and friends)')\n .action(async () => {\n const settings = resolveSettings(globals())\n if (!settings.url || !settings.token) {\n throw new CliError(\n 'No instance configured. Run `aictiq auth login --url <url>` or set AICTIQ_URL and AICTIQ_TOKEN.',\n ExitCode.Auth,\n )\n }\n\n // The bridge itself offers no sampling, roots or elicitation: it forwards server\n // capabilities downstream and nothing upstream.\n const upstream = new Client({ name: 'aictiq-cli', version }, { capabilities: {} })\n try {\n await upstream.connect(\n new StreamableHTTPClientTransport(\n new URL('/mcp', `${settings.url.replace(/\\/+$/, '')}/`),\n { requestInit: { headers: { Authorization: `Bearer ${settings.token}` } } },\n ),\n )\n } catch (cause) {\n const detail = cause instanceof Error ? cause.message : String(cause)\n // `/mcp` needs more than a valid token: the `mcp` scope, and a token bound to one\n // organization. Both refusals arrive here as a bare 403, which on its own tells\n // nobody which of the two to fix.\n throw new CliError(\n detail.includes('403') || detail.includes('401')\n ? `${settings.url} refused the token for /mcp. It needs the \"mcp\" scope and must be bound to one organization - create it under Settings → Access tokens with an organization selected.`\n : `Cannot open an MCP session at ${settings.url}/mcp: ${detail}`,\n ExitCode.Auth,\n )\n }\n\n // Advertise exactly what the instance advertises: a client that sees `prompts` here\n // but gets \"method not found\" from upstream has been lied to by the bridge.\n const capabilities = upstream.getServerCapabilities() ?? {}\n const server = new Server(\n { name: 'aictiq', version },\n {\n capabilities: {\n ...(capabilities.tools ? { tools: capabilities.tools } : {}),\n ...(capabilities.resources ? { resources: capabilities.resources } : {}),\n ...(capabilities.prompts ? { prompts: capabilities.prompts } : {}),\n },\n },\n )\n\n if (capabilities.tools) {\n server.setRequestHandler(ListToolsRequestSchema, (request) =>\n upstream.listTools(request.params),\n )\n server.setRequestHandler(CallToolRequestSchema, (request) =>\n upstream.callTool(request.params),\n )\n }\n if (capabilities.resources) {\n server.setRequestHandler(ListResourcesRequestSchema, (request) =>\n upstream.listResources(request.params),\n )\n server.setRequestHandler(ListResourceTemplatesRequestSchema, (request) =>\n upstream.listResourceTemplates(request.params),\n )\n server.setRequestHandler(ReadResourceRequestSchema, (request) =>\n upstream.readResource(request.params),\n )\n }\n if (capabilities.prompts) {\n server.setRequestHandler(ListPromptsRequestSchema, (request) =>\n upstream.listPrompts(request.params),\n )\n server.setRequestHandler(GetPromptRequestSchema, (request) =>\n upstream.getPrompt(request.params),\n )\n }\n\n // stdout is the transport, so nothing else may be written to it while the bridge\n // runs; diagnostics go to stderr.\n await server.connect(new StdioServerTransport())\n\n const shutdown = async () => {\n await Promise.allSettled([server.close(), upstream.close()])\n process.exit(0)\n }\n process.on('SIGINT', () => void shutdown())\n process.on('SIGTERM', () => void shutdown())\n\n // Resolve only when stdin closes, which is how a stdio MCP client says goodbye.\n await new Promise<void>((resolve) => process.stdin.once('close', resolve))\n await shutdown()\n })\n}\n","import { createRequire } from 'node:module'\n\n// Read at runtime rather than baked in by the bundler, so `aictiq --version` and the MCP\n// handshake cannot drift from the version npm actually installed.\nconst manifest = createRequire(import.meta.url)('../package.json') as { version?: string }\n\nexport const version = manifest.version ?? '0.0.0'\n","import { Command } from 'commander'\nimport type { ProjectView } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { GlobalOptions } from '../context.js'\nimport { print, printJson, renderTable } from '../output.js'\n\nexport function projectCommand(globals: () => GlobalOptions): Command {\n const project = new Command('project').description('Projects in the organization')\n\n project\n .command('list')\n .description('List the projects you can see')\n .option('--archived', 'Include archived projects')\n .action(async (options: { archived?: boolean }) => {\n const ctx = createContext(globals())\n const projects = await ctx.client.request<\n ProjectView[],\n '/api/v1/orgs/{orgSlug}/projects',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects', {\n path: { orgSlug: await ctx.org() },\n query: { includeArchived: options.archived === true },\n })\n\n if (ctx.json) return printJson(projects)\n if (projects.length === 0) return print('No projects.')\n print(\n renderTable(projects, [\n { header: 'KEY', value: (p) => p.key },\n { header: 'NAME', value: (p) => p.name },\n { header: 'ROLE', value: (p) => p.role },\n { header: 'VISIBILITY', value: (p) => p.visibility },\n { header: 'STATUS', value: (p) => (p.isArchived ? 'archived' : 'active') },\n ]),\n )\n })\n\n return project\n}\n","import { Command } from 'commander'\nimport type {\n AgentView,\n PagedResult,\n PlaybookView,\n RunLogEntry,\n RunLogPage,\n RunStatus,\n RunView,\n} from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport {\n formatDateTime,\n formatNumber,\n print,\n printJson,\n renderFields,\n renderTable,\n} from '../output.js'\nimport { normalizeItemKey, projectKeyOf } from '../resolve.js'\n\nconst statuses: RunStatus[] = [\n 'queued',\n 'assigned',\n 'running',\n 'succeeded',\n 'failed',\n 'cancelled',\n 'timedOut',\n]\nconst terminal = new Set<RunStatus>(['succeeded', 'failed', 'cancelled', 'timedOut'])\n\n/** One page of the log per request; the API clamps at 1000. */\nconst logPageSize = 200\n\n/**\n * The server's \"log truncated\" marker sits at `int.MaxValue` (`RunLogChunk.TruncatedSeq`);\n * `truncated` on the page is the flag, so the marker row itself is not printed as output.\n */\nconst truncatedSeq = 2147483647\n\n/**\n * `--follow` polls rather than joining the hub: a CLI has no SignalR client and a poll every\n * two seconds is the right cost for a log that grows a few lines at a time. The interval is\n * an environment variable so a test does not spend two real seconds per iteration.\n */\nconst defaultPollMs = 2000\n\nexport function pollIntervalMs(env: NodeJS.ProcessEnv = process.env): number {\n const raw = env.AICTIQ_RUN_POLL_MS\n if (raw === undefined || raw === '') return defaultPollMs\n const parsed = Number(raw)\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : defaultPollMs\n}\n\nexport function runCommand(globals: () => GlobalOptions): Command {\n const run = new Command('run').description('Factory runs: hand an item to an agent and watch it')\n\n run\n .command('start')\n .description('Dispatch a run for a work item')\n .argument('<key>', 'Work item key, e.g. ACME-123')\n .option('--playbook <nameOrId>', \"One of the project's playbooks; the default when omitted\")\n .option(\n '--agent <nameOrId>',\n \"An agent of the project; the project's default agent when omitted\",\n )\n .action(async (key: string, options: { playbook?: string; agent?: string }) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const itemKey = normalizeItemKey(key)\n const playbookId = options.playbook\n ? await resolvePlaybookId(ctx, projectKeyOf(itemKey), options.playbook)\n : undefined\n const agentId = options.agent ? await resolveAgentId(ctx, options.agent) : undefined\n\n const started = await ctx.client.request<\n RunView,\n '/api/v1/orgs/{orgSlug}/items/{itemKey}/runs',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/items/{itemKey}/runs', {\n path: { orgSlug, itemKey },\n body: {\n ...(playbookId === undefined ? {} : { playbookId }),\n ...(agentId === undefined ? {} : { agentId }),\n },\n })\n\n if (ctx.json) return printJson(started)\n print(\n renderFields([\n ['Run', started.id],\n ['Item', started.itemKey],\n ['Status', started.status],\n ['Agent', started.agentName ?? started.agentId],\n ['Playbook', started.playbookName ?? started.playbookId],\n ]),\n )\n })\n\n run\n .command('list')\n .description('List runs, newest first')\n .option('-p, --project <key>', 'Only runs in this project')\n .option('--status <status>', `One of ${statuses.join(', ')}`)\n .option('--agent <id>', 'Only runs by this agent (user id)')\n .option('--item <key>', 'Only runs for this item')\n .option('--page <n>', 'Page number', '1')\n .option('--page-size <n>', 'Runs per page (max 100)', '25')\n .action(\n async (options: {\n project?: string\n status?: string\n agent?: string\n item?: string\n page: string\n pageSize: string\n }) => {\n const ctx = createContext(globals())\n if (options.status !== undefined && !statuses.includes(options.status as RunStatus)) {\n throw new CliError(\n `Unknown run status \"${options.status}\". Statuses: ${statuses.join(', ')}.`,\n ExitCode.Validation,\n )\n }\n const page = await ctx.client.request<\n PagedResult<RunView>,\n '/api/v1/orgs/{orgSlug}/runs',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/runs', {\n path: { orgSlug: await ctx.org() },\n query: {\n project: options.project?.toUpperCase(),\n status: options.status,\n agent: options.agent,\n item: options.item === undefined ? undefined : normalizeItemKey(options.item),\n page: options.page,\n pageSize: options.pageSize,\n },\n })\n\n if (ctx.json) return printJson(page)\n if (page.items.length === 0) return print('No runs match.')\n print(\n renderTable(page.items, [\n { header: 'ID', value: (r) => r.id },\n { header: 'ITEM', value: (r) => r.itemKey },\n { header: 'STATUS', value: (r) => r.status },\n { header: 'AGENT', value: (r) => r.agentName ?? r.agentId },\n { header: 'PLAYBOOK', value: (r) => r.playbookName ?? r.playbookId },\n { header: 'QUEUED', value: (r) => formatDateTime(r.queuedAt) },\n { header: 'FINISHED', value: (r) => formatDateTime(r.finishedAt) },\n { header: 'PR', value: (r) => r.pullRequestUrl ?? '' },\n ]),\n )\n print('')\n print(`Page ${page.page} of ${Math.max(1, page.totalPages)} · ${page.totalCount} runs`)\n },\n )\n\n run\n .command('view')\n .description('Show a run')\n .argument('<runId>', 'Run id')\n .action(async (runId: string) => {\n const ctx = createContext(globals())\n const found = await getRun(ctx, await ctx.org(), runId)\n if (ctx.json) return printJson(found)\n\n const cost =\n found.costUsd === null && found.inputTokens === null && found.outputTokens === null\n ? undefined\n : [\n found.costUsd === null ? undefined : `$${found.costUsd.toFixed(4)}`,\n found.inputTokens === null && found.outputTokens === null\n ? undefined\n : `${formatNumber(found.inputTokens) || '0'} in / ${formatNumber(found.outputTokens) || '0'} out tokens`,\n ]\n .filter((part) => part !== undefined)\n .join(' · ')\n\n print(\n renderFields([\n ['Run', found.id],\n ['Item', found.itemKey],\n ['Status', found.status],\n ['Agent', found.agentName ?? found.agentId],\n ['Playbook', found.playbookName ?? found.playbookId],\n ['Runner', found.runnerName ?? found.runnerId ?? undefined],\n ['Harness', found.harness],\n [\n 'Requested by',\n found.requestedBy ?? (found.ruleId ? `rule: ${found.ruleName ?? '(deleted)'}` : undefined),\n ],\n ['Max minutes', String(found.maxMinutes)],\n ['Queued', formatDateTime(found.queuedAt)],\n ['Assigned', formatDateTime(found.assignedAt)],\n ['Started', formatDateTime(found.startedAt)],\n ['Finished', formatDateTime(found.finishedAt)],\n ['Last heartbeat', formatDateTime(found.lastHeartbeatAt)],\n ['Cancel requested', found.cancelRequested ? 'yes' : undefined],\n ['Outcome', found.outcomeSummary ?? undefined],\n ['PR', found.pullRequestUrl ?? undefined],\n ['Exit code', found.exitCode === null ? undefined : String(found.exitCode)],\n ['Cost', cost],\n ['Failure', found.failureReason ?? undefined],\n ]),\n )\n })\n\n run\n .command('logs')\n .description(\"Print a run's log; --follow keeps polling until the run finishes\")\n .argument('<runId>', 'Run id')\n .option('-f, --follow', 'Poll for new output every 2 s until the run is finished')\n .action(async (runId: string, options: { follow?: boolean }) => {\n const ctx = createContext(globals())\n await streamLog(ctx, await ctx.org(), runId, options.follow === true, pollIntervalMs())\n })\n\n run\n .command('cancel')\n .description('Ask a run to stop; the runner ends the harness and the run records cancelled')\n .argument('<runId>', 'Run id')\n .action(async (runId: string) => {\n const ctx = createContext(globals())\n await ctx.client.request<undefined, '/api/v1/orgs/{orgSlug}/runs/{runId}/cancel', 'post'>(\n 'post',\n '/api/v1/orgs/{orgSlug}/runs/{runId}/cancel',\n { path: { orgSlug: await ctx.org(), runId } },\n )\n if (ctx.json) return printJson({ id: runId, cancelRequested: true })\n print(`Cancel requested for run ${runId}.`)\n })\n\n return run\n}\n\nasync function getRun(ctx: Context, orgSlug: string, runId: string): Promise<RunView> {\n return ctx.client.request<RunView, '/api/v1/orgs/{orgSlug}/runs/{runId}', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/runs/{runId}',\n { path: { orgSlug, runId } },\n )\n}\n\n/**\n * Prints the log from the start and, when following, keeps going until the run is in a\n * terminal state and one last page after that has been drained - the status is read\n * *before* each page, so output written between the last page and the finish is never\n * missed. A full page is followed by another request straight away; a short one waits.\n */\nasync function streamLog(\n ctx: Context,\n orgSlug: string,\n runId: string,\n follow: boolean,\n pollMs: number,\n): Promise<void> {\n let after = -1\n let notedTruncation = false\n for (;;) {\n const finished = follow ? terminal.has((await getRun(ctx, orgSlug, runId)).status) : true\n for (;;) {\n const page = await ctx.client.request<\n RunLogPage,\n '/api/v1/orgs/{orgSlug}/runs/{runId}/log',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/runs/{runId}/log', {\n path: { orgSlug, runId },\n query: { after, pageSize: logPageSize },\n })\n for (const entry of page.items) {\n after = Math.max(after, entry.seq)\n if (entry.seq !== truncatedSeq) print(formatLogEntry(entry))\n }\n if (page.truncated && !notedTruncation) {\n notedTruncation = true\n print('(log truncated)')\n }\n if (page.items.length < logPageSize) break\n }\n if (finished) return\n await new Promise<void>((resolve) => setTimeout(resolve, pollMs))\n }\n}\n\nexport function formatLogEntry(entry: RunLogEntry): string {\n const text = entry.text.endsWith('\\n') ? entry.text.slice(0, -1) : entry.text\n if (entry.stream === 'stdout') return text\n const prefix = entry.stream === 'stderr' ? '[stderr] ' : '[event] '\n return text\n .split('\\n')\n .map((line) => `${prefix}${line}`)\n .join('\\n')\n}\n\nconst uuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\n/** An id passes through; a name is matched case-insensitively against the project's playbooks. */\nasync function resolvePlaybookId(\n ctx: Context,\n projectKey: string,\n playbook: string,\n): Promise<string> {\n if (uuid.test(playbook)) return playbook\n const playbooks = await ctx.client.request<\n PlaybookView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/playbooks',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/playbooks', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n const wanted = playbook.trim().toLowerCase()\n const matches = playbooks.filter((p) => p.name.toLowerCase() === wanted)\n if (matches.length === 1) return matches[0]!.id\n if (matches.length === 0) {\n throw new CliError(\n `No playbook \"${playbook}\" in ${projectKey}. Playbooks: ${playbooks.map((p) => p.name).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n throw new CliError(\n `Several playbooks in ${projectKey} are named \"${playbook}\"; pass one by id: ${matches.map((p) => p.id).join(', ')}.`,\n ExitCode.Validation,\n )\n}\n\n/** An id passes through; a display name is matched case-insensitively against the organization's agents. */\nasync function resolveAgentId(ctx: Context, agent: string): Promise<string> {\n if (uuid.test(agent)) return agent\n const agents = await ctx.client.request<AgentView[], '/api/v1/orgs/{orgSlug}/agents', 'get'>(\n 'get',\n '/api/v1/orgs/{orgSlug}/agents',\n { path: { orgSlug: await ctx.org() } },\n )\n const byId = agents.find((a) => a.userId === agent)\n if (byId) return byId.userId\n const wanted = agent.trim().toLowerCase()\n const matches = agents.filter((a) => a.displayName.toLowerCase() === wanted)\n if (matches.length === 1) return matches[0]!.userId\n if (matches.length === 0) {\n throw new CliError(\n `No agent \"${agent}\" in this organization. Agents: ${agents.map((a) => a.displayName).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n throw new CliError(\n `Several agents are named \"${agent}\"; pass one by id: ${matches.map((a) => a.userId).join(', ')}.`,\n ExitCode.Validation,\n )\n}\n","import { Command } from 'commander'\nimport { randomUUID } from 'node:crypto'\nimport { existsSync } from 'node:fs'\nimport { arch, homedir, platform } from 'node:os'\nimport { resolve } from 'node:path'\nimport type { GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { print, printJson, renderFields, renderTable } from '../output.js'\nimport { promptSecret } from '../prompt.js'\nimport { version } from '../version.js'\nimport { RunnerClient, RunnerHttpError } from '../runner/client.js'\nimport {\n profileKey,\n profileLabel,\n readRunnerConfig,\n runnerConfigPath,\n sameInstance,\n writeRunnerConfig,\n} from '../runner/config.js'\nimport type { RunnerConfig, RunnerProfile } from '../runner/config.js'\nimport { executeRun } from '../runner/execute.js'\nimport { harnesses, probeHarnesses } from '../runner/harness/index.js'\nimport { serviceDefinition, servicePlatform, type ServicePlatform } from '../runner/service.js'\nimport { RunnerLoop, RunnerRevokedError } from '../runner/loop.js'\nimport { RunnerSupervisor } from '../runner/supervisor.js'\nimport type { RunnerCapabilities } from '../runner/types.js'\nimport { DefaultAttachmentMaxBytes, DefaultAttachmentMaxCount, defaultWorkspaceRoot } from '../runner/workspace.js'\n\n/**\n * `aictiq runner` - the worker on the factory floor. It authenticates with a\n * `jrn_` runner secret kept in its own `runner.json`, never with the person's PAT.\n */\nexport function runnerCommand(globals: () => GlobalOptions): Command {\n const runner = new Command('runner').description(\n 'Run agent work dispatched from a Aictiq instance on this machine',\n )\n\n runner\n .command('register')\n .description(\n 'Store a runner secret (jrn_…) from Factory → Runners and check it. A secret from another organization adds it to this machine',\n )\n // Not requiredOption: the root command defines --url and --token too, and commander hands\n // them to the root, so they are read from both places exactly as `auth login` does.\n .option('--url <url>', 'Base URL of the Aictiq instance')\n .option('--token <token>', 'Runner secret; read from stdin when omitted')\n .option('--name <name>', 'A local label for this machine (each instance keeps its own name)')\n .action(async (options: { url?: string; token?: string; name?: string }) => {\n const global = globals()\n const rawUrl = options.url ?? global.url\n if (!rawUrl) {\n throw new CliError(\n 'Pass --url with the address of your Aictiq instance.',\n ExitCode.Validation,\n )\n }\n const token =\n options.token ??\n global.token ??\n process.env.AICTIQ_RUNNER_TOKEN ??\n (await promptSecret('Runner secret: '))\n if (!token?.startsWith('jrn_')) {\n throw new CliError(\n 'A runner secret starts with jrn_. Create one under Factory → Runners.',\n ExitCode.Validation,\n )\n }\n const url = rawUrl.replace(/\\/+$/, '')\n\n const existing = readRunnerConfig()\n const machineId = existing?.machineId ?? randomUUID()\n // Verify before writing, as `auth login` does: a stored secret that never worked\n // turns into a service that restarts forever somewhere nobody is looking.\n const capabilities = await probe(1, machineId)\n const hello = await new RunnerClient({ baseUrl: url, token })\n .hello(capabilities)\n .catch((error: unknown) => {\n throw asCliError(error)\n })\n\n const profiles = existing?.profiles ?? []\n const index = await matchingProfile(profiles, url, token, hello.organizationSlug, capabilities)\n const previous = index >= 0 ? profiles[index] : undefined\n const profile: RunnerProfile = {\n url,\n token,\n organization: hello.organizationSlug,\n // Re-registering one organization (a rotated secret) keeps the repository map\n // someone built up; a new organization starts with its own, empty one.\n workspaces: previous?.workspaces ?? {},\n repoRoots: previous?.repoRoots ?? [],\n }\n const next = index >= 0 ? profiles.map((p, i) => (i === index ? profile : p)) : [...profiles, profile]\n const name = options.name ?? existing?.name\n writeRunnerConfig({\n machineId,\n ...(name ? { name } : {}),\n profiles: next,\n attachments: existing?.attachments ?? { maxCount: DefaultAttachmentMaxCount, maxBytes: DefaultAttachmentMaxBytes },\n })\n\n if (globals().json) {\n printJson({\n url,\n runner: hello,\n capabilities,\n configPath: runnerConfigPath(),\n organizations: next.map(profileLabel),\n })\n return\n }\n const organizations = next.map(profileLabel)\n const lines = [\n `Registered runner \"${hello.name}\" with ${url} (${hello.organizationSlug}).`,\n `Harnesses: ${capabilities.harnesses.map((h) => h.name).join(', ') || 'none found on PATH'}`,\n `Config written to ${runnerConfigPath()}.`,\n ]\n if (next.length > 1) {\n lines.push(\n '',\n `This machine now runs for ${next.length} organizations: ${organizations.join(', ')}.`,\n 'Runs from different organizations never execute at the same time.',\n `Repository roots and mappings are per organization: \\`aictiq runner root <path> --org ${hello.organizationSlug}\\`.`,\n 'A running `aictiq runner start` picks this up within a few seconds; otherwise start it.',\n )\n } else {\n lines.push('Start it with `aictiq runner start`.')\n }\n print(lines.join('\\n'))\n })\n\n runner\n .command('map')\n .description(\n 'Map a project key to a local clone, for projects whose repository source is local',\n )\n .argument('<projectKey>', 'Project key, e.g. ACME')\n .argument('[path]', 'Path of the clone (default: the current directory); omit with --remove')\n .option('--remove', 'Remove the mapping')\n .option('--org <slug>', 'The organization the mapping is for, when this machine runs for several')\n .action((projectKey: string, path: string | undefined, options: { remove?: boolean; org?: string }) => {\n const config = requireConfig()\n const profile = selectProfile(config, options.org ?? globals().org)\n const key = projectKey.toUpperCase()\n if (options.remove) {\n delete profile.workspaces[key]\n } else {\n const absolute = resolve(path ?? '.')\n if (!existsSync(absolute))\n throw new CliError(`${absolute} does not exist.`, ExitCode.Validation)\n profile.workspaces[key] = absolute\n }\n writeRunnerConfig(config)\n const where = config.profiles.length > 1 ? ` (${profileLabel(profile)})` : ''\n print(\n options.remove\n ? `Removed the mapping for ${key}${where}.`\n : `${key} → ${profile.workspaces[key]}${where}`,\n )\n })\n\n runner\n .command('root')\n .description(\n \"Trust the web UI's path hint for local projects whose clone is under this directory\",\n )\n .argument('[path]', 'Directory that holds your clones (default: the current directory)')\n .option('--remove', 'Stop trusting path hints under this directory')\n .option('--org <slug>', 'The organization whose path hints to trust, when this machine runs for several')\n .action((path: string | undefined, options: { remove?: boolean; org?: string }) => {\n const config = requireConfig()\n const profile = selectProfile(config, options.org ?? globals().org)\n const absolute = resolve(path ?? '.')\n if (options.remove) {\n profile.repoRoots = profile.repoRoots.filter((root) => resolve(root) !== absolute)\n } else {\n if (!existsSync(absolute))\n throw new CliError(`${absolute} does not exist.`, ExitCode.Validation)\n if (!profile.repoRoots.some((root) => resolve(root) === absolute))\n profile.repoRoots.push(absolute)\n }\n writeRunnerConfig(config)\n const whose = config.profiles.length > 1 ? `${profileLabel(profile)}'s path hints` : 'Path hints'\n print(\n options.remove\n ? `${whose} under ${absolute} are no longer used.`\n : `${whose} under ${absolute} are used for projects without a mapping.`,\n )\n })\n\n runner\n .command('remove')\n .description('Stop running for one organization on this machine (the other organizations are kept)')\n .argument('<org>', 'Organization slug, as `aictiq runner status` lists it')\n .action((org: string) => {\n const config = requireConfig()\n const profile = selectProfile(config, org)\n config.profiles = config.profiles.filter((p) => p !== profile)\n writeRunnerConfig(config)\n print(\n `Removed ${profileLabel(profile)} from this machine. A running \\`aictiq runner start\\` stops taking its runs within a few seconds.\\n` +\n `Its secret still works until you disable or delete the runner in ${profileLabel(profile)}'s Factory → Runners.`,\n )\n })\n\n runner\n .command('status')\n .description('Show each registration, detected harnesses and mapped repositories')\n .action(async () => {\n const config = requireConfig()\n const capabilities = await probe(1, config.machineId)\n const registrations = await Promise.all(\n config.profiles.map(async (profile) => {\n try {\n const hello = await new RunnerClient({ baseUrl: profile.url, token: profile.token }).hello(capabilities)\n return { profile, hello, text: `ok - \"${hello.name}\" in ${hello.organizationSlug}`, revoked: false }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n profile,\n error: message,\n text: `failing - ${message}`,\n revoked: error instanceof RunnerHttpError && error.revoked,\n }\n }\n }),\n )\n // A health check scripted around `status` must be able to tell a dead secret apart.\n if (registrations.some((r) => r.revoked)) process.exitCode = ExitCode.Auth\n\n if (globals().json) {\n printJson({\n machineId: config.machineId,\n capabilities,\n attachments: config.attachments,\n profiles: registrations.map((r) => ({\n url: r.profile.url,\n organization: r.hello?.organizationSlug ?? r.profile.organization ?? null,\n registration: r.hello ?? { error: r.error },\n workspaces: r.profile.workspaces,\n repoRoots: r.profile.repoRoots,\n })),\n })\n return\n }\n print(\n renderFields([\n ['Config', runnerConfigPath()],\n ['Machine', config.machineId],\n ['Workspaces', defaultWorkspaceRoot()],\n ['Attachments', `${config.attachments.maxCount} files / ${formatBytes(config.attachments.maxBytes)} per run`],\n ['CLI', `${version} (${capabilities.os}/${capabilities.arch})`],\n ]),\n )\n print('')\n print(\n capabilities.harnesses.length === 0\n ? 'No harness found on PATH (claude, codex, opencode).'\n : renderTable(capabilities.harnesses, [\n { header: 'HARNESS', value: (h) => h.name },\n { header: 'VERSION', value: (h) => h.version ?? '' },\n ]),\n )\n for (const { profile, hello, text } of registrations) {\n const org = hello?.organizationSlug ?? profileLabel(profile)\n print('')\n print(\n renderFields([\n ['Organization', org],\n ['Instance', profile.url],\n ['Registration', text],\n ]),\n )\n const mapped = Object.entries(profile.workspaces)\n print(\n mapped.length === 0\n ? `No local repositories mapped (\\`aictiq runner map <KEY> <path> --org ${org}\\`).`\n : renderTable(mapped, [\n { header: 'PROJECT', value: ([key]) => key },\n { header: 'REPOSITORY', value: ([, path]) => path },\n ]),\n )\n print(\n profile.repoRoots.length === 0\n ? `No repository roots; path hints from ${org} are not used (\\`aictiq runner root <path> --org ${org}\\`).`\n : renderTable(profile.repoRoots, [{ header: 'REPOSITORY ROOT', value: (root) => root }]),\n )\n }\n })\n\n runner\n .command('start')\n .description('Poll every registered organization for runs and execute them until interrupted')\n .option('--parallel <n>', 'Runs of one organization executed at the same time', '1')\n .option('--keep-workspaces', 'Leave each run’s checkout on disk after it finishes')\n .option('--workspace-root <path>', 'Where run checkouts are created')\n .action(\n async (options: { parallel: string; keepWorkspaces?: boolean; workspaceRoot?: string }) => {\n const config = requireConfig()\n const parallel = Number.parseInt(options.parallel, 10)\n if (!Number.isInteger(parallel) || parallel < 1 || parallel > 16) {\n throw new CliError('--parallel is between 1 and 16.', ExitCode.Validation)\n }\n // Keeps the machine id, and rewrites a file from before profiles in the new shape.\n writeRunnerConfig(config)\n\n const log = (message: string) =>\n process.stderr.write(`${new Date().toISOString()} ${message}\\n`)\n const workspaceRoot = resolve(options.workspaceRoot ?? defaultWorkspaceRoot())\n const supervisor = new RunnerSupervisor({\n readConfig: () => readRunnerConfig(),\n local: log,\n learned: (profile) => {\n // Re-read rather than write what this process holds: `register` or `root` may\n // have changed the file since.\n const current = readRunnerConfig()\n const stored = current?.profiles.find((p) => p.token === profile.token)\n if (!current || !stored || stored.organization === profile.organization) return\n stored.organization = profile.organization\n writeRunnerConfig(current)\n },\n createLoop: (profile, floor, onHello) => {\n const client = new RunnerClient({ baseUrl: profile.url, token: profile.token })\n const local = (message: string) => log(`[${profileLabel(profile)}] ${message}`)\n return new RunnerLoop({\n client,\n parallel,\n probe: () => probe(parallel, config.machineId),\n local,\n floor,\n floorKey: profileKey(profile),\n onHello,\n execute: (run, hello, shutdown) => {\n // Re-read per run, so a new mapping or root applies without restarting the\n // runner. Only this profile's: another organization's roots never apply.\n const current = readRunnerConfig()\n const own = current?.profiles.find((p) => p.token === profile.token) ?? profile\n return executeRun(run, {\n client,\n hello,\n adapters: harnesses,\n runnerToken: profile.token,\n shutdown,\n local,\n workspace: {\n root: workspaceRoot,\n repositories: own.workspaces,\n repoRoots: own.repoRoots,\n keep: options.keepWorkspaces === true,\n mcpServer: mcpServerCommand(),\n attachmentMaxCount: (current ?? config).attachments.maxCount,\n attachmentMaxBytes: (current ?? config).attachments.maxBytes,\n },\n })\n },\n })\n },\n })\n\n let interrupts = 0\n const onSignal = (signal: NodeJS.Signals) => {\n interrupts++\n if (interrupts === 1 && supervisor.inFlight > 0) {\n log(\n `${signal}: finishing ${supervisor.inFlight} run(s) in flight; send it again to cancel them`,\n )\n supervisor.stop()\n } else if (interrupts === 1) {\n supervisor.stop()\n } else {\n log(`${signal}: cancelling runs in flight`)\n supervisor.abort()\n }\n }\n process.on('SIGINT', onSignal)\n process.on('SIGTERM', onSignal)\n try {\n await supervisor.run()\n } catch (error) {\n throw asCliError(error)\n } finally {\n process.off('SIGINT', onSignal)\n process.off('SIGTERM', onSignal)\n }\n },\n )\n\n runner\n .command('install-service')\n .description(\n 'Print a service definition that keeps `aictiq runner start` running: a systemd user unit (Linux), a launchd agent (macOS) or a Task Scheduler installer (Windows)',\n )\n .option('--parallel <n>', 'Runs executed at the same time', '1')\n .option('--platform <platform>', 'linux, macos or windows (default: this machine)')\n .action((options: { parallel: string; platform?: string }) => {\n const platform = options.platform ?? servicePlatform()\n if (!isServicePlatform(platform)) {\n throw new CliError(\n `Unknown platform \"${platform}\". Use linux, macos or windows.`,\n ExitCode.Validation,\n )\n }\n print(\n serviceDefinition(platform, {\n node: process.execPath,\n entry: cliEntry(),\n parallel: options.parallel,\n path: process.env.PATH ?? '/usr/local/bin:/usr/bin:/bin',\n home: homedir(),\n }),\n )\n })\n\n return runner\n}\n\nasync function probe(maxParallel: number, machineId: string): Promise<RunnerCapabilities> {\n return {\n v: 1,\n harnesses: await probeHarnesses(),\n os: platform(),\n arch: arch(),\n cliVersion: version,\n maxParallel,\n machineId,\n }\n}\n\n/**\n * The profile a registration replaces: the same organization on the same instance (a\n * rotated secret). A profile from before profiles existed has no organization yet; it is\n * asked, and if its secret no longer works at all while it is the only one, it is taken to be\n * this organization's previous secret, as re-registering always treated it.\n */\nasync function matchingProfile(\n profiles: RunnerProfile[],\n url: string,\n token: string,\n organization: string,\n capabilities: RunnerCapabilities,\n): Promise<number> {\n const exact = profiles.findIndex(\n (p) => p.token === token || (sameInstance(p.url, url) && p.organization === organization),\n )\n if (exact >= 0) return exact\n\n for (const [index, profile] of profiles.entries()) {\n if (profile.organization || !sameInstance(profile.url, url)) continue\n try {\n const hello = await new RunnerClient({ baseUrl: profile.url, token: profile.token }).hello(capabilities)\n profile.organization = hello.organizationSlug\n if (hello.organizationSlug === organization) return index\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked && profiles.length === 1) return index\n }\n }\n return -1\n}\n\nfunction selectProfile(config: RunnerConfig, org: string | undefined): RunnerProfile {\n const serves = config.profiles.map(profileLabel).join(', ')\n if (org) {\n const wanted = org.toLowerCase()\n const found = config.profiles.find((p) => profileLabel(p).toLowerCase() === wanted)\n if (!found) {\n throw new CliError(`This machine does not run for ${org}. It runs for: ${serves}.`, ExitCode.Validation)\n }\n return found\n }\n if (config.profiles.length === 1) return config.profiles[0]!\n throw new CliError(\n `This machine runs for several organizations (${serves}). Say which with --org <slug>.`,\n ExitCode.Validation,\n )\n}\n\n/** The CLI that is running now, so the agent's MCP bridge is this exact version. */\nfunction cliEntry(): string {\n return resolve(process.argv[1] ?? 'aictiq')\n}\n\nfunction mcpServerCommand(): { command: string; args: string[] } {\n return { command: process.execPath, args: [cliEntry(), 'mcp'] }\n}\n\nfunction formatBytes(value: number): string {\n return value >= 1024 * 1024 ? `${(value / (1024 * 1024)).toFixed(1)} MiB` : `${value} bytes`\n}\n\nfunction requireConfig(): RunnerConfig {\n const config = readRunnerConfig()\n if (!config || config.profiles.length === 0) {\n throw new CliError(\n `This machine is not registered as a runner (${runnerConfigPath()}). Run \\`aictiq runner register --url <url> --token <jrn_…>\\`.`,\n ExitCode.Auth,\n )\n }\n return config\n}\n\nfunction asCliError(error: unknown): unknown {\n if (error instanceof RunnerRevokedError) return new CliError(error.message, ExitCode.Auth)\n if (error instanceof RunnerHttpError) {\n return new CliError(\n error.status === 401\n ? `The instance refused the runner secret: ${error.message}`\n : error.message,\n error.status === 401 ? ExitCode.Auth : ExitCode.Error,\n )\n }\n return error\n}\n\nfunction isServicePlatform(value: string): value is ServicePlatform {\n return value === 'linux' || value === 'macos' || value === 'windows'\n}\n","import type { ProblemDetails } from '../errors.js'\nimport type {\n ClaimedRun,\n FinishReport,\n LogStream,\n RunAttachment,\n RunnerCapabilities,\n RunnerHello,\n} from './types.js'\n\nexport interface LogChunk {\n seq: number\n stream: LogStream\n text: string\n at: string\n}\n\n/** A refused request: the status and problem type are what the runner decides on. */\nexport class RunnerHttpError extends Error {\n readonly status: number\n readonly problem: ProblemDetails | undefined\n\n constructor(status: number, problem: ProblemDetails | undefined, message: string) {\n super(message)\n this.name = 'RunnerHttpError'\n this.status = status\n this.problem = problem\n }\n\n /** A disabled, deleted or rotated runner: retrying cannot help, so the process must stop. */\n get revoked(): boolean {\n return this.status === 401\n }\n}\n\n/** The instance could not be reached at all - the only failure worth a backoff and retry. */\nexport class RunnerNetworkError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'RunnerNetworkError'\n }\n}\n\nexport interface RunnerClientOptions {\n baseUrl: string\n token: string\n fetch?: typeof fetch\n}\n\n/**\n * The runner protocol (`/api/v1/runner/*`). Not the generated\n * `AictiqClient`: these routes take a `jrn_` secret that no person's command should ever\n * hold, and the item heartbeat below is the one call made with the run's agent token.\n */\nexport class RunnerClient {\n readonly baseUrl: string\n private readonly token: string\n private readonly doFetch: typeof fetch\n\n constructor(options: RunnerClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/+$/, '')\n this.token = options.token\n this.doFetch = options.fetch ?? fetch\n }\n\n hello(capabilities: RunnerCapabilities): Promise<RunnerHello> {\n return this.send<RunnerHello>('/runner/hello', { capabilities })\n }\n\n async heartbeat(capabilities: RunnerCapabilities): Promise<void> {\n await this.send('/runner/heartbeat', { capabilities })\n }\n\n /** Long-polls; null when the server had nothing within its poll timeout. */\n async claim(\n harnesses: string[],\n slots: number,\n signal?: AbortSignal,\n ): Promise<ClaimedRun | null> {\n return (await this.send<ClaimedRun>('/runner/runs/claim', { harnesses, slots }, signal)) ?? null\n }\n\n /** Hands a claimed run back before it starts; the instance queues it again and revokes its token. */\n async release(runId: string): Promise<void> {\n await this.send(`/runner/runs/${runId}/release`)\n }\n\n async started(runId: string): Promise<void> {\n await this.send(`/runner/runs/${runId}/started`)\n }\n\n async log(runId: string, chunks: LogChunk[]): Promise<void> {\n await this.send(`/runner/runs/${runId}/log`, { chunks })\n }\n\n async runHeartbeat(runId: string): Promise<{ cancelRequested: boolean }> {\n return this.send<{ cancelRequested: boolean }>(`/runner/runs/${runId}/heartbeat`)\n }\n\n async finish(runId: string, report: FinishReport): Promise<void> {\n await this.send(`/runner/runs/${runId}/finish`, report)\n }\n\n async repoToken(runId: string): Promise<string | null> {\n const response = await this.send<{ token: string | null }>(`/runner/runs/${runId}/repo-token`)\n return response?.token ?? null\n }\n\n /** Lists committed attachments on an item, including attachments posted in its comments. */\n listAttachments(run: ClaimedRun): Promise<RunAttachment[]> {\n return this.get<RunAttachment[]>(\n `/orgs/${encodeURIComponent(run.organizationSlug)}/items/${encodeURIComponent(run.itemKey)}/attachments?include=comments`,\n run.agentToken,\n )\n }\n\n /** Downloads attachment bytes using the short-lived agent credential, never the runner secret. */\n async downloadAttachment(run: ClaimedRun, attachmentId: string): Promise<Uint8Array> {\n const path = `/orgs/${encodeURIComponent(run.organizationSlug)}/attachments/${encodeURIComponent(attachmentId)}/download`\n const response = await this.request(path, 'GET', undefined, undefined, run.agentToken)\n if (!response.ok) throw await this.error(path, response)\n return new Uint8Array(await response.arrayBuffer())\n }\n\n /**\n * Keeps the item's claim fresh with the agent's own token. Without it the claim goes\n * stale after `Claims:StaleAfterMinutes` and another agent may take the item mid-run.\n */\n async itemHeartbeat(run: ClaimedRun): Promise<void> {\n await this.send(\n `/orgs/${encodeURIComponent(run.organizationSlug)}/items/${encodeURIComponent(run.itemKey)}/heartbeat`,\n undefined,\n undefined,\n run.agentToken,\n )\n }\n\n private async send<T>(\n path: string,\n body?: unknown,\n signal?: AbortSignal,\n token = this.token,\n ): Promise<T> {\n const response = await this.request(path, 'POST', body, signal, token)\n\n if (response.status === 204) return undefined as T\n if (!response.ok) throw await this.error(path, response)\n const text = await response.text()\n let payload: unknown\n try {\n payload = text.length === 0 ? undefined : JSON.parse(text)\n } catch {\n payload = undefined\n }\n return payload as T\n }\n\n private async get<T>(path: string, token: string): Promise<T> {\n const response = await this.request(path, 'GET', undefined, undefined, token)\n if (!response.ok) throw await this.error(path, response)\n return (await response.json()) as T\n }\n\n private async request(path: string, method: 'GET' | 'POST', body?: unknown, signal?: AbortSignal, token = this.token): Promise<Response> {\n try {\n return await this.doFetch(`${this.baseUrl}/api/v1${path}`, {\n method,\n headers: {\n Authorization: `Bearer ${token}`,\n Accept: 'application/json',\n 'User-Agent': 'aictiq-runner',\n ...(body === undefined ? {} : { 'Content-Type': 'application/json' }),\n },\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n ...(signal ? { signal } : {}),\n })\n } catch (cause) {\n if (signal?.aborted) throw cause\n throw new RunnerNetworkError(`Cannot reach ${this.baseUrl}: ${cause instanceof Error ? cause.message : String(cause)}`)\n }\n }\n\n private async error(path: string, response: Response): Promise<RunnerHttpError | RunnerNetworkError> {\n // A gateway in front of the instance answering 502 is the network, not a verdict.\n if (response.status >= 502 && response.status <= 504) return new RunnerNetworkError(`${this.baseUrl} answered ${response.status}`)\n const text = await response.text()\n let payload: unknown\n try { payload = text.length === 0 ? undefined : JSON.parse(text) } catch { payload = undefined }\n const problem = typeof payload === 'object' && payload !== null ? (payload as ProblemDetails) : undefined\n return new RunnerHttpError(response.status, problem, `${path}: ${response.status} ${problem?.title ?? response.statusText}${problem?.detail ? ` - ${problem.detail}` : ''}`)\n }\n}\n","import { createHash, randomUUID } from 'node:crypto'\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { dirname, join } from 'node:path'\nimport { DefaultAttachmentMaxBytes, DefaultAttachmentMaxCount } from './workspace.js'\n\nexport interface RunnerAttachmentConfig {\n maxCount: number\n maxBytes: number\n}\n\n/**\n * One organization this machine runs for: its own secret, and its own repository map and\n * roots. Nothing here is shared between profiles - a path hint from one organization is\n * never resolved under another organization's roots, and a project key that exists in two\n * organizations maps to two different clones.\n */\nexport interface RunnerProfile {\n url: string\n token: string\n /**\n * The organization slug the instance named on hello. Absent only in a profile carried over\n * from a `runner.json` written before profiles existed, until its first hello.\n */\n organization?: string\n /** Project key → path of a local clone, for projects whose repository source is `local`. */\n workspaces: Record<string, string>\n /**\n * Directories under which a project's path hint (set in the web UI) is used when the\n * project has no `workspaces` entry. Absolute, or starting with `~/`.\n */\n repoRoots: string[]\n}\n\n/**\n * What `aictiq runner register` writes. Deliberately a separate file from `config.json`:\n * a runner's credential is not a person's, and a machine that is both somebody's laptop\n * and a runner must not have one overwrite the other.\n */\nexport interface RunnerConfig {\n /**\n * Random, kept for the life of this file, and reported to every organization, so the web UI\n * can show this machine once however many organizations it serves. It authorizes nothing.\n */\n machineId: string\n /** A local label for this machine (each instance keeps its own runner name). */\n name?: string\n profiles: RunnerProfile[]\n attachments: RunnerAttachmentConfig\n}\n\nexport function runnerConfigPath(env: NodeJS.ProcessEnv = process.env): string {\n const base = env.AICTIQ_CONFIG_HOME ?? env.XDG_CONFIG_HOME ?? join(homedir(), '.config')\n return join(base, 'aictiq', 'runner.json')\n}\n\n/**\n * Null when the file is missing or unreadable. A file from before profiles (`url` and `token`\n * at the top level) reads as one profile, and a file without a machine id gets a new one,\n * which is kept from the next write on.\n */\nexport function readRunnerConfig(path = runnerConfigPath()): RunnerConfig | null {\n if (!existsSync(path)) return null\n let parsed: unknown\n try {\n parsed = JSON.parse(readFileSync(path, 'utf8'))\n } catch {\n return null\n }\n if (typeof parsed !== 'object' || parsed === null) return null\n const raw = parsed as Record<string, unknown>\n\n let profiles: RunnerProfile[]\n if (Array.isArray(raw.profiles)) {\n profiles = raw.profiles.flatMap((entry) => {\n const profile = readProfile(entry)\n return profile ? [profile] : []\n })\n } else {\n const legacy = readProfile(raw)\n if (!legacy) return null\n profiles = [legacy]\n }\n\n const rawLimits =\n typeof raw.attachments === 'object' && raw.attachments !== null\n ? (raw.attachments as Record<string, unknown>)\n : {}\n return {\n machineId:\n typeof raw.machineId === 'string' && UuidPattern.test(raw.machineId)\n ? raw.machineId\n : randomUUID(),\n ...(typeof raw.name === 'string' ? { name: raw.name } : {}),\n profiles,\n attachments: {\n maxCount: validLimit(rawLimits.maxCount, DefaultAttachmentMaxCount),\n maxBytes: validLimit(rawLimits.maxBytes, DefaultAttachmentMaxBytes),\n },\n }\n}\n\nexport function writeRunnerConfig(config: RunnerConfig, path = runnerConfigPath()): void {\n mkdirSync(dirname(path), { recursive: true, mode: 0o700 })\n const document = {\n machineId: config.machineId,\n ...(config.name ? { name: config.name } : {}),\n attachments: config.attachments,\n profiles: config.profiles.map((profile) => ({\n ...(profile.organization ? { organization: profile.organization } : {}),\n url: profile.url,\n token: profile.token,\n workspaces: profile.workspaces,\n repoRoots: profile.repoRoots,\n })),\n }\n writeFileSync(path, `${JSON.stringify(document, null, 2)}\\n`, { mode: 0o600 })\n // The mode argument only applies on creation; narrow a file someone widened.\n chmodSync(path, 0o600)\n}\n\n/** How the runner names a profile in its log and its messages. */\nexport function profileLabel(profile: Pick<RunnerProfile, 'organization' | 'url'>): string {\n if (profile.organization) return profile.organization\n try {\n return new URL(profile.url).host\n } catch {\n return profile.url\n }\n}\n\n/**\n * A profile's identity for the runner's own bookkeeping (the floor), never its secret: keys\n * end up in messages, and a secret must not.\n */\nexport function profileKey(profile: Pick<RunnerProfile, 'token'>): string {\n return createHash('sha256').update(profile.token).digest('hex').slice(0, 16)\n}\n\nexport function sameInstance(left: string, right: string): boolean {\n return left.replace(/\\/+$/, '').toLowerCase() === right.replace(/\\/+$/, '').toLowerCase()\n}\n\nconst UuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i\n\nfunction readProfile(value: unknown): RunnerProfile | null {\n if (typeof value !== 'object' || value === null) return null\n const { url, token, organization, workspaces, repoRoots } = value as Record<string, unknown>\n if (typeof url !== 'string' || typeof token !== 'string') return null\n\n const mapped: Record<string, string> = {}\n if (typeof workspaces === 'object' && workspaces !== null) {\n for (const [key, path] of Object.entries(workspaces)) {\n if (typeof path === 'string') mapped[key] = path\n }\n }\n const roots = Array.isArray(repoRoots)\n ? repoRoots.filter((root): root is string => typeof root === 'string' && root.trim() !== '')\n : []\n return {\n url,\n token,\n ...(typeof organization === 'string' && organization !== '' ? { organization } : {}),\n workspaces: mapped,\n repoRoots: roots,\n }\n}\n\nfunction validLimit(value: unknown, fallback: number): number {\n return typeof value === 'number' && Number.isSafeInteger(value) && value >= 0 ? value : fallback\n}\n","import { spawn } from 'node:child_process'\nimport { chmodSync, mkdirSync, realpathSync, rmSync, writeFileSync } from 'node:fs'\nimport { homedir } from 'node:os'\nimport { isAbsolute, join, relative, resolve } from 'node:path'\nimport { RunFailure, type ClaimedRun, type RunAttachment } from './types.js'\n\nexport const DefaultAttachmentMaxCount = 25\nexport const DefaultAttachmentMaxBytes = 25 * 1024 * 1024\n\n/** The runner's small agent-token-only view of item attachments. */\nexport interface AttachmentProvider {\n list(): Promise<RunAttachment[]>\n download(attachmentId: string): Promise<Uint8Array>\n}\n\n/**\n * Where a run's work happens. Everything the runner writes for a run lives in\n * `<root>/<runId>/`; the harness works in `repo/` below it. The prompt, the MCP config and\n * the askpass script sit beside the checkout rather than in it, so nothing the agent\n * commits can carry them.\n */\nexport interface WorkspaceOptions {\n root: string\n /** project key → local repository path, from runner.json `workspaces` */\n repositories: Record<string, string>\n /**\n * Directories, from runner.json `repoRoots`, under which the project's path hint is trusted\n * when the project has no explicit mapping. Empty means the hint is never used.\n */\n repoRoots?: string[]\n keep: boolean\n mcpServer: { command: string; args: string[] }\n /** runner milestones, streamed as `event` log chunks */\n event: (line: string) => void\n /** fetches a fresh GitHub installation token when the claimed one is missing/expired (POST /runner/runs/{id}/repo-token) */\n refreshCloneToken?: () => Promise<string | null>\n /** Where `github` repositories are cloned from; tests point it at a local bare repository. */\n githubBaseUrl?: string\n env?: NodeJS.ProcessEnv\n signal?: AbortSignal\n /** Optional because old instances do not yet expose the attachment list endpoint. */\n attachments?: AttachmentProvider\n /** Limits for files outside the checkout. Zero disables provisioning. */\n attachmentMaxCount?: number\n attachmentMaxBytes?: number\n}\n\nexport interface Workspace {\n runDir: string\n checkout: string\n branch: string\n promptFile: string\n mcpConfigFile: string\n attachmentsDir: string\n /** The source prompt plus the runner-generated attachment inventory. */\n prompt: string\n /** Extra environment for the harness process (the push credential for a `github` clone). */\n env: Record<string, string>\n /** removes the worktree (git worktree remove --force + prune in the source repo) or clone, then the run dir; no-op when keep; never throws */\n cleanup(): Promise<void>\n}\n\nexport function defaultWorkspaceRoot(env: NodeJS.ProcessEnv = process.env): string {\n const base = env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share')\n return join(base, 'aictiq', 'runner')\n}\n\nexport const TOKEN_ENV = 'AICTIQ_GIT_TOKEN'\n\n// Answers only `get`: git also calls helpers with `store` after a successful push, and the\n// token must not end up anywhere but this process's environment.\nexport const CREDENTIAL_HELPER = `!f() { test \"$1\" = get || return 0; echo username=x-access-token; echo \"password=$${TOKEN_ENV}\"; }; f`\n\nexport const ASKPASS_SCRIPT = `#!/bin/sh\ncase \"$1\" in\n *[Uu]sername*) echo x-access-token ;;\n *) echo \"$${TOKEN_ENV}\" ;;\nesac\n`\n\nexport async function provisionWorkspace(\n run: ClaimedRun,\n options: WorkspaceOptions,\n): Promise<Workspace> {\n // The run id becomes a directory name; anything path-like in it is refused outright.\n if (!/^[A-Za-z0-9][A-Za-z0-9_-]*$/.test(run.runId)) {\n throw new RunFailure(\n 'workspace-failed',\n `Refusing to create a workspace for run id \"${run.runId}\".`,\n )\n }\n\n const runDir = join(options.root, run.runId)\n const checkout = join(runDir, 'repo')\n const promptFile = join(runDir, 'prompt.md')\n const mcpConfigFile = join(runDir, 'mcp.json')\n const attachmentsDir = join(runDir, 'attachments')\n const env = options.env ?? process.env\n\n let source: string | null = null\n const cleanup = async (): Promise<void> => {\n if (options.keep) return\n if (source !== null) {\n await git(['worktree', 'remove', '--force', checkout], { cwd: source, env }).catch(\n () => undefined,\n )\n await git(['worktree', 'prune'], { cwd: source, env }).catch(() => undefined)\n }\n try {\n rmSync(runDir, { recursive: true, force: true })\n } catch {\n // Cleanup is best effort; a leftover directory is not a failed run.\n }\n }\n\n mkdirSync(options.root, { recursive: true, mode: 0o700 })\n // A leftover directory from an earlier attempt would make `worktree add` or `clone` refuse.\n rmSync(runDir, { recursive: true, force: true })\n mkdirSync(runDir, { mode: 0o700 })\n chmodSync(runDir, 0o700)\n\n try {\n const mcpConfig = {\n mcpServers: { aictiq: { command: options.mcpServer.command, args: options.mcpServer.args } },\n }\n writePrivate(mcpConfigFile, `${JSON.stringify(mcpConfig, null, 2)}\\n`)\n\n await assertRefName(run.branchName, 'branch', env)\n await assertRefName(run.defaultBranch, 'default branch', env)\n\n let harnessEnv: Record<string, string> = {}\n if (run.repo.source === 'local') {\n source = await provisionLocal(run, checkout, options, env)\n } else {\n harnessEnv = await provisionGithub(run, runDir, checkout, options, env)\n }\n\n const prompt = await provisionAttachments(run, attachmentsDir, options)\n writePrivate(promptFile, prompt)\n\n return {\n runDir,\n checkout,\n branch: run.branchName,\n promptFile,\n mcpConfigFile,\n attachmentsDir,\n prompt,\n env: harnessEnv,\n cleanup,\n }\n } catch (error) {\n await cleanup()\n throw error\n }\n}\n\nasync function provisionAttachments(run: ClaimedRun, attachmentsDir: string, options: WorkspaceOptions): Promise<string> {\n if (!options.attachments) return run.prompt\n const maxCount = limit(options.attachmentMaxCount, DefaultAttachmentMaxCount)\n const maxBytes = limit(options.attachmentMaxBytes, DefaultAttachmentMaxBytes)\n if (maxCount === 0 || maxBytes === 0) {\n options.event('Attachment provisioning is disabled by this runner configuration')\n return `${run.prompt}\\n\\n## Attachments\\n\\nAttachment provisioning is disabled on this runner. Use the attachment download URL from Aictiq if needed.\\n`\n }\n\n let attachments: RunAttachment[]\n try {\n attachments = await options.attachments.list()\n } catch (error) {\n // A missing list endpoint or a transient instance error must not prevent a code run.\n options.event(`Could not list item attachments: ${message(error)}`)\n return run.prompt\n }\n if (attachments.length === 0) return run.prompt\n\n mkdirSync(attachmentsDir, { recursive: true, mode: 0o700 })\n chmodSync(attachmentsDir, 0o700)\n let total = 0\n const names = new Set<string>()\n const provisioned: Array<RunAttachment & { localName: string }> = []\n\n for (const attachment of attachments) {\n if (provisioned.length >= maxCount) {\n options.event(`Skipped attachment \"${attachment.fileName}\" (limit: ${maxCount} files)`)\n continue\n }\n if (!Number.isSafeInteger(attachment.sizeBytes) || attachment.sizeBytes < 0 || total + attachment.sizeBytes > maxBytes) {\n options.event(`Skipped attachment \"${attachment.fileName}\" (would exceed ${formatBytes(maxBytes)} total)`)\n continue\n }\n try {\n const bytes = await options.attachments.download(attachment.id)\n if (bytes.byteLength > attachment.sizeBytes || total + bytes.byteLength > maxBytes) {\n options.event(`Skipped attachment \"${attachment.fileName}\" (download exceeds ${formatBytes(maxBytes)} total)`)\n continue\n }\n const name = uniqueFileName(sanitiseFileName(attachment.fileName, attachment.id), names)\n writePrivate(join(attachmentsDir, name), bytes)\n total += bytes.byteLength\n provisioned.push({ ...attachment, localName: name })\n } catch (error) {\n // One unavailable blob is useful information, but never a reason to fail the run.\n options.event(`Failed to download attachment \"${attachment.fileName}\": ${message(error)}`)\n }\n }\n\n if (provisioned.length === 0) return run.prompt\n options.event(`Provisioned ${provisioned.length} attachment${provisioned.length === 1 ? '' : 's'}: ${provisioned.map(x => x.localName).join(', ')}`)\n const inventory = provisioned.map((attachment) => {\n const source = attachment.commentId ? `comment ${attachment.commentId}` : 'item description'\n const url = `/api/v1/orgs/${encodeURIComponent(run.organizationSlug)}/attachments/${encodeURIComponent(attachment.id)}/download`\n return `- ${join(attachmentsDir, attachment.localName)} - original: ${attachment.fileName}; ${attachment.contentType}; ${formatBytes(attachment.sizeBytes)}; from ${source}; replaces ${url}`\n }).join('\\n')\n const images = provisioned.filter(attachment => attachment.contentType.startsWith('image/'))\n return `${run.prompt}\\n\\n## Attachments\\n\\nThese files are outside the git checkout at \\`${attachmentsDir}\\`; do not add or commit them. ${images.length > 0 ? 'Look at these images before planning.' : ''}\\n\\n${inventory}\\n`\n}\n\nfunction limit(value: number | undefined, fallback: number): number {\n return Number.isSafeInteger(value) && value !== undefined && value >= 0 ? value : fallback\n}\n\nfunction sanitiseFileName(value: string, id: string): string {\n const clean = value.replace(/[\\\\/\\p{Cc}]/gu, '_').trim().replace(/^\\.+$/, '')\n return (clean || `attachment-${id}`).slice(0, 200)\n}\n\nfunction uniqueFileName(value: string, existing: Set<string>): string {\n const extension = value.lastIndexOf('.') > 0 ? value.slice(value.lastIndexOf('.')) : ''\n const stem = extension ? value.slice(0, -extension.length) : value\n let candidate = value\n let sequence = 2\n while (existing.has(candidate.toLocaleLowerCase())) candidate = `${stem}-${sequence++}${extension}`\n existing.add(candidate.toLocaleLowerCase())\n return candidate\n}\n\nfunction formatBytes(value: number): string {\n return value >= 1024 * 1024 ? `${(value / (1024 * 1024)).toFixed(1)} MiB` : `${value} bytes`\n}\n\n/**\n * The clone a runner-local run works from: the explicit `workspaces` mapping, else the\n * project's path hint when it lies inside one of the runner's `repoRoots`. The hint comes\n * from the server, so it is only trusted inside directories this machine's operator named;\n * symlinks and `..` are resolved before that check. `root` is null for an explicit mapping.\n */\nfunction resolveLocalRepository(\n run: ClaimedRun,\n options: WorkspaceOptions,\n): { path: string; root: string | null } {\n const mapped = options.repositories[run.projectKey]\n if (mapped !== undefined) return { path: mapped, root: null }\n\n const hint = run.repo.localPathHint?.trim()\n const roots = options.repoRoots ?? []\n if (hint) {\n const expanded = expandHome(hint)\n if (isAbsolute(expanded)) {\n const real = realpathOrSelf(expanded)\n for (const configured of roots) {\n const expandedRoot = expandHome(configured)\n if (!isAbsolute(expandedRoot)) continue\n const root = realpathOrSelf(expandedRoot)\n if (isWithin(real, root)) return { path: real, root }\n }\n }\n }\n\n const example = `(\"${run.projectKey}\": \"/path/to/repository\")`\n const detail = !hint\n ? ` Add it to the \\`workspaces\\` map in runner.json ${example}, or set the project's path hint and list its parent directory in \\`repoRoots\\`.`\n : roots.length === 0\n ? ` The project suggests ${hint}. Add its parent directory to \\`repoRoots\\` in runner.json (\\`aictiq runner root <path>\\`), or map it in \\`workspaces\\` ${example}.`\n : ` The project suggests ${hint}, which is not under any of this runner's repoRoots (${roots.join(', ')}). Add a root that contains it, or map it in \\`workspaces\\` ${example}.`\n throw new RunFailure(\n 'no-local-repository',\n `No local repository is mapped for project ${run.projectKey}.${detail}`,\n )\n}\n\nfunction expandHome(path: string): string {\n if (path === '~') return homedir()\n return path.startsWith('~/') ? join(homedir(), path.slice(2)) : path\n}\n\n/** The canonical path; a path that does not exist yet is still normalised (`..`, `.`). */\nfunction realpathOrSelf(path: string): string {\n const normalised = resolve(path)\n try {\n return realpathSync(normalised)\n } catch {\n return normalised\n }\n}\n\n/** True when `path` is `root` itself or below it. Both should already be real paths. */\nfunction isWithin(path: string, root: string): boolean {\n const rel = relative(root, path)\n return rel === '' || (!rel.startsWith('..') && !isAbsolute(rel))\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nasync function provisionLocal(\n run: ClaimedRun,\n checkout: string,\n options: WorkspaceOptions,\n env: NodeJS.ProcessEnv,\n): Promise<string | null> {\n const { path: mapped, root } = resolveLocalRepository(run, options)\n const origin = root === null ? 'mapped for project' : 'the path hint for project'\n\n const toplevel = await git(['rev-parse', '--show-toplevel'], {\n cwd: mapped,\n env,\n signal: options.signal,\n }).catch((error: unknown) => {\n if (isAbort(error)) throw error\n throw new RunFailure(\n 'no-local-repository',\n `${mapped}, ${origin} ${run.projectKey}, is not a git repository.`,\n )\n })\n // A hinted directory that is not a clone itself would otherwise resolve to whatever\n // repository encloses it, e.g. a dotfiles repository in the home directory.\n if (root !== null && !isWithin(realpathOrSelf(toplevel.trim()), root)) {\n throw new RunFailure(\n 'no-local-repository',\n `${mapped}, the path hint for project ${run.projectKey}, is not a git repository under ${root}.`,\n )\n }\n const repo = toplevel.trim()\n const call = (args: string[]) => gitStep(args, { cwd: repo, env, signal: options.signal })\n\n const hasOrigin = await git(['remote', 'get-url', 'origin'], {\n cwd: repo,\n env,\n signal: options.signal,\n }).then(\n () => true,\n (error: unknown) => {\n if (isAbort(error)) throw error\n return false\n },\n )\n if (run.workOnDefaultBranch && !hasOrigin) {\n // The isolated clone has nowhere to push, and it is deleted after the run: the agent's\n // commits would be lost while the run still reported success.\n throw new RunFailure(\n 'no-remote',\n `${repo}, ${origin} ${run.projectKey}, has no origin remote to push ${run.branchName} to. Direct delivery needs one; add it with \\`git remote add origin <url>\\` or use branch-and-pull-request delivery.`,\n )\n }\n\n let base = run.defaultBranch\n if (hasOrigin) {\n options.event(`Fetching origin in ${repo}`)\n await call(['fetch', 'origin'])\n base = `origin/${run.defaultBranch}`\n }\n\n if (run.workOnDefaultBranch) {\n // The default branch is often already checked out by the developer. An independent\n // clone avoids worktree conflicts and leaves their branch, files and index alone.\n await call(['clone', '--no-hardlinks', '--', repo, checkout])\n const isolated = (args: string[]) =>\n gitStep(args, { cwd: checkout, env, signal: options.signal })\n const remote = (await git(['remote', 'get-url', 'origin'], { cwd: repo, env })).trim()\n // Resolve relative local remotes against the source repository, not the new clone.\n const remoteUrl =\n isAbsolute(remote) || /^[A-Za-z][A-Za-z0-9+.-]*:/.test(remote) || /^[^/]+:/.test(remote)\n ? remote\n : resolve(repo, remote)\n await isolated(['remote', 'set-url', 'origin', remoteUrl])\n await isolated(['fetch', 'origin'])\n await isolated(['checkout', '-B', run.branchName, `origin/${run.branchName}`])\n await isolated(['branch', '--set-upstream-to', `origin/${run.branchName}`, run.branchName])\n options.event(`Created isolated clone ${checkout} on default branch ${run.branchName}`)\n return null\n }\n\n const branchExists = await git(\n ['rev-parse', '--verify', '--quiet', `refs/heads/${run.branchName}`],\n {\n cwd: repo,\n env,\n signal: options.signal,\n },\n ).then(\n () => true,\n (error: unknown) => {\n if (isAbort(error)) throw error\n return false\n },\n )\n\n if (branchExists) {\n // A retried run: its branch may already carry the previous attempt's commits.\n await call(['worktree', 'add', checkout, run.branchName])\n options.event(`Created worktree ${checkout} on existing branch ${run.branchName}`)\n } else {\n // --no-track: the new branch must not have the default branch as its upstream, or a bare\n // `git push` from the agent could land on it.\n await call(['worktree', 'add', '--no-track', '-b', run.branchName, checkout, base])\n options.event(`Created worktree ${checkout} on branch ${run.branchName} from ${base}`)\n }\n return repo\n}\n\nasync function provisionGithub(\n run: ClaimedRun,\n runDir: string,\n checkout: string,\n options: WorkspaceOptions,\n env: NodeJS.ProcessEnv,\n): Promise<Record<string, string>> {\n const full = run.repo.repoFullName\n if (!full || !/^[A-Za-z0-9_.-]+\\/[A-Za-z0-9_.-]+$/.test(full)) {\n throw new RunFailure(\n 'workspace-failed',\n `The run names no valid GitHub repository (${full ?? 'none'}).`,\n )\n }\n\n const token = run.repo.cloneToken ?? (await options.refreshCloneToken?.()) ?? null\n if (!token) {\n throw new RunFailure(\n 'repository-token-unavailable',\n `No GitHub installation token is available to clone ${full}. Check that the GitHub App is still installed on the repository.`,\n )\n }\n\n // The token reaches git only through the environment: the askpass script prints it when\n // asked, so it is never in argv (readable through /proc), the remote URL or .git/config.\n const askpass = join(runDir, 'askpass.sh')\n writeFileSync(askpass, ASKPASS_SCRIPT, { mode: 0o700 })\n chmodSync(askpass, 0o700)\n const secretEnv: Record<string, string> = { GIT_ASKPASS: askpass, [TOKEN_ENV]: token }\n const cloneEnv = { ...env, ...secretEnv }\n\n const base = (options.githubBaseUrl ?? 'https://github.com').replace(/\\/+$/, '')\n const url = `${base}/${full}.git`\n await gitStep(\n // An empty credential.helper resets the user's own helpers, so a global `store` helper\n // cannot write the token to ~/.git-credentials after the clone succeeds.\n [\n '-c',\n 'credential.helper=',\n 'clone',\n '--depth',\n '50',\n '--branch',\n run.defaultBranch,\n url,\n checkout,\n ],\n { cwd: runDir, env: cloneEnv, signal: options.signal },\n token,\n )\n options.event(`Cloned ${full} (depth 50)`)\n\n const call = (args: string[]) =>\n gitStep(args, { cwd: checkout, env, signal: options.signal }, token)\n if (!run.workOnDefaultBranch) {\n await call(['checkout', '-b', run.branchName])\n options.event(`Created branch ${run.branchName} from ${run.defaultBranch}`)\n }\n\n // So the agent can push: a helper that reads the token from the harness's environment.\n await call(['config', '--local', '--replace-all', 'credential.helper', ''])\n await call(['config', '--local', '--add', 'credential.helper', CREDENTIAL_HELPER])\n\n return { [TOKEN_ENV]: token }\n}\n\nfunction writePrivate(path: string, content: string | Uint8Array): void {\n writeFileSync(path, content, { mode: 0o600 })\n chmodSync(path, 0o600)\n}\n\nasync function assertRefName(name: string, what: string, env: NodeJS.ProcessEnv): Promise<void> {\n // Also refuses names starting with `-`, which git would otherwise read as an option.\n const valid = await git(['check-ref-format', '--branch', name], { cwd: process.cwd(), env }).then(\n () => true,\n () => false,\n )\n if (!valid)\n throw new RunFailure(\n 'workspace-failed',\n `The run's ${what} \"${name}\" is not a valid git branch name.`,\n )\n}\n\ninterface GitOptions {\n cwd: string\n env: NodeJS.ProcessEnv\n signal?: AbortSignal | undefined\n}\n\nclass GitError extends Error {\n readonly stderr: string\n constructor(args: string[], code: number | null, stderr: string) {\n super(\n `git ${args[0] === '-c' ? (args[2] ?? '') : (args[0] ?? '')} exited with ${code ?? 'a signal'}`,\n )\n this.stderr = stderr\n }\n}\n\n/** A step whose failure fails the run, with git's own words in the message. */\nasync function gitStep(args: string[], options: GitOptions, secret?: string): Promise<string> {\n try {\n return await git(args, options)\n } catch (error) {\n if (error instanceof GitError) {\n const tail = error.stderr.trim().split('\\n').slice(-20).join('\\n')\n let message = tail ? `${error.message}:\\n${tail}` : error.message\n if (secret) message = message.replaceAll(secret, '***')\n throw new RunFailure('workspace-failed', message)\n }\n throw error\n }\n}\n\nfunction git(args: string[], options: GitOptions): Promise<string> {\n return new Promise((resolve, reject) => {\n const child = spawn('git', args, {\n cwd: options.cwd,\n env: { ...options.env, GIT_TERMINAL_PROMPT: '0' },\n stdio: ['ignore', 'pipe', 'pipe'],\n signal: options.signal,\n })\n let stdout = ''\n let stderr = ''\n child.stdout.setEncoding('utf8').on('data', (chunk: string) => (stdout += chunk))\n child.stderr.setEncoding('utf8').on('data', (chunk: string) => {\n // Only the tail is ever reported; a long fetch must not grow this without bound.\n stderr = (stderr + chunk).slice(-16_384)\n })\n child.on('error', reject)\n child.on('close', (code) => {\n if (code === 0) resolve(stdout)\n else reject(new GitError(args, code, stderr))\n })\n })\n}\n\nfunction isAbort(error: unknown): boolean {\n return error instanceof Error && error.name === 'AbortError'\n}\n","/**\n * The runner's shared vocabulary: what the instance hands over on a claim\n * (`RunnerRunClaimed`), what the runner reports about itself (`RunnerCapabilities`, v1),\n * and the seams between the poll loop, the workspace and the harness adapters.\n */\n\nexport type HarnessName = 'claude' | 'codex' | 'opencode'\n\nexport interface HarnessInfo {\n name: string\n version: string | null\n}\n\n/** `RunnerCapabilities` on the server - a versioned contract, not an implementation detail. */\nexport interface RunnerCapabilities {\n v: 1\n harnesses: HarnessInfo[]\n os: string | null\n arch: string | null\n cliVersion: string | null\n maxParallel: number\n /** The same for every organization this machine serves; groups them in the web UI, authorizes nothing. */\n machineId?: string\n}\n\nexport interface RunnerHello {\n runnerId: string\n name: string\n organizationSlug: string\n heartbeatIntervalSeconds: number\n pollTimeoutSeconds: number\n maxLogBytes: number\n maxLogBatchBytes: number\n maxRunMinutes: number\n}\n\nexport interface RunRepo {\n /** `github` when the project has a binding, `local` when the runner finds the working copy. */\n source: 'github' | 'local'\n repoFullName: string | null\n cloneToken: string | null\n localPathHint: string | null\n}\n\n/** Metadata for an item attachment which the runner can make available beside its checkout. */\nexport interface RunAttachment {\n id: string\n fileName: string\n contentType: string\n sizeBytes: number\n /** Undefined for an attachment on the item description itself. */\n commentId?: string | null\n}\n\nexport interface ClaimedRun {\n runId: string\n itemId: string\n itemKey: string\n projectId: string\n projectKey: string\n organizationSlug: string\n harness: string\n prompt: string\n playbookRevisionId: string | null\n repo: RunRepo\n defaultBranch: string\n branchName: string\n /** Absent on older servers: keep the branch-and-PR workflow. */\n workOnDefaultBranch?: boolean\n maxMinutes: number\n aictiqUrl: string | null\n agentToken: string\n agentTokenDisplay: string | null\n heartbeatIntervalSeconds: number\n}\n\nexport type LogStream = 'stdout' | 'stderr' | 'event'\n\nexport type RunnerOutcome = 'succeeded' | 'failed' | 'cancelled'\n\nexport interface FinishReport {\n outcome: RunnerOutcome\n exitCode?: number | null\n summary?: string | null\n pullRequestUrl?: string | null\n costUsd?: number | null\n inputTokens?: number | null\n outputTokens?: number | null\n failureReason?: string | null\n}\n\n/** One stdout line of a harness, as the adapter reads it. */\nexport interface ParsedLine {\n /** What goes into the run log; null drops the line (e.g. a noisy init event). */\n log: string | null\n progress?: string\n costUsd?: number\n inputTokens?: number\n outputTokens?: number\n /** The cost and token counts are this step's alone, to add to the run's total rather than replace it. */\n accumulate?: boolean\n /** A final answer the harness produced, used as the success summary. */\n result?: string\n}\n\nexport interface HarnessInvocation {\n command: string\n args: string[]\n /** Written to the child's stdin and then closed, when the harness reads its prompt there. */\n stdin?: string\n env?: Record<string, string>\n}\n\nexport interface HarnessOutcome {\n outcome: 'succeeded' | 'failed'\n summary: string | null\n failureReason: string | null\n}\n\n/** Everything an adapter may need to start a harness for one run. */\nexport interface InvocationContext {\n prompt: string\n promptFile: string\n /** The git checkout the harness works in (its cwd). */\n workspace: string\n /** Read-only, per-run files that live beside the checkout and must never be committed. */\n attachmentsDir: string\n /**\n * A Claude-style MCP config (`{ mcpServers: { aictiq: { command, args } } }`) written\n * outside the checkout, so nothing the agent might commit carries it.\n */\n mcpConfigFile: string\n /** The same server as a command line, for harnesses configured by flags or their own file. */\n mcpServer: { command: string; args: string[] }\n}\n\nexport interface HarnessAdapter {\n readonly name: HarnessName\n /** The executable's `--version`, or null when it is not on PATH. */\n available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null>\n /**\n * How to start the harness. The prompt is already in `promptFile` (0600, outside the\n * checkout): adapters pass it on stdin or by path rather than in argv, which has a length\n * limit and is readable by every user through /proc.\n */\n invocation(context: InvocationContext): HarnessInvocation\n parse(line: string): ParsedLine\n outcome(exitCode: number | null, lastLines: string[], lastResult: string | null): HarnessOutcome\n}\n\n/** A failure the runner reports as the run's `failureReason` rather than crashing on. */\nexport class RunFailure extends Error {\n readonly reason: string\n constructor(reason: string, message: string) {\n super(message)\n this.name = 'RunFailure'\n this.reason = reason\n }\n}\n","import { execFile } from 'node:child_process'\nimport { stripVTControlCharacters } from 'node:util'\nimport { RunnerHttpError, RunnerNetworkError } from './client.js'\nimport type { RunnerClient } from './client.js'\nimport { LogStreamer } from './log.js'\nimport { spawnSupervised } from './process.js'\nimport type { SupervisedProcess } from './process.js'\nimport { RunFailure } from './types.js'\nimport type { ClaimedRun, FinishReport, HarnessAdapter, RunnerHello } from './types.js'\nimport { provisionWorkspace } from './workspace.js'\nimport type { Workspace, WorkspaceOptions } from './workspace.js'\n\nconst MaxSummary = 4000\nconst MaxFailureReason = 500\nconst PullRequestUrl = /https:\\/\\/github\\.com\\/[\\w.-]+\\/[\\w.-]+\\/pull\\/\\d+/g\n\nexport interface ExecuteOptions {\n client: RunnerClient\n hello: RunnerHello\n adapters: Partial<Record<string, HarnessAdapter>>\n /** Workspace settings shared by every run; the per-run hooks are filled in here. */\n workspace: Omit<WorkspaceOptions, 'event' | 'refreshCloneToken' | 'signal'>\n /** The runner's own secret, redacted from the log like the run's tokens. */\n runnerToken: string\n /** The runner is shutting down and will not wait: stop the harness and report `cancelled`. */\n shutdown?: AbortSignal\n /** Runner-side messages for the operator's terminal (never sent to the instance). */\n local?: (message: string) => void\n provision?: (run: ClaimedRun, options: WorkspaceOptions) => Promise<Workspace>\n findPullRequest?: (\n checkout: string,\n branch: string,\n env: NodeJS.ProcessEnv,\n ) => Promise<string | null>\n heartbeatMs?: number\n graceMs?: number\n flushIntervalMs?: number\n}\n\n/**\n * Executes one claimed run from `started` to `finish`. The runner decides nothing about\n * the item - transitions, the outcome comment and the claim release are the server's\n * business once `finish` lands. What it does own: a workspace, a harness process,\n * the log, the heartbeat, and killing the process when told to or when time runs out.\n *\n * Returns the report it sent, or null when the server had already closed the run (a\n * sweeper's verdict, or a finish that was refused as a duplicate) and there was nothing\n * left to report.\n */\nexport async function executeRun(\n run: ClaimedRun,\n options: ExecuteOptions,\n): Promise<FinishReport | null> {\n const { client } = options\n const local = options.local ?? (() => {})\n const log = new LogStreamer({\n send: (chunks) => client.log(run.runId, chunks),\n secrets: [run.agentToken, options.runnerToken, run.repo.cloneToken ?? ''],\n maxBatchBytes: options.hello.maxLogBatchBytes,\n flushIntervalMs: options.flushIntervalMs ?? 1000,\n local: (message) => local(`${run.itemKey}: ${message}`),\n })\n const event = (line: string) => log.push('event', line)\n\n let harness: SupervisedProcess | undefined\n let stopReason: 'cancelled' | 'timed-out' | 'shutdown' | 'closed' | undefined\n const abort = new AbortController()\n const stop = (reason: NonNullable<typeof stopReason>) => {\n if (stopReason) return\n stopReason = reason\n abort.abort()\n void harness?.stop(options.graceMs ?? 10_000)\n }\n\n const onShutdown = () => stop('shutdown')\n options.shutdown?.addEventListener('abort', onShutdown, { once: true })\n if (options.shutdown?.aborted) onShutdown()\n\n let workspace: Workspace | undefined\n let revoked: RunnerHttpError | undefined\n let heartbeat: NodeJS.Timeout | undefined\n let beating: Promise<void> = Promise.resolve()\n let deadline: NodeJS.Timeout | undefined\n\n const report = await (async (): Promise<FinishReport | null> => {\n try {\n await client.started(run.runId)\n } catch (error) {\n // 409: the run was cancelled or swept between the claim and now. Nothing to execute.\n if (error instanceof RunnerHttpError && (error.status === 409 || error.status === 404)) {\n local(`${run.itemKey}: the instance closed run ${run.runId} before it started`)\n return null\n }\n throw error\n }\n event(`Runner picked up ${run.itemKey} with ${run.harness}`)\n\n // The heartbeat starts before anything slow: the item's claim was taken at dispatch and\n // goes stale if nobody refreshes it while the workspace is being cloned.\n const beat = async () => {\n try {\n const { cancelRequested } = await client.runHeartbeat(run.runId)\n if (cancelRequested) {\n event('Cancel requested; stopping the harness')\n stop('cancelled')\n }\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) {\n // The runner's secret is dead, so no finish can land either: stop now and let the\n // loop exit rather than run the harness on until the next runner heartbeat.\n revoked ??= error\n stop('closed')\n return\n }\n if (error instanceof RunnerHttpError && (error.status === 409 || error.status === 404)) {\n local(`${run.itemKey}: the instance closed run ${run.runId}; stopping it here`)\n stop('closed')\n return\n }\n local(`${run.itemKey}: run heartbeat failed: ${message(error)}`)\n }\n try {\n await client.itemHeartbeat(run)\n } catch (error) {\n local(`${run.itemKey}: item heartbeat failed: ${message(error)}`)\n }\n }\n const tick = () => {\n beating = beat()\n }\n tick()\n heartbeat = setInterval(\n tick,\n options.heartbeatMs ?? run.heartbeatIntervalSeconds * 1000,\n )\n deadline = setTimeout(() => {\n event(`The run reached its limit of ${run.maxMinutes} minutes; stopping the harness`)\n stop('timed-out')\n }, run.maxMinutes * 60_000)\n\n const adapter = options.adapters[run.harness]\n const info = adapter ? await adapter.available() : null\n if (!adapter || !info) {\n event(`Harness \"${run.harness}\" is not installed on this runner`)\n return failed(\n 'harness-unavailable',\n `This runner has no working \"${run.harness}\" on its PATH.`,\n )\n }\n event(`Using ${run.harness} ${info.version ?? ''}`.trim())\n\n try {\n workspace = await (options.provision ?? provisionWorkspace)(run, {\n ...options.workspace,\n event,\n refreshCloneToken: () => client.repoToken(run.runId),\n attachments: {\n list: () => client.listAttachments(run),\n download: (attachmentId) => client.downloadAttachment(run, attachmentId),\n },\n signal: abort.signal,\n })\n } catch (error) {\n if (stopReason) return stopped(null, [])\n if (error instanceof RunFailure) {\n event(error.message)\n return failed(error.reason, error.message)\n }\n event(`Workspace provisioning failed: ${message(error)}`)\n return failed('workspace-failed', message(error))\n }\n if (stopReason) return stopped(null, [])\n\n const invocation = adapter.invocation({\n prompt: workspace.prompt,\n promptFile: workspace.promptFile,\n workspace: workspace.checkout,\n attachmentsDir: workspace.attachmentsDir,\n mcpConfigFile: workspace.mcpConfigFile,\n mcpServer: options.workspace.mcpServer,\n })\n const env: NodeJS.ProcessEnv = {\n ...inheritedEnv(process.env),\n ...invocation.env,\n ...workspace.env,\n // The agent reaches the instance as itself, never as the runner: `aictiq mcp` and the\n // CLI both read these, and they exist only in this process tree.\n AICTIQ_URL: run.aictiqUrl ?? client.baseUrl,\n AICTIQ_TOKEN: run.agentToken,\n AICTIQ_ORG: run.organizationSlug,\n AICTIQ_ITEM: run.itemKey,\n AICTIQ_RUN: run.runId,\n }\n\n const lastLines: string[] = []\n let lastResult: string | null = null\n let pullRequestUrl: string | null = null\n let costUsd: number | undefined\n let inputTokens: number | undefined\n let outputTokens: number | undefined\n const remember = (line: string) => {\n lastLines.push(line)\n if (lastLines.length > 20) lastLines.shift()\n }\n\n event(`Starting ${invocation.command} in ${workspace.checkout}`)\n harness = spawnSupervised({\n command: invocation.command,\n args: invocation.args,\n cwd: workspace.checkout,\n env,\n ...(invocation.stdin === undefined ? {} : { stdin: invocation.stdin }),\n onLine: (stream, raw) => {\n // Harnesses colour their errors even into a pipe; the log view and the summary\n // are plain text.\n const line = stripVTControlCharacters(raw)\n if (!run.workOnDefaultBranch) {\n for (const match of line.matchAll(PullRequestUrl)) pullRequestUrl = match[0]\n }\n if (stream === 'stderr') {\n log.push('stderr', line)\n remember(line)\n return\n }\n const parsed = adapter.parse(line)\n const tally = (total: number | undefined, value: number | undefined) =>\n value === undefined ? total : parsed.accumulate ? (total ?? 0) + value : value\n costUsd = tally(costUsd, parsed.costUsd)\n inputTokens = tally(inputTokens, parsed.inputTokens)\n outputTokens = tally(outputTokens, parsed.outputTokens)\n if (parsed.result !== undefined) lastResult = parsed.result\n if (parsed.log !== null) {\n log.push('stdout', parsed.log)\n remember(parsed.log)\n }\n },\n })\n // A stop requested while the process was being spawned must still reach it.\n if (stopReason) void harness.stop(options.graceMs ?? 10_000)\n\n const exitCode = await harness.exited\n event(exitCode === null ? 'Harness was killed' : `Harness exited with code ${exitCode}`)\n const usage = { costUsd, inputTokens, outputTokens, exitCode }\n if (stopReason) return stopped(exitCode, lastLines, usage)\n\n const verdict = adapter.outcome(exitCode, lastLines, lastResult)\n if (verdict.outcome === 'succeeded' && !run.workOnDefaultBranch && !pullRequestUrl) {\n pullRequestUrl = await (options.findPullRequest ?? findPullRequest)(\n workspace.checkout,\n run.branchName,\n env,\n )\n }\n if (pullRequestUrl) event(`Pull request: ${pullRequestUrl}`)\n return {\n outcome: verdict.outcome,\n exitCode,\n summary: truncate(verdict.summary, MaxSummary),\n pullRequestUrl,\n failureReason:\n verdict.outcome === 'failed'\n ? truncate(verdict.failureReason ?? 'harness-failed', MaxFailureReason)\n : null,\n costUsd: costUsd ?? null,\n inputTokens: inputTokens ?? null,\n outputTokens: outputTokens ?? null,\n }\n })()\n .catch((error: unknown): FinishReport | null => {\n if (error instanceof RunnerHttpError && error.revoked) throw error\n local(`${run.itemKey}: ${message(error)}`)\n event(`Runner error: ${message(error)}`)\n return failed('runner-error', message(error))\n })\n .finally(() => {\n clearInterval(heartbeat)\n clearTimeout(deadline)\n options.shutdown?.removeEventListener('abort', onShutdown)\n })\n\n if (report?.outcome === 'failed' && report.failureReason)\n event(`Run failed: ${report.failureReason}`)\n // A beat still in flight would otherwise reach the instance after the finish, and its\n // item heartbeat with a token the finish just revoked.\n await beating\n await log.close()\n await workspace?.cleanup()\n if (revoked) throw revoked\n if (!report) return null\n return (await sendFinish(client, run, report, local)) ? report : null\n\n function failed(reason: string, detail: string): FinishReport {\n return {\n outcome: 'failed',\n failureReason: truncate(reason, MaxFailureReason),\n summary: truncate(detail, MaxSummary),\n }\n }\n\n function stopped(\n exitCode: number | null,\n lines: string[],\n usage: Partial<FinishReport> = {},\n ): FinishReport | null {\n const tail = lines.length > 0 ? lines.join('\\n') : null\n switch (stopReason) {\n case 'closed':\n return null\n case 'timed-out':\n // `timed_out` is the server's verdict alone (its sweeper would reach it too); the\n // runner reports a failure whose reason says the same thing.\n return {\n ...usage,\n outcome: 'failed',\n exitCode,\n failureReason: 'timed-out',\n summary: truncate(tail, MaxSummary),\n }\n case 'shutdown':\n return {\n ...usage,\n outcome: 'cancelled',\n exitCode,\n failureReason: 'runner-shutdown',\n summary: 'The runner was stopped before the run finished.',\n }\n default:\n return { ...usage, outcome: 'cancelled', exitCode, summary: truncate(tail, MaxSummary) }\n }\n }\n}\n\n/** Reports the outcome, retrying while the instance is unreachable; false if it was refused. */\nasync function sendFinish(\n client: RunnerClient,\n run: ClaimedRun,\n report: FinishReport,\n local: (message: string) => void,\n): Promise<boolean> {\n for (let attempt = 0; ; attempt++) {\n try {\n await client.finish(run.runId, report)\n local(\n `${run.itemKey}: ${report.outcome}${report.failureReason ? ` (${report.failureReason})` : ''}`,\n )\n return true\n } catch (error) {\n if (error instanceof RunnerNetworkError && attempt < 30) {\n await new Promise((resolve) => setTimeout(resolve, Math.min(30_000, 1000 * 2 ** attempt)))\n continue\n }\n if (error instanceof RunnerHttpError && error.revoked) throw error\n // 409: already finished (a sweeper got there first). Anything else: the server's\n // sweepers will close the run; looping here would only hold the slot.\n local(`${run.itemKey}: could not report the outcome: ${message(error)}`)\n return false\n }\n }\n}\n\n/** `gh pr view <branch>`, when `gh` is installed and signed in; null otherwise. */\nexport function findPullRequest(\n checkout: string,\n branch: string,\n env: NodeJS.ProcessEnv,\n): Promise<string | null> {\n return new Promise((resolve) => {\n execFile(\n 'gh',\n ['pr', 'view', branch, '--json', 'url', '--jq', '.url'],\n { cwd: checkout, env, timeout: 15_000 },\n (error, stdout) => {\n const url = error ? '' : stdout.trim()\n resolve(/^https:\\/\\/\\S+\\/pull\\/\\d+$/.test(url) ? url : null)\n },\n )\n })\n}\n\nfunction truncate(value: string | null | undefined, max: number): string | null {\n if (!value) return null\n return value.length <= max ? value : `${value.slice(0, max - 1)}…`\n}\n\n/**\n * The runner's own environment minus every `AICTIQ_` variable: a person's token, a runner\n * secret passed as `AICTIQ_RUNNER_TOKEN` or another organization's settings must not reach an\n * agent. The run's own `AICTIQ_*` values are added back on top.\n */\nexport function inheritedEnv(env: NodeJS.ProcessEnv): NodeJS.ProcessEnv {\n return Object.fromEntries(Object.entries(env).filter(([key]) => !key.toUpperCase().startsWith('AICTIQ_')))\n}\n\nfunction message(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n","import { RunnerHttpError } from './client.js'\nimport type { LogChunk } from './client.js'\nimport type { LogStream } from './types.js'\n\n/** The server's per-chunk text limit (`RunLogChunk.MaxTextLength`) and per-batch count. */\nconst MaxChunkChars = 65_536\nconst MaxChunksPerBatch = 512\n\nexport interface LogStreamerOptions {\n send: (chunks: LogChunk[]) => Promise<void>\n /** Secrets to blank out of every line before it leaves the machine. */\n secrets: string[]\n maxBatchBytes: number\n flushIntervalMs?: number\n /** Where the runner says something about the log itself (the cap was hit). */\n local?: (message: string) => void\n now?: () => Date\n retryDelayMs?: (attempt: number) => number\n}\n\n/**\n * Replaces each secret with a marker. Longest first, so a secret that contains another\n * (an installation token that happens to share a prefix) is not half-redacted.\n */\nexport function redact(text: string, secrets: readonly string[]): string {\n let result = text\n for (const secret of [...secrets]\n .filter((s) => s.length >= 8)\n .sort((a, b) => b.length - a.length)) {\n result = result.split(secret).join('[redacted]')\n }\n return result\n}\n\n/**\n * Batches log lines for `POST /runner/runs/{id}/log`: every second or when a batch reaches\n * the server's byte limit, whichever comes first. Each line gets its own `seq`, assigned\n * when it is queued, so a failed batch is re-sent with the same numbers and the server's\n * `ON CONFLICT DO NOTHING` makes the overlap harmless. Sends are strictly sequential.\n */\nexport class LogStreamer {\n private readonly options: LogStreamerOptions\n private readonly queue: LogChunk[] = []\n private seq = 0\n private timer: NodeJS.Timeout | undefined\n private sending: Promise<void> = Promise.resolve()\n private capped = false\n private closed = false\n private closing = false\n\n constructor(options: LogStreamerOptions) {\n this.options = options\n }\n\n /** True once the server refused the log for exceeding its cap; later lines are dropped. */\n get truncated(): boolean {\n return this.capped\n }\n\n push(stream: LogStream, line: string): void {\n if (this.capped || this.closed) return\n const text = redact(line, this.options.secrets)\n const at = (this.options.now?.() ?? new Date()).toISOString()\n // A line longer than one chunk may hold (or than one batch may carry) is split, so a\n // minified bundle printed by a build step cannot wedge the stream on a 400.\n for (const piece of splitByBytes(text, Math.min(this.options.maxBatchBytes, MaxChunkChars))) {\n this.queue.push({ seq: this.seq++, stream, text: piece, at })\n }\n\n if (this.queuedBytes() >= this.options.maxBatchBytes) {\n void this.flush()\n } else {\n this.timer ??= setTimeout(() => {\n this.timer = undefined\n void this.flush()\n }, this.options.flushIntervalMs ?? 1000)\n }\n }\n\n /** Sends everything queued so far; resolves once it is stored or the log is capped. */\n flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer)\n this.timer = undefined\n }\n this.sending = this.sending.then(() => this.drain())\n return this.sending\n }\n\n /** Flushes and stops accepting lines. */\n async close(): Promise<void> {\n this.closing = true\n await this.flush()\n this.closed = true\n }\n\n private async drain(): Promise<void> {\n while (this.queue.length > 0 && !this.capped) {\n const batch = this.takeBatch()\n let attempt = 0\n while (true) {\n try {\n await this.options.send(batch)\n this.queue.splice(0, batch.length)\n break\n } catch (error) {\n if (error instanceof RunnerHttpError && error.status === 413) {\n this.capped = true\n this.queue.length = 0\n this.options.local?.(\n 'The instance capped this run log; further output is kept out of it.',\n )\n return\n }\n // 409: the run is finished server-side, so its log is closed for good. Any\n // other refusal is a bug worth not looping on; only the network is retried.\n if (error instanceof RunnerHttpError) {\n this.queue.length = 0\n this.capped = true\n this.options.local?.(`The instance refused the run log: ${error.message}`)\n return\n }\n attempt++\n // While running, the network may come back and the log should survive it; at\n // close the run has to be reported, and a log that cannot be sent must not block it.\n if (attempt > 8 && this.closing) {\n this.queue.length = 0\n return\n }\n await delay(this.options.retryDelayMs?.(attempt) ?? Math.min(30_000, 500 * 2 ** attempt))\n }\n }\n }\n }\n\n private takeBatch(): LogChunk[] {\n const batch: LogChunk[] = []\n let bytes = 0\n for (const chunk of this.queue) {\n const size = Buffer.byteLength(chunk.text, 'utf8')\n if (\n batch.length > 0 &&\n (bytes + size > this.options.maxBatchBytes || batch.length >= MaxChunksPerBatch)\n )\n break\n batch.push(chunk)\n bytes += size\n }\n return batch\n }\n\n private queuedBytes(): number {\n let bytes = 0\n for (const chunk of this.queue) bytes += Buffer.byteLength(chunk.text, 'utf8')\n return bytes\n }\n}\n\n/** Splits on code-point boundaries so that each piece is at most `maxBytes` of UTF-8. */\nexport function splitByBytes(text: string, maxBytes: number): string[] {\n if (Buffer.byteLength(text, 'utf8') <= maxBytes) return [text]\n const pieces: string[] = []\n let current = ''\n let bytes = 0\n for (const char of text) {\n const size = Buffer.byteLength(char, 'utf8')\n if (bytes + size > maxBytes) {\n pieces.push(current)\n current = ''\n bytes = 0\n }\n current += char\n bytes += size\n }\n pieces.push(current)\n return pieces\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n","import { spawn } from 'node:child_process'\nimport type { ChildProcess } from 'node:child_process'\nimport { StringDecoder } from 'node:string_decoder'\n\nexport interface SupervisedProcess {\n readonly pid: number | undefined\n /** Resolves with the exit code, or null when a signal ended it. */\n readonly exited: Promise<number | null>\n /** SIGTERM to the whole process group, then SIGKILL after `graceMs` if it is still there. */\n stop(graceMs?: number): Promise<number | null>\n}\n\nexport interface SpawnOptions {\n command: string\n args: string[]\n cwd: string\n env: NodeJS.ProcessEnv\n stdin?: string\n onLine: (stream: 'stdout' | 'stderr', line: string) => void\n}\n\n/**\n * Starts a harness in its own process group (`detached`), so that stopping it stops what it\n * started too: a coding agent routinely leaves a dev server or a test watcher behind, and\n * signalling only the harness's pid would orphan them on the runner.\n */\nexport function spawnSupervised(options: SpawnOptions): SupervisedProcess {\n const child = spawn(options.command, options.args, {\n cwd: options.cwd,\n env: options.env,\n detached: process.platform !== 'win32',\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n const exited = new Promise<number | null>((resolve) => {\n let settled = false\n const settle = (code: number | null) => {\n if (settled) return\n settled = true\n resolve(code)\n }\n // A missing executable arrives as 'error' with no 'close'; 127 is the shell's answer.\n child.on('error', (error: NodeJS.ErrnoException) => {\n options.onLine('stderr', `Could not start ${options.command}: ${error.message}`)\n settle(error.code === 'ENOENT' ? 127 : 1)\n })\n child.on('close', (code) => {\n settle(code)\n signal(child, 'SIGKILL')\n })\n // 'close' waits for stdout to close, which a background process the harness left\n // behind keeps open indefinitely. Its exit is the verdict; the stragglers get two\n // seconds to flush and then go with the group.\n child.on('exit', (code) => {\n setTimeout(() => {\n settle(code)\n signal(child, 'SIGKILL')\n }, 2000)\n })\n })\n\n splitLines(child, 'stdout', options.onLine)\n splitLines(child, 'stderr', options.onLine)\n child.stdin?.on('error', () => {\n // The harness may exit before reading its prompt; EPIPE is not the runner's failure.\n })\n child.stdin?.end(options.stdin ?? '')\n\n return {\n pid: child.pid,\n exited,\n async stop(graceMs = 10_000) {\n signal(child, 'SIGTERM')\n const timer = setTimeout(() => signal(child, 'SIGKILL'), graceMs)\n try {\n return await exited\n } finally {\n clearTimeout(timer)\n // The harness may be gone while its children linger; the group goes with it.\n signal(child, 'SIGKILL')\n }\n },\n }\n}\n\nfunction signal(child: ChildProcess, name: NodeJS.Signals): void {\n if (child.pid === undefined) return\n try {\n if (process.platform === 'win32') child.kill(name)\n else process.kill(-child.pid, name)\n } catch {\n // ESRCH: already gone.\n }\n}\n\nfunction splitLines(\n child: ChildProcess,\n stream: 'stdout' | 'stderr',\n onLine: (stream: 'stdout' | 'stderr', line: string) => void,\n): void {\n const source = child[stream]\n if (!source) return\n const decoder = new StringDecoder('utf8')\n let buffer = ''\n source.on('data', (data: Buffer) => {\n buffer += decoder.write(data)\n let index: number\n while ((index = buffer.indexOf('\\n')) >= 0) {\n onLine(stream, buffer.slice(0, index).replace(/\\r$/, ''))\n buffer = buffer.slice(index + 1)\n }\n })\n source.on('end', () => {\n buffer += decoder.end()\n if (buffer.length > 0) onLine(stream, buffer)\n buffer = ''\n })\n}\n","import { execFile } from 'node:child_process'\nimport type { HarnessAdapter, HarnessInfo, ParsedLine } from '../types.js'\n\nconst limit = (value: string, length: number) =>\n value.length > length ? `${value.slice(0, Math.max(0, length - 1))}…` : value\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null\n\n/** Reads only the first line: some CLIs add build information after their version. */\nexport function versionOf(\n command: string,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<string | null> {\n return new Promise((resolve) => {\n execFile(command, ['--version'], { env, timeout: 5_000 }, (error, stdout, stderr) => {\n if (error) return resolve(null)\n const output = String(stdout || stderr).trim()\n const firstLine = output.split(/\\r?\\n/)[0]?.slice(0, 100) ?? ''\n resolve(firstLine || null)\n })\n })\n}\n\nfunction failedOutcome(exitCode: number | null, lastLines: string[]) {\n return {\n outcome: 'failed' as const,\n failureReason: exitCode === null ? 'harness-killed' : `harness-exit-${exitCode}`,\n summary: limit(lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n}\n\nexport const claude: HarnessAdapter = {\n name: 'claude',\n\n async available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null> {\n const version = await versionOf('claude', env)\n return version === null ? null : { name: 'claude', version }\n },\n\n invocation(context) {\n return {\n command: 'claude',\n args: [\n '-p',\n '--output-format',\n 'stream-json',\n '--verbose',\n '--permission-mode',\n 'bypassPermissions',\n '--mcp-config',\n context.mcpConfigFile,\n // Claude's working directory remains the checkout. Attachments are deliberately\n // beside it, so grant this one read-only run directory explicitly.\n '--add-dir',\n context.attachmentsDir,\n ],\n // Claude's -p mode consumes stdin when there is no positional prompt.\n stdin: context.prompt,\n }\n },\n\n parse(line): ParsedLine {\n let event: Record<string, unknown>\n try {\n const parsed = JSON.parse(line) as unknown\n event =\n recordOf(parsed) ??\n (() => {\n throw new Error('not an object')\n })()\n } catch {\n return { log: line }\n }\n\n if (event.type === 'system' && event.subtype === 'init') {\n return { log: `[init] model ${typeof event.model === 'string' ? event.model : 'unknown'}` }\n }\n\n if (event.type === 'assistant') {\n const message = recordOf(event.message)\n const content = Array.isArray(message?.content) ? message.content : []\n const logs = content.flatMap((block) => {\n const part = recordOf(block)\n if (!part || part.type === 'thinking') return []\n if (part.type === 'text' && typeof part.text === 'string') return [part.text]\n if (part.type === 'tool_use') {\n const name = typeof part.name === 'string' ? part.name : 'tool'\n const input = limit(JSON.stringify(part.input ?? {}), 200)\n return [`→ ${name} ${input}`]\n }\n return []\n })\n return { log: logs.length > 0 ? logs.join('\\n') : null }\n }\n\n if (event.type === 'user') {\n const message = recordOf(event.message)\n const content = Array.isArray(message?.content) ? message.content[0] : message?.content\n const result = recordOf(content)\n if (result?.type !== 'tool_result') return { log: null }\n const text =\n typeof result.content === 'string' ? result.content : JSON.stringify(result.content ?? '')\n const error = result.is_error === true ? '[error] ' : ''\n return { log: `← ${error}${limit(text.split(/\\r?\\n/)[0] ?? '', 200)}` }\n }\n\n if (event.type === 'result') {\n const usage = recordOf(event.usage)\n const input =\n numberOf(usage?.input_tokens) +\n numberOf(usage?.cache_creation_input_tokens) +\n numberOf(usage?.cache_read_input_tokens)\n return {\n // The marker is what `outcome` reads: the runner keeps the logged lines, not the raw JSON.\n log: `[result] ${typeof event.subtype === 'string' ? event.subtype : 'unknown'}${event.is_error === true ? ' (error)' : ''} in ${numberOf(event.duration_ms)}ms`,\n costUsd: numberOrUndefined(event.total_cost_usd),\n inputTokens: input || undefined,\n outputTokens: numberOrUndefined(usage?.output_tokens),\n result: typeof event.result === 'string' ? event.result : undefined,\n }\n }\n\n return { log: null }\n },\n\n outcome(exitCode, lastLines, lastResult) {\n if (exitCode !== 0) return failedOutcome(exitCode, lastLines)\n // An error result (a refused prompt, an exhausted budget) can still exit 0; the result\n // line `parse` logged is what says so.\n if (lastLines.some((line) => /^\\[result\\] .*\\(error\\)/.test(line))) {\n return { ...failedOutcome(exitCode, lastLines), failureReason: 'harness-error' }\n }\n return {\n outcome: 'succeeded',\n failureReason: null,\n summary: limit(lastResult ?? lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n },\n}\n\nfunction numberOf(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { HarnessAdapter, HarnessInfo, ParsedLine } from '../types.js'\nimport { versionOf } from './claude.js'\n\nconst limit = (value: string, length: number) =>\n value.length > length ? `${value.slice(0, Math.max(0, length - 1))}…` : value\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null\n\nconst MCP_ENV = ['AICTIQ_URL', 'AICTIQ_TOKEN', 'AICTIQ_ORG', 'AICTIQ_ITEM', 'AICTIQ_RUN']\n\nexport const codex: HarnessAdapter = {\n name: 'codex',\n\n async available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null> {\n const version = await versionOf('codex', env)\n return version === null ? null : { name: 'codex', version }\n },\n\n invocation(context) {\n return {\n command: 'codex',\n args: [\n 'exec',\n '--json',\n // 0.154.0 removed --full-auto. The runner is the ticket's explicit trust boundary:\n // the agent needs unrestricted network access for the MCP server and git push.\n '--dangerously-bypass-approvals-and-sandbox',\n // This mode also permits the absolute attachment paths named in prompt.md outside\n // the checkout. The runner itself remains the trust boundary for those files.\n '--skip-git-repo-check',\n '-C',\n context.workspace,\n '-c',\n `mcp_servers.aictiq.command=${JSON.stringify(context.mcpServer.command)}`,\n '-c',\n `mcp_servers.aictiq.args=${JSON.stringify(context.mcpServer.args)}`,\n // Codex starts MCP servers with a scrubbed environment; without this the bridge\n // never sees the run's credential and the handshake fails. Names only - the values\n // stay in the process environment, out of argv.\n '-c',\n `mcp_servers.aictiq.env_vars=${JSON.stringify(MCP_ENV)}`,\n '-',\n ],\n stdin: context.prompt,\n }\n },\n\n parse(line): ParsedLine {\n let event: Record<string, unknown>\n try {\n const parsed = JSON.parse(line) as unknown\n event =\n recordOf(parsed) ??\n (() => {\n throw new Error('not an object')\n })()\n } catch {\n return { log: line }\n }\n\n const item = recordOf(event.item)\n if ((event.type === 'item.completed' || event.type === 'item.started') && item) {\n if (item.type === 'agent_message' && typeof item.text === 'string') {\n return { log: item.text, result: item.text }\n }\n // A command arrives twice, started and completed; log it once, when it starts.\n if (item.type === 'command_execution') {\n if (event.type === 'item.completed') return { log: null }\n const command =\n typeof item.command === 'string' ? item.command : JSON.stringify(item.command ?? '')\n return { log: `→ command ${limit(command, 200)}` }\n }\n if (item.type === 'file_change') {\n const changes = Array.isArray(item.changes) ? item.changes : []\n const paths = changes\n .map((change) => recordOf(change)?.path)\n .filter((path): path is string => typeof path === 'string')\n return { log: paths.length > 0 ? `→ file_change ${limit(paths.join(', '), 200)}` : null }\n }\n }\n\n const usage = usageOf(event)\n if (usage) {\n const input =\n numberOf(usage.input_tokens) +\n numberOf(usage.cached_input_tokens) +\n numberOf(usage.cache_write_input_tokens)\n return {\n log: null,\n inputTokens: input || undefined,\n outputTokens: numberOrUndefined(usage.output_tokens),\n }\n }\n return { log: null }\n },\n\n outcome(exitCode, lastLines, lastResult) {\n if (exitCode !== 0) return failedOutcome(exitCode, lastLines)\n return {\n outcome: 'succeeded',\n failureReason: null,\n summary: limit(lastResult ?? lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n },\n}\n\nfunction usageOf(event: Record<string, unknown>): Record<string, unknown> | null {\n if (event.type === 'turn.completed') return recordOf(event.usage)\n if (event.type === 'token_count') return recordOf(event.usage) ?? recordOf(event.info)\n const payload = recordOf(event.payload)\n if (payload?.type === 'token_count') {\n return recordOf(payload.usage) ?? recordOf(recordOf(payload.info)?.total_token_usage)\n }\n return null\n}\n\nfunction failedOutcome(exitCode: number | null, lastLines: string[]) {\n return {\n outcome: 'failed' as const,\n failureReason: exitCode === null ? 'harness-killed' : `harness-exit-${exitCode}`,\n summary: limit(lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n}\n\nfunction numberOf(value: unknown): number {\n return typeof value === 'number' && Number.isFinite(value) ? value : 0\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { HarnessAdapter, HarnessInfo, ParsedLine } from '../types.js'\nimport { versionOf } from './claude.js'\n\nconst limit = (value: string, length: number) =>\n value.length > length ? `${value.slice(0, Math.max(0, length - 1))}…` : value\n\nconst recordOf = (value: unknown): Record<string, unknown> | null =>\n typeof value === 'object' && value !== null ? (value as Record<string, unknown>) : null\n\nexport const opencode: HarnessAdapter = {\n name: 'opencode',\n\n async available(env?: NodeJS.ProcessEnv): Promise<HarnessInfo | null> {\n const version = await versionOf('opencode', env)\n return version === null ? null : { name: 'opencode', version }\n },\n\n invocation(context) {\n return {\n command: 'opencode',\n // `--file` is a variadic option: anything after it is taken as another file to\n // attach, so the message goes first and the prompt file last.\n args: [\n 'run',\n 'Follow the instructions in the attached file.',\n '--format',\n 'json',\n '--dir',\n context.workspace,\n '--file',\n context.promptFile,\n context.attachmentsDir,\n ],\n env: {\n OPENCODE_CONFIG_CONTENT: JSON.stringify({\n $schema: 'https://opencode.ai/config.json',\n mcp: {\n aictiq: {\n type: 'local',\n command: [context.mcpServer.command, ...context.mcpServer.args],\n enabled: true,\n },\n },\n }),\n },\n }\n },\n\n parse(line): ParsedLine {\n let event: Record<string, unknown>\n try {\n const parsed = JSON.parse(line) as unknown\n event =\n recordOf(parsed) ??\n (() => {\n throw new Error('not an object')\n })()\n } catch {\n return { log: line }\n }\n\n const part = recordOf(event.part)\n if (!part) return { log: null }\n if (event.type === 'text' && typeof part.text === 'string') {\n // Returning each text part as result lets the runner retain the final one per run.\n return { log: part.text, result: part.text }\n }\n if (event.type === 'tool_use') {\n const tool =\n typeof part.tool === 'string'\n ? part.tool\n : typeof part.name === 'string'\n ? part.name\n : 'tool'\n const state = recordOf(part.state)\n return { log: `→ ${tool} ${limit(JSON.stringify(state?.input ?? part.input ?? {}), 200)}` }\n }\n // Each step reports its own usage, so the runner adds them up. Cache reads and writes\n // are input the model processed, as the Codex adapter counts them; reasoning is output.\n if (event.type === 'step_finish') {\n const tokens = recordOf(part.tokens)\n const cache = recordOf(tokens?.cache)\n return {\n log: null,\n accumulate: true,\n costUsd: numberOrUndefined(part.cost),\n inputTokens: sumOf(tokens?.input, cache?.read, cache?.write),\n outputTokens: sumOf(tokens?.output, tokens?.reasoning),\n }\n }\n return { log: null }\n },\n\n outcome(exitCode, lastLines, lastResult) {\n if (exitCode !== 0) return failedOutcome(exitCode, lastLines)\n return {\n outcome: 'succeeded',\n failureReason: null,\n summary: limit(lastResult ?? lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n },\n}\n\nfunction failedOutcome(exitCode: number | null, lastLines: string[]) {\n return {\n outcome: 'failed' as const,\n failureReason: exitCode === null ? 'harness-killed' : `harness-exit-${exitCode}`,\n summary: limit(lastLines.slice(-20).join('\\n'), 4_000) || null,\n }\n}\n\nfunction sumOf(...values: unknown[]): number | undefined {\n const numbers = values.filter(\n (value): value is number => typeof value === 'number' && Number.isFinite(value),\n )\n return numbers.length === 0 ? undefined : numbers.reduce((total, value) => total + value, 0)\n}\n\nfunction numberOrUndefined(value: unknown): number | undefined {\n return typeof value === 'number' && Number.isFinite(value) ? value : undefined\n}\n","import type { HarnessAdapter, HarnessInfo, HarnessName } from '../types.js'\nimport { claude } from './claude.js'\nimport { codex } from './codex.js'\nimport { opencode } from './opencode.js'\n\nexport { versionOf } from './claude.js'\n\nexport const harnesses: Record<HarnessName, HarnessAdapter> = { claude, codex, opencode }\n\nexport async function probeHarnesses(env?: NodeJS.ProcessEnv): Promise<HarnessInfo[]> {\n const found = await Promise.all(Object.values(harnesses).map((harness) => harness.available(env)))\n return found.filter((info): info is HarnessInfo => info !== null)\n}\n","import { posix } from 'node:path'\n\n/**\n * What `aictiq runner install-service` prints: a definition that keeps `aictiq runner start`\n * running as the current user, for the service manager of each supported OS. Nothing here\n * writes or enables anything; the operator reads the output and installs it.\n *\n * Every variant runs as the person who generated it, with their harness sign-ins and git\n * credentials: one runner is one trust domain. Every variant also stops for good on exit 5\n * (the runner secret was revoked), because restarting cannot fix that.\n */\nexport type ServicePlatform = 'linux' | 'macos' | 'windows'\n\nexport interface ServiceOptions {\n /** Absolute path of the Node.js binary. */\n node: string\n /** Absolute path of the CLI entry script. */\n entry: string\n parallel: string\n /** The PATH the service runs with, so it finds git and every harness. */\n path: string\n /** The home directory; macOS logs go below it. */\n home: string\n}\n\nexport const RevokedExitCode = 5\n\nexport function servicePlatform(platform: NodeJS.Platform = process.platform): ServicePlatform {\n if (platform === 'darwin') return 'macos'\n if (platform === 'win32') return 'windows'\n return 'linux'\n}\n\nexport function serviceDefinition(platform: ServicePlatform, options: ServiceOptions): string {\n switch (platform) {\n case 'macos':\n return launchdAgent(options)\n case 'windows':\n return scheduledTaskInstaller(options)\n default:\n return systemdUnit(options)\n }\n}\n\nexport function systemdUnit({ node, entry, parallel, path }: ServiceOptions): string {\n return `# Save as ~/.config/systemd/user/aictiq-runner.service, then:\n# systemctl --user daemon-reload\n# systemctl --user enable --now aictiq-runner\n# loginctl enable-linger \"$USER\" # keep it running after you log out\n#\n# The runner executes agents as this user, with this user's harness sign-ins and git\n# credentials: one runner is one trust domain. SIGTERM lets runs in flight finish;\n# TimeoutStopSec bounds how long systemd waits before it cancels them.\n[Unit]\nDescription=Aictiq runner\nAfter=network-online.target\nWants=network-online.target\n\n[Service]\nType=simple\nExecStart=${node} ${entry} runner start --parallel ${parallel}\nRestart=on-failure\nRestartSec=10\n# Exit ${RevokedExitCode} means the secret was revoked; restarting cannot fix that.\nRestartPreventExitStatus=${RevokedExitCode}\nKillMode=mixed\nTimeoutStopSec=15min\nEnvironment=PATH=${path}\n\n[Install]\nWantedBy=default.target\n`\n}\n\nexport const LaunchdLabel = 'com.aictiq.runner'\n\n/**\n * launchd restarts on any non-zero exit (`SuccessfulExit` false) and cannot exempt one code,\n * so a small sh wrapper turns the revoked exit into 0. It also forwards launchd's SIGTERM to\n * the runner - otherwise sh would die on it and launchd would SIGKILL the runs in flight\n * instead of letting them finish. Paths reach the wrapper as arguments, never inside the\n * script text, so no quoting can break.\n */\nconst LaunchdWrapper = `\"$1\" \"$2\" runner start --parallel \"$3\" &\nchild=$!\ntrap 'kill -TERM \"$child\" 2>/dev/null' TERM INT\nwait \"$child\"\nstatus=$?\nwhile kill -0 \"$child\" 2>/dev/null; do wait \"$child\"; status=$?; done\nif [ \"$status\" -eq ${RevokedExitCode} ]; then exit 0; fi\nexit \"$status\"`\n\nexport function launchdAgent({ node, entry, parallel, path, home }: ServiceOptions): string {\n // A macOS path even when the definition is generated elsewhere (`--platform macos`).\n const log = posix.join(home, 'Library', 'Logs', 'aictiq-runner.log')\n const plistPath = `~/Library/LaunchAgents/${LaunchdLabel}.plist`\n const string = (value: string) => `<string>${xml(value)}</string>`\n return `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--\n Save as ${plistPath}, then:\n launchctl bootstrap gui/$(id -u) ${plistPath}\n Check it: launchctl print gui/$(id -u)/${LaunchdLabel}\n Log: tail -f ${xmlComment(log)}\n Remove it: launchctl bootout gui/$(id -u)/${LaunchdLabel}\n\n The runner executes agents as this user, with this user's harness sign-ins and git\n credentials: one runner is one trust domain. It runs while this user is logged in.\n A stop lets runs in flight finish for up to 15 minutes before launchd kills them.\n-->\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n ${string(LaunchdLabel)}\n <key>ProgramArguments</key>\n <array>\n ${string('/bin/sh')}\n ${string('-c')}\n ${string(LaunchdWrapper)}\n ${string('aictiq-runner')}\n ${string(node)}\n ${string(entry)}\n ${string(parallel)}\n </array>\n <key>EnvironmentVariables</key>\n <dict>\n <key>PATH</key>\n ${string(path)}\n </dict>\n <key>RunAtLoad</key>\n <true/>\n <key>KeepAlive</key>\n <dict>\n <key>SuccessfulExit</key>\n <false/>\n </dict>\n <key>ThrottleInterval</key>\n <integer>10</integer>\n <key>ExitTimeOut</key>\n <integer>900</integer>\n <key>ProcessType</key>\n ${string('Background')}\n <key>StandardOutPath</key>\n ${string(log)}\n <key>StandardErrorPath</key>\n ${string(log)}\n</dict>\n</plist>\n`\n}\n\nexport const ScheduledTaskName = 'Aictiq runner'\n\n/**\n * Windows has no service manager for a script that should run as the signed-in person, so\n * this is a PowerShell installer for a Task Scheduler task that starts at logon. Task\n * Scheduler's own \"restart on failure\" only covers a task that fails to *start*, not one\n * that exits non-zero, so the task runs a loop script that restarts the runner itself and\n * stops on the revoked exit. The loop also writes the log, since a task has no console.\n */\nexport function scheduledTaskInstaller({ node, entry, parallel, path }: ServiceOptions): string {\n const loop = `# Written by \\`aictiq runner install-service\\`; the \"${ScheduledTaskName}\" task runs it at logon.\n$ErrorActionPreference = 'Continue'\n$env:PATH = ${ps(path)}\n$log = Join-Path $env:LOCALAPPDATA 'aictiq\\\\runner.log'\nwhile ($true) {\n # \"$_\" turns stderr's error records back into the plain lines the runner wrote.\n & ${ps(node)} ${ps(entry)} runner start --parallel ${ps(parallel)} 2>&1 |\n ForEach-Object { \"$_\" } | Add-Content -Path $log -Encoding utf8\n if ($LASTEXITCODE -eq ${RevokedExitCode}) {\n Add-Content -Path $log -Encoding utf8 -Value 'The runner secret was revoked; not restarting.'\n break\n }\n Start-Sleep -Seconds 10\n}\n`\n return `# Aictiq runner as a Windows scheduled task. Save as install-runner.ps1, then run:\n# powershell -NoProfile -ExecutionPolicy Bypass -File install-runner.ps1\n# Check it: Get-ScheduledTask -TaskName '${ScheduledTaskName}' | Get-ScheduledTaskInfo\n# Log: Get-Content -Wait \"$env:LOCALAPPDATA\\\\aictiq\\\\runner.log\"\n# Remove it: Unregister-ScheduledTask -TaskName '${ScheduledTaskName}' -Confirm:$false\n#\n# The task starts at logon and runs while this user is logged in, as this user, with this\n# user's harness sign-ins and git credentials: one runner is one trust domain. Stopping the\n# task ends the runner at once; runs in flight are cancelled, not finished.\n$ErrorActionPreference = 'Stop'\n$dir = Join-Path $env:LOCALAPPDATA 'aictiq'\nNew-Item -ItemType Directory -Force -Path $dir | Out-Null\n$script = Join-Path $dir 'runner-service.ps1'\nSet-Content -Path $script -Encoding utf8 -Value @'\n${loop}'@\n\n$action = New-ScheduledTaskAction -Execute 'powershell.exe' -Argument \"-NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass -File \\`\"$script\\`\"\"\n$trigger = New-ScheduledTaskTrigger -AtLogOn -User \"$env:USERDOMAIN\\\\$env:USERNAME\"\n$principal = New-ScheduledTaskPrincipal -UserId \"$env:USERDOMAIN\\\\$env:USERNAME\" -LogonType Interactive -RunLevel Limited\n$settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit ([TimeSpan]::Zero) -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -MultipleInstances IgnoreNew\nRegister-ScheduledTask -TaskName '${ScheduledTaskName}' -Action $action -Trigger $trigger -Principal $principal -Settings $settings -Force | Out-Null\nStart-ScheduledTask -TaskName '${ScheduledTaskName}'\nWrite-Host \"Installed and started '${ScheduledTaskName}'. Log: $(Join-Path $dir 'runner.log')\"\n`\n}\n\nfunction xml(value: string): string {\n return value\n .replace(/&/g, '&')\n .replace(/</g, '<')\n .replace(/>/g, '>')\n .replace(/\"/g, '"')\n}\n\n/** A comment cannot contain `--`; a path in one is for reading, so a space keeps it valid. */\nfunction xmlComment(value: string): string {\n return value.replace(/--/g, '- -')\n}\n\n/** A PowerShell single-quoted literal: nothing inside expands, and `'` doubles. */\nfunction ps(value: string): string {\n return `'${value.replace(/'/g, \"''\")}'`\n}\n\n","import { RunnerHttpError, RunnerNetworkError } from './client.js'\nimport type { RunnerClient } from './client.js'\nimport type { Floor } from './floor.js'\nimport type { ClaimedRun, RunnerCapabilities, RunnerHello } from './types.js'\n\n/** Every harness the CLI has an adapter for, offered when none is detected (see below). */\nexport const KnownHarnesses = ['claude', 'codex', 'opencode'] as const\n\nexport interface RunnerLoopOptions {\n client: RunnerClient\n parallel: number\n probe: () => Promise<RunnerCapabilities>\n execute: (run: ClaimedRun, hello: RunnerHello, shutdown: AbortSignal) => Promise<unknown>\n local: (message: string) => void\n backoffMs?: (attempt: number) => number\n /**\n * Shared by every organization this machine serves, so their runs never execute at the\n * same time. Absent, the loop answers only to its own `parallel`.\n */\n floor?: Floor\n /** This loop's place on the floor: one key per organization. */\n floorKey?: string\n /** Called once the instance has said who this runner is. */\n onHello?: (hello: RunnerHello) => void\n}\n\nexport class RunnerRevokedError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'RunnerRevokedError'\n }\n}\n\n/**\n * The runner's life: `hello`, then claim → execute in up to `parallel` slots, heartbeating\n * the runner alongside. `stop()` is the first Ctrl-C: claim nothing more and let the runs\n * in flight finish. `abort()` is the second: stop the harnesses and report them cancelled.\n */\nexport class RunnerLoop {\n private readonly options: RunnerLoopOptions\n private readonly active = new Set<Promise<void>>()\n private readonly claimAbort = new AbortController()\n private readonly shutdown = new AbortController()\n private stopping = false\n private revoked: RunnerRevokedError | undefined\n private wake: (() => void) | undefined\n\n constructor(options: RunnerLoopOptions) {\n this.options = options\n }\n\n get inFlight(): number {\n return this.active.size\n }\n\n stop(): void {\n this.stopping = true\n this.claimAbort.abort()\n this.wake?.()\n }\n\n abort(): void {\n this.stop()\n this.shutdown.abort()\n }\n\n /** Resolves when the loop has stopped and every run it took is reported. */\n async run(): Promise<void> {\n const { client, local } = this.options\n let capabilities = await this.options.probe()\n const hello = await this.retrying(() => client.hello(capabilities))\n if (!hello) return\n this.options.onHello?.(hello)\n local(\n `Runner \"${hello.name}\" connected to ${client.baseUrl} (${hello.organizationSlug}); harnesses: ${\n capabilities.harnesses.map((h) => h.name).join(', ') || 'none detected'\n }`,\n )\n\n const heartbeat = setInterval(() => {\n void (async () => {\n try {\n capabilities = await this.options.probe()\n await client.heartbeat(capabilities)\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) this.revoke(error)\n else local(`Heartbeat failed: ${error instanceof Error ? error.message : String(error)}`)\n }\n })()\n }, hello.heartbeatIntervalSeconds * 1000)\n\n const { floor } = this.options\n const floorKey = this.options.floorKey ?? client.baseUrl\n try {\n let attempt = 0\n while (!this.stopping) {\n if (floor) {\n await floor.turn(floorKey, this.claimAbort.signal)\n if (this.stopping) break\n }\n const free = this.options.parallel - this.active.size\n if (free <= 0) {\n await this.waitForSlot()\n continue\n }\n\n // With no harness detected the runner still offers every one it knows, so a run\n // dispatched to a misconfigured machine fails at once with `harness-unavailable`\n // instead of waiting in the queue with no explanation.\n const detected = capabilities.harnesses.map((h) => h.name)\n const offered = detected.length > 0 ? detected : [...KnownHarnesses]\n let claimed: ClaimedRun | null\n try {\n claimed = await client.claim(offered, free, this.claimAbort.signal)\n attempt = 0\n } catch (error) {\n if (this.stopping) break\n if (error instanceof RunnerHttpError && error.revoked) {\n this.revoke(error)\n break\n }\n attempt++\n const wait =\n this.options.backoffMs?.(attempt) ?? Math.min(60_000, 1000 * 2 ** (attempt - 1))\n local(\n `Claim failed (${error instanceof Error ? error.message : String(error)}); retrying in ${Math.round(wait / 1000)}s`,\n )\n await this.sleep(wait)\n continue\n }\n if (!claimed) continue\n if (floor && !floor.enter(floorKey) && !(await this.handBack(claimed, floor, floorKey)))\n continue\n\n local(`Claimed ${claimed.itemKey} (run ${claimed.runId}, ${claimed.harness})`)\n const execution = this.options\n .execute(claimed, hello, this.shutdown.signal)\n .then(() => undefined)\n .catch((error: unknown) => {\n if (error instanceof RunnerHttpError && error.revoked) this.revoke(error)\n else\n local(\n `Run ${claimed.runId} ended with an error: ${error instanceof Error ? error.message : String(error)}`,\n )\n })\n .finally(() => {\n floor?.leave(floorKey)\n this.active.delete(execution)\n this.wake?.()\n })\n this.active.add(execution)\n }\n\n if (this.active.size > 0) local(`Waiting for ${this.active.size} run(s) to finish…`)\n await Promise.all([...this.active])\n } finally {\n clearInterval(heartbeat)\n }\n\n if (this.revoked) throw this.revoked\n }\n\n /**\n * A run claimed while another organization took the floor. It goes back to the queue;\n * true only when it could not be given back and has now waited for the floor instead,\n * so the caller executes it.\n */\n private async handBack(run: ClaimedRun, floor: Floor, key: string): Promise<boolean> {\n const { client, local } = this.options\n try {\n await client.release(run.runId)\n local(\n `Gave ${run.itemKey} back to the queue: another organization has runs executing on this machine`,\n )\n return false\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) {\n this.revoke(error)\n return false\n }\n // A problem document means the instance answered about the run: it was cancelled or\n // swept meanwhile and is no longer ours. A bare 404 or a network failure means the\n // run is still ours (an instance without the release route): wait, then execute it.\n if (error instanceof RunnerHttpError && error.problem?.type) return false\n local(\n `Could not give ${run.itemKey} back (${error instanceof Error ? error.message : String(error)}); it starts when the other organization's runs finish`,\n )\n while (!floor.enter(key)) await floor.turn(key)\n return true\n }\n }\n\n private revoke(error: RunnerHttpError): void {\n this.revoked ??= new RunnerRevokedError(\n error.problem?.type?.endsWith('token-revoked')\n ? 'This runner was disabled, deleted or rotated. Register it again with `aictiq runner register`.'\n : `The instance refused the runner secret (${error.message}). Register it again with \\`aictiq runner register\\`.`,\n )\n this.abort()\n }\n\n /** Retries network failures until stopped; a refusal is thrown. */\n private async retrying<T>(action: () => Promise<T>): Promise<T | null> {\n for (let attempt = 1; !this.stopping; attempt++) {\n try {\n return await action()\n } catch (error) {\n if (error instanceof RunnerHttpError && error.revoked) {\n this.revoke(error)\n throw this.revoked\n }\n if (!(error instanceof RunnerNetworkError)) throw error\n const wait =\n this.options.backoffMs?.(attempt) ?? Math.min(60_000, 1000 * 2 ** (attempt - 1))\n this.options.local(`${error.message}; retrying in ${Math.round(wait / 1000)}s`)\n await this.sleep(wait)\n }\n }\n return null\n }\n\n private waitForSlot(): Promise<void> {\n return new Promise((resolve) => {\n this.wake = () => {\n this.wake = undefined\n resolve()\n }\n })\n }\n\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => {\n const timer = setTimeout(done, ms)\n this.wake = done\n function done() {\n clearTimeout(timer)\n resolve()\n }\n })\n }\n}\n","/**\n * The factory floor of one machine that serves several organizations: runs of one\n * organization may execute side by side, runs of two never do. While a run is live, the\n * other organizations' agents cannot read its token from the process table, find its\n * checkout under the workspace root, or push with its GitHub token.\n *\n * Every organization's loop asks for its {@link turn} before it claims, and must\n * {@link enter} before it executes what it claimed. Loops of an idle machine poll side by\n * side, so two claims can land together; the loser's `enter` fails and it gives its run\n * back. When the floor frees, the organization that held it waits a moment\n * ({@link handoffMs}) if another one is waiting, so one busy queue cannot keep the others\n * out indefinitely.\n */\nexport class Floor {\n private holder: string | null = null\n private count = 0\n private last: string | null = null\n private freedAt = 0\n private readonly waiting = new Map<string, number>()\n private changed = deferred()\n\n constructor(private readonly handoffMs = 2000) {}\n\n /** The organization with runs executing, or null when the floor is free. */\n get current(): string | null {\n return this.holder\n }\n\n /**\n * Resolves when `key` may claim: the floor is free, or its own runs hold it. Also resolves\n * when `signal` aborts; the caller checks why.\n */\n async turn(key: string, signal?: AbortSignal): Promise<void> {\n this.waiting.set(key, (this.waiting.get(key) ?? 0) + 1)\n try {\n while (!signal?.aborted) {\n const yieldFor = this.yieldFor(key)\n if (this.count > 0 ? this.holder === key : yieldFor === 0) return\n\n const waits: Promise<unknown>[] = [this.changed.promise]\n let timer: NodeJS.Timeout | undefined\n if (yieldFor > 0)\n waits.push(new Promise((resolve) => (timer = setTimeout(resolve, yieldFor))))\n let onAbort: (() => void) | undefined\n if (signal) {\n waits.push(\n new Promise<void>((resolve) => {\n onAbort = () => resolve()\n signal.addEventListener('abort', onAbort, { once: true })\n }),\n )\n }\n await Promise.race(waits)\n clearTimeout(timer)\n if (onAbort) signal?.removeEventListener('abort', onAbort)\n }\n } finally {\n const left = (this.waiting.get(key) ?? 1) - 1\n if (left === 0) this.waiting.delete(key)\n else this.waiting.set(key, left)\n }\n }\n\n /** Takes the floor for one run of `key`; false when another organization's runs hold it. */\n enter(key: string): boolean {\n if (this.count > 0 && this.holder !== key) return false\n this.holder = key\n this.count++\n this.notify()\n return true\n }\n\n leave(key: string): void {\n if (this.holder !== key || this.count === 0) return\n this.count--\n if (this.count === 0) {\n this.holder = null\n this.last = key\n this.freedAt = Date.now()\n }\n this.notify()\n }\n\n /** How long `key` stands back from a free floor so a waiting organization goes first. */\n private yieldFor(key: string): number {\n if (this.count > 0 || key !== this.last) return 0\n const othersWaiting = [...this.waiting.keys()].some((other) => other !== key)\n if (!othersWaiting) return 0\n return Math.max(0, this.freedAt + this.handoffMs - Date.now())\n }\n\n private notify(): void {\n const previous = this.changed\n this.changed = deferred()\n previous.resolve()\n }\n}\n\nfunction deferred(): { promise: Promise<void>; resolve: () => void } {\n let resolve!: () => void\n const promise = new Promise<void>((done) => (resolve = done))\n return { promise, resolve }\n}\n","import { Floor } from './floor.js'\nimport { RunnerRevokedError } from './loop.js'\nimport type { RunnerLoop } from './loop.js'\nimport { profileLabel } from './config.js'\nimport type { RunnerConfig, RunnerProfile } from './config.js'\nimport type { RunnerHello } from './types.js'\n\nexport interface RunnerSupervisorOptions {\n /** Read again every {@link reloadMs}; a new registration starts, a removed one stops. */\n readConfig: () => RunnerConfig | null\n createLoop: (\n profile: RunnerProfile,\n floor: Floor,\n onHello: (hello: RunnerHello) => void,\n ) => RunnerLoop\n /** A profile's first hello named its organization; persist it. */\n learned?: (profile: RunnerProfile, hello: RunnerHello) => void\n local: (message: string) => void\n reloadMs?: number\n /** How long a profile that failed for a reason other than revocation waits before it is tried again. */\n retryMs?: number\n floor?: Floor\n}\n\ninterface Running {\n profile: RunnerProfile\n loop: RunnerLoop\n done: Promise<void>\n /** Set when the supervisor stopped it (the profile left runner.json); its ending is expected. */\n retired: boolean\n}\n\n/**\n * `aictiq runner start` on a machine with several profiles: one {@link RunnerLoop} per\n * organization, all on one {@link Floor}. Profiles are keyed by their secret, so\n * `aictiq runner register` in another terminal - a new organization or a rotated secret -\n * takes effect within {@link reloadMs}, without a restart.\n *\n * One organization's secret being revoked stops that organization only. The process ends\n * with the revoked error (exit 5) once no profile in `runner.json` still works, which is\n * what the service definitions treat as \"stop for good\".\n */\nexport class RunnerSupervisor {\n private readonly options: RunnerSupervisorOptions\n private readonly floor: Floor\n private readonly running = new Map<string, Running>()\n /** Secrets that failed: revoked ones for good, others until the time given. */\n private readonly failed = new Map<\n string,\n { revoked: RunnerRevokedError | null; retryAt: number }\n >()\n private stopping = false\n private settle: (() => void) | undefined\n\n constructor(options: RunnerSupervisorOptions) {\n this.options = options\n this.floor = options.floor ?? new Floor()\n }\n\n get inFlight(): number {\n let total = 0\n for (const { loop } of this.running.values()) total += loop.inFlight\n return total\n }\n\n stop(): void {\n this.stopping = true\n for (const { loop } of this.running.values()) loop.stop()\n this.settle?.()\n }\n\n abort(): void {\n this.stopping = true\n for (const { loop } of this.running.values()) loop.abort()\n this.settle?.()\n }\n\n async run(): Promise<void> {\n const reload = setInterval(() => this.sync(), this.options.reloadMs ?? 5000)\n try {\n this.sync()\n while (!this.stopping) {\n const revoked = this.allRevoked()\n if (revoked) throw revoked\n await new Promise<void>((resolve) => (this.settle = resolve))\n }\n await Promise.all([...this.running.values()].map(({ done }) => done))\n } finally {\n clearInterval(reload)\n this.settle = undefined\n }\n }\n\n /** Every configured profile is revoked and nothing runs: the error to exit with, else null. */\n private allRevoked(): RunnerRevokedError | null {\n if (this.running.size > 0) return null\n const profiles = this.options.readConfig()?.profiles ?? []\n if (profiles.length === 0) return null\n let last: RunnerRevokedError | null = null\n for (const profile of profiles) {\n const failure = this.failed.get(profile.token)\n if (!failure?.revoked) return null\n last = failure.revoked\n }\n return profiles.length === 1 || !last\n ? last\n : new RunnerRevokedError(\n 'Every organization this runner served disabled, deleted or rotated its runner. Register it again with `aictiq runner register`.',\n )\n }\n\n private sync(): void {\n if (this.stopping) return\n const config = this.options.readConfig()\n const profiles = config?.profiles ?? []\n const wanted = new Map(profiles.map((profile) => [profile.token, profile]))\n\n for (const [token, running] of this.running) {\n if (wanted.has(token) || running.retired) continue\n running.retired = true\n this.options.local(\n `[${profileLabel(running.profile)}] Removed from runner.json; stopping after its runs finish`,\n )\n running.loop.stop()\n }\n\n for (const profile of wanted.values()) {\n if (this.running.has(profile.token)) continue\n const failure = this.failed.get(profile.token)\n if (failure && (failure.revoked || Date.now() < failure.retryAt)) continue\n this.failed.delete(profile.token)\n this.start(profile)\n }\n this.settle?.()\n }\n\n private start(profile: RunnerProfile): void {\n const label = () => profileLabel(profile)\n const loop = this.options.createLoop(profile, this.floor, (hello) => {\n if (profile.organization !== hello.organizationSlug) {\n profile.organization = hello.organizationSlug\n this.options.learned?.(profile, hello)\n }\n })\n const running: Running = { profile, loop, done: Promise.resolve(), retired: false }\n running.done = loop\n .run()\n .catch((error: unknown) => {\n if (error instanceof RunnerRevokedError) {\n this.options.local(`[${label()}] ${error.message}`)\n this.failed.set(profile.token, { revoked: error, retryAt: Number.POSITIVE_INFINITY })\n return\n }\n const retryMs = this.options.retryMs ?? 60_000\n this.options.local(\n `[${label()}] Stopped: ${error instanceof Error ? error.message : String(error)}; trying again in ${Math.round(retryMs / 1000)}s`,\n )\n this.failed.set(profile.token, { revoked: null, retryAt: Date.now() + retryMs })\n })\n .finally(() => {\n this.running.delete(profile.token)\n this.settle?.()\n })\n this.running.set(profile.token, running)\n }\n}\n","import { Command } from 'commander'\nimport type { SprintView, TeamView } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { formatNumber, print, printJson, renderFields, renderTable } from '../output.js'\nimport { getTeams } from '../resolve.js'\n\ninterface TaskboardCell {\n key: string\n name: string\n remainingHours: number\n tasks: { key: string; title: string; assigneeId: string | null }[]\n}\n\ninterface TaskboardView {\n sprintId: string\n rows: { parentKey: string | null; name: string; remainingHours: number; cells: TaskboardCell[] }[]\n unparentedTasks: TaskboardCell[]\n}\n\nexport function sprintCommand(globals: () => GlobalOptions): Command {\n const sprint = new Command('sprint').description('Sprints')\n\n sprint\n .command('list')\n .description(\"List a team's sprints, newest first\")\n .requiredOption('-t, --team <key>', 'Team key, name or id')\n .option('-p, --project <key>', 'Project key; required when the team is named, not an id')\n .action(async (options: { team: string; project?: string }) => {\n const ctx = createContext(globals())\n const teamId = await resolveTeamId(ctx, options.team, options.project)\n const sprints = await ctx.client.request<\n SprintView[],\n '/api/v1/orgs/{orgSlug}/teams/{teamId}/sprints',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/teams/{teamId}/sprints', {\n path: { orgSlug: await ctx.org(), teamId },\n })\n\n if (ctx.json) return printJson(sprints)\n if (sprints.length === 0) return print('No sprints.')\n print(\n renderTable(sprints, [\n { header: 'ID', value: (s) => s.id },\n { header: 'NAME', value: (s) => s.name },\n { header: 'STATE', value: (s) => s.state },\n { header: 'STARTS', value: (s) => s.startsOn },\n { header: 'ENDS', value: (s) => s.endsOn },\n {\n header: 'DONE',\n value: (s) => `${s.progress.completedItems}/${s.progress.totalItems}`,\n align: 'right',\n },\n ]),\n )\n })\n\n sprint\n .command('view')\n .description('Show a sprint and its taskboard')\n .argument('<sprintId>', 'Sprint id')\n .option('--taskboard', 'Include the taskboard rows')\n .action(async (sprintId: string, options: { taskboard?: boolean }) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const found = await ctx.client.request<\n SprintView,\n '/api/v1/orgs/{orgSlug}/sprints/{sprintId}',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/sprints/{sprintId}', { path: { orgSlug, sprintId } })\n const taskboard = options.taskboard\n ? await ctx.client.request<\n TaskboardView,\n '/api/v1/orgs/{orgSlug}/sprints/{sprintId}/taskboard',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/sprints/{sprintId}/taskboard', {\n path: { orgSlug, sprintId },\n })\n : undefined\n\n if (ctx.json) return printJson({ ...found, ...(taskboard ? { taskboard } : {}) })\n\n print(\n renderFields([\n ['Sprint', found.name],\n ['Goal', found.goal],\n ['State', found.state],\n ['Dates', `${found.startsOn} → ${found.endsOn}`],\n ['Days left', String(found.daysLeft)],\n ['Items', `${found.progress.completedItems}/${found.progress.totalItems}`],\n [\n 'Points',\n `${formatNumber(found.progress.pointsDone)}/${formatNumber(found.progress.pointsTotal)}`,\n ],\n ['Remaining hours', formatNumber(found.progress.remainingHours)],\n ]),\n )\n if (taskboard) {\n for (const row of taskboard.rows) {\n print('')\n print(`${row.parentKey ?? '(no parent)'} ${row.name}`)\n for (const cell of row.cells) {\n for (const task of cell.tasks) {\n print(` [${cell.name}] ${task.key} ${task.title}`)\n }\n }\n }\n }\n })\n\n return sprint\n}\n\n/** A team id passes through; a key or name needs the project whose teams to search. */\nasync function resolveTeamId(ctx: Context, team: string, projectKey?: string): Promise<string> {\n if (/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(team)) return team\n if (!projectKey) {\n throw new CliError(\n 'Pass -p <projectKey> alongside a team key or name, or give the team id.',\n ExitCode.Validation,\n )\n }\n const teams: TeamView[] = await getTeams(ctx, projectKey.toUpperCase())\n const needle = team.trim().toLowerCase()\n const found = teams.find((t) => t.key.toLowerCase() === needle || t.name.toLowerCase() === needle)\n if (!found) {\n throw new CliError(\n `No team \"${team}\" in ${projectKey}. Teams: ${teams.map((t) => t.key).join(', ') || '(none)'}.`,\n ExitCode.Validation,\n )\n }\n return found.id\n}\n","import { Command } from 'commander'\nimport type { WikiPageView, WikiTreePageView } from '../api/views.js'\nimport { createContext } from '../context.js'\nimport type { Context, GlobalOptions } from '../context.js'\nimport { CliError, ExitCode } from '../errors.js'\nimport { print, printJson, renderTable } from '../output.js'\nimport { readBody } from '../resolve.js'\n\nexport function wikiCommand(globals: () => GlobalOptions): Command {\n const wiki = new Command('wiki').description('Project wiki pages')\n\n wiki\n .command('tree')\n .description('List the page tree of a project')\n .requiredOption('-p, --project <key>', 'Project key, e.g. ACME')\n .action(async (options: { project: string }) => {\n const ctx = createContext(globals())\n const pages = await fetchTree(ctx, options.project.toUpperCase())\n if (ctx.json) return printJson(pages)\n if (pages.length === 0) return print('No wiki pages.')\n const paths = pathsOf(pages)\n print(\n renderTable(pages, [\n { header: 'PATH', value: (p) => paths.get(p.id) ?? p.slug },\n { header: 'TITLE', value: (p) => p.title },\n ]),\n )\n })\n\n wiki\n .command('get')\n .description('Print a wiki page as Markdown')\n .argument('<project>', 'Project key, e.g. ACME')\n .argument('<path>', 'Slug path, e.g. specs/login')\n .action(async (project: string, path: string) => {\n const ctx = createContext(globals())\n const pages = await fetchTree(ctx, project.toUpperCase())\n const page = findByPath(pages, path)\n if (!page) throw new CliError(`No wiki page at \"${path}\" in ${project}.`, ExitCode.NotFound)\n const full = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}', {\n path: { orgSlug: await ctx.org(), pageId: page.id },\n })\n if (ctx.json) return printJson(full)\n print(full.contentMarkdown)\n })\n\n wiki\n .command('put')\n .description('Create or replace a wiki page from Markdown')\n .argument('<project>', 'Project key, e.g. ACME')\n .argument('<path>', 'Slug path, e.g. specs/login')\n .option('--file <path>', 'Markdown file, or - for stdin', '-')\n .option('-m, --body <markdown>', 'Markdown body given inline')\n .option('--title <title>', 'Page title; defaults to the last path segment')\n .option('--summary <text>', 'Revision summary recorded in the history')\n .action(\n async (\n project: string,\n path: string,\n options: { file?: string; body?: string; title?: string; summary?: string },\n ) => {\n const ctx = createContext(globals())\n const orgSlug = await ctx.org()\n const projectKey = project.toUpperCase()\n const content = await readBody(\n options.body,\n options.body ? undefined : (options.file ?? '-'),\n )\n if (content === undefined || content.trim().length === 0) {\n throw new CliError('The page body is empty.', ExitCode.Validation)\n }\n\n const pages = await fetchTree(ctx, projectKey)\n const existing = findByPath(pages, path)\n if (existing) {\n // The version comes from the page we are about to replace, so a concurrent edit\n // 409s (exit 3) instead of silently winning.\n const current = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}', {\n path: { orgSlug, pageId: existing.id },\n })\n const updated = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}',\n 'patch'\n >('patch', '/api/v1/orgs/{orgSlug}/wiki/pages/{pageId}', {\n path: { orgSlug, pageId: existing.id },\n body: {\n contentMd: content,\n version: current.version,\n ...(options.title ? { title: options.title } : {}),\n ...(options.summary ? { summary: options.summary } : {}),\n },\n })\n if (ctx.json) return printJson(updated)\n return print(`Updated ${path} (revision ${updated.revisionNumber}).`)\n }\n\n const segments = path.split('/').filter((s) => s.length > 0)\n const parentPath = segments.slice(0, -1).join('/')\n const parent = parentPath ? findByPath(pages, parentPath) : undefined\n if (parentPath && !parent) {\n throw new CliError(\n `The parent page \"${parentPath}\" does not exist; create it first.`,\n ExitCode.NotFound,\n )\n }\n const created = await ctx.client.request<\n WikiPageView,\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/pages',\n 'post'\n >('post', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/pages', {\n path: { orgSlug, projectKey },\n body: {\n title: options.title ?? titleFrom(segments.at(-1) ?? path),\n contentMd: content,\n ...(parent ? { parentId: parent.id } : {}),\n },\n })\n if (ctx.json) return printJson(created)\n // The API derives the slug from the title, so the page may not sit at the path\n // that was asked for. Saying where it landed beats a silent surprise next `get`.\n print(`Created ${created.slug} (${created.title}).`)\n },\n )\n\n return wiki\n}\n\nasync function fetchTree(ctx: Context, projectKey: string): Promise<WikiTreePageView[]> {\n return ctx.client.request<\n WikiTreePageView[],\n '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/tree',\n 'get'\n >('get', '/api/v1/orgs/{orgSlug}/projects/{projectKey}/wiki/tree', {\n path: { orgSlug: await ctx.org(), projectKey },\n })\n}\n\n/** Slugs are unique per parent, so a page is addressed by the path of slugs to it. */\nfunction pathsOf(pages: readonly WikiTreePageView[]): Map<string, string> {\n const byId = new Map(pages.map((page) => [page.id, page]))\n const paths = new Map<string, string>()\n const walk = (page: WikiTreePageView): string => {\n const cached = paths.get(page.id)\n if (cached) return cached\n const parent = page.parentId ? byId.get(page.parentId) : undefined\n const path = parent ? `${walk(parent)}/${page.slug}` : page.slug\n paths.set(page.id, path)\n return path\n }\n for (const page of pages) walk(page)\n return paths\n}\n\nfunction findByPath(\n pages: readonly WikiTreePageView[],\n path: string,\n): WikiTreePageView | undefined {\n const wanted = path\n .split('/')\n .filter((s) => s.length > 0)\n .join('/')\n .toLowerCase()\n const paths = pathsOf(pages)\n return pages.find((page) => paths.get(page.id)?.toLowerCase() === wanted)\n}\n\nfunction titleFrom(slug: string): string {\n const words = slug.replace(/[-_]+/g, ' ').trim()\n return words.charAt(0).toUpperCase() + words.slice(1)\n}\n","import { CliError, ExitCode } from './errors.js'\nimport { createProgram } from './program.js'\n\nasync function main(): Promise<void> {\n const program = createProgram()\n // Commander's own failures (unknown command, missing required option) are usage errors,\n // which is the same class as a rejected request body: exit 2.\n program.exitOverride((error) => {\n if (error.code === 'commander.helpDisplayed' || error.code === 'commander.version') {\n process.exit(ExitCode.Ok)\n }\n process.exit(error.exitCode === 0 ? ExitCode.Ok : ExitCode.Validation)\n })\n await program.parseAsync(process.argv)\n}\n\nmain().catch((error: unknown) => {\n if (error instanceof CliError) {\n // The message already carries the problem's title and field errors.\n process.stderr.write(`${error.message}\\n`)\n process.exit(error.exitCode)\n }\n process.stderr.write(`${error instanceof Error ? error.message : String(error)}\\n`)\n process.exit(ExitCode.Error)\n})\n"],"mappings":"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","names":["message","Command","Command","resolve","Command","Command","readFileSync","message","readFileSync","Command","version","Command","Command","resolve","Command","Command","Command","Command","resolve","Command","randomUUID","existsSync","homedir","resolve","message","harnesses","signal","chmodSync","existsSync","mkdirSync","readFileSync","writeFileSync","homedir","dirname","join","chmodSync","mkdirSync","rmSync","writeFileSync","homedir","join","message","join","homedir","rmSync","mkdirSync","chmodSync","writeFileSync","message","resolve","join","homedir","existsSync","readFileSync","mkdirSync","dirname","writeFileSync","chmodSync","resolve","spawn","resolve","message","resolve","execFile","limit","resolve","version","message","limit","recordOf","version","numberOf","numberOrUndefined","failedOutcome","limit","recordOf","version","numberOrUndefined","failedOutcome","platform","message","resolve","signal","resolve","resolve","Command","randomUUID","resolve","existsSync","message","formatBytes","signal","platform","homedir","Command","Command","resolveTeamId","Command","Command","Command"]}
|