@impulselab/hepha 0.2.322 → 0.2.325
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 +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1734,6 +1734,13 @@ function formatEvent(event) {
|
|
|
1734
1734
|
return `${out.paint("event", "dim")} ${out.cell(part.title)}${part.conclusion ? ` \u2014 ${out.cell(part.conclusion)}` : ""}`;
|
|
1735
1735
|
case "system":
|
|
1736
1736
|
return out.paint(`system ${truncate(part.text, 300)}`, "dim");
|
|
1737
|
+
// The session's opening row: with the fenced prompt hidden, this is the
|
|
1738
|
+
// only place a CLI reader sees what the run was asked to do.
|
|
1739
|
+
case "source_context":
|
|
1740
|
+
return `${out.paint("source", "dim")} ${out.cell(
|
|
1741
|
+
[part.reference, part.title].filter(Boolean).join(" ")
|
|
1742
|
+
)}${part.url ? ` \u2014 ${out.cell(part.url)}` : ""}${part.body ? `
|
|
1743
|
+
${truncate(part.body, 400)}` : ""}`;
|
|
1737
1744
|
case "verification":
|
|
1738
1745
|
return `${out.paint("check", "dim")} ${out.cell(part.name)} ${out.paint(`(${part.status})`, "dim")}`;
|
|
1739
1746
|
default:
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../packages/core/src/tagged-error.ts","../src/lib/shared/errors-constants.ts","../src/lib/cli/cli-error.ts","../src/lib/shared/output-constants.ts","../src/lib/ansi/strip-ansi.ts","../src/lib/supports/supports-color.ts","../src/lib/cli/cli-output.ts","../src/lib/output/out.ts","../src/lib/shared/config.ts","../src/lib/shared/config-constants.ts","../src/lib/path/config-path-constants.ts","../src/lib/file/read-file-as-object.ts","../src/lib/string/config-read-string.ts","../src/lib/user/read-user.ts","../src/lib/http/is-http-url.ts","../src/lib/http/read-http-url.ts","../src/lib/same/is-same-origin.ts","../src/lib/version/read-version.ts","../src/lib/version/version-constants.ts","../src/commands/help/help-constants.ts","../src/commands/command/help-command.ts","../src/lib/args/args-constants.ts","../src/lib/boolean/boolean-flags-constants.ts","../src/lib/args/parse-flag.ts","../src/lib/args/args-parser.ts","../src/lib/args/args.ts","../src/lib/wants/wants-json.ts","../src/lib/api/api-constants.ts","../src/lib/timeout/resolve-timeout.ts","../src/lib/auth/auth-headers.ts","../src/lib/retry/retry-after-seconds.ts","../src/lib/response/fetch-response.ts","../src/lib/api/add-query-parameters.ts","../src/lib/excerpt/excerpt.ts","../src/lib/api/parse-response-payload.ts","../src/lib/issues/read-issues.ts","../src/lib/string/read-string.ts","../src/lib/message/message-from.ts","../src/lib/api/throw-response-error.ts","../src/lib/api/api.ts","../src/lib/path/path.ts","../src/lib/read/read.ts","../src/lib/expect/expect-shape.ts","../src/lib/is/is.ts","../src/commands/approvals/approvals-constants.ts","../src/commands/approvals/list-approvals.ts","../src/commands/command/approvals-command.ts","../src/commands/catalog/list-catalog-branches.ts","../src/commands/catalog/list-catalog-models.ts","../src/commands/catalog/read-catalog-list.ts","../src/commands/catalog/list-catalog-repos.ts","../src/commands/catalog/list-catalog-skills.ts","../src/commands/catalog/catalog-topics.ts","../src/commands/command/catalog-command.ts","../src/commands/keys/keys-constants.ts","../src/commands/key/create-key.ts","../src/commands/command/keys-command.ts","../src/commands/command/login-command.ts","../src/lib/token/device-token-error.ts","../src/lib/retry/next-poll-delay.ts","../src/lib/browser/open-browser.ts","../src/commands/login/login-constants.ts","../../../packages/database/shared/constants.ts","../src/commands/client/client-id-constants.ts","../src/commands/sleep/sleep.ts","../src/commands/complete/complete-login.ts","../src/commands/login/resolve-login-base-url.ts","../src/commands/command/logout-command.ts","../src/commands/answers/collect-answers-constants.ts","../src/commands/answer/validate-free-text.ts","../src/commands/answer/validate-selected-option-ids.ts","../src/commands/answer/validate-answer.ts","../src/commands/answers/parse-answer-entry.ts","../src/commands/answers/parse-answers-flag.ts","../src/commands/answers/collect-answers.ts","../src/commands/questions/questions-constants.ts","../src/commands/questions/list-questions.ts","../src/commands/batch/print-batch-question.ts","../src/commands/batch/print-batch.ts","../src/commands/command/questions-command.ts","../src/lib/follow/follow-constants.ts","../src/lib/truncate/truncate.ts","../src/lib/event/format-event.ts","../src/lib/session/consume-session-events.ts","../src/lib/sleep/sleep.ts","../src/lib/sleep/sleep-constants.ts","../src/lib/sleep/timer-delay-ms.ts","../src/lib/sleep/interruptible-sleep.ts","../src/lib/session/default-follow-session-dependencies.ts","../src/lib/session/retry/follow-outage-message.ts","../src/lib/session/retry/follow-retry-constants.ts","../src/lib/session/retry/follow-retry-delay.ts","../src/lib/session/retry/remaining-outage-seconds.ts","../src/lib/session/retry/retryable-follow-error.ts","../src/lib/session/retry/should-report-follow-outage.ts","../src/lib/session/retry/wait-for-follow-retry.ts","../src/lib/session/retry/request-with-follow-retry.ts","../src/lib/blocked/blocked-constants.ts","../src/lib/terminal/terminal-constants.ts","../src/lib/session/is-follow-stop-status.ts","../src/lib/session/retry/resolve-follow-outage-budget.ts","../src/lib/session/retry/follow-request-timeout-ms.ts","../src/lib/session/follow-session.ts","../src/lib/session/build-session-detail-rows.ts","../src/lib/session/print-playbook-steps.ts","../src/lib/session/print-session.ts","../src/lib/session/session-outcome.ts","../src/lib/session/write-followed-session-outcome.ts","../src/commands/harnesses/harnesses-constants.ts","../src/commands/task/task-types-constants.ts","../src/commands/command/create-run-input.ts","../src/commands/command/run-command.ts","../src/commands/sessions/sessions-constants.ts","../src/commands/sessions/list-sessions.ts","../src/commands/session/send-session-message.ts","../src/commands/show/follow-session-logs.ts","../src/commands/show/show-logs.ts","../src/commands/sessions/session-actions.ts","../src/commands/detail/detail.ts","../src/commands/command/run-session-control-action.ts","../src/commands/command/run-session-operation.ts","../src/commands/command/sessions-command.ts","../src/commands/command/whoami-command.ts","../src/catalog-topics-constants.ts","../src/dispatch.ts","../src/main.ts","../src/cli-entry.ts"],"sourcesContent":["/**\n * Base for error kinds recognised across bundle boundaries. `instanceof` is\n * unreliable there — server and tasks bundle their own copy of a shared class —\n * so classification reads the `_tag` literal instead.\n */\nexport abstract class TaggedError<Tag extends string = string> extends Error {\n readonly _tag: Tag;\n\n constructor(tag: Tag, message: string, options?: ErrorOptions) {\n super(message, options);\n this._tag = tag;\n this.name = tag;\n }\n\n static is(value: unknown): value is TaggedError {\n return (\n value instanceof Error &&\n \"_tag\" in value &&\n typeof value._tag === \"string\"\n );\n }\n\n static hasTag<Expected extends string>(\n value: unknown,\n tag: Expected,\n ): value is TaggedError<Expected> {\n return TaggedError.is(value) && value._tag === tag;\n }\n}\n","export const CLI_ERROR_CODES = {\n BAD_USAGE: \"BAD_USAGE\",\n /** The session needs a person — the exit-3 family. */\n NEEDS_HUMAN: \"NEEDS_HUMAN\",\n NOT_AUTHENTICATED: \"NOT_AUTHENTICATED\",\n NETWORK: \"NETWORK\",\n TIMEOUT: \"TIMEOUT\",\n /** Ctrl-C: a cancellation, not a failure of ours. */\n INTERRUPTED: \"INTERRUPTED\",\n /** A 2xx whose shape this CLI version does not understand. */\n API_SCHEMA_MISMATCH: \"API_SCHEMA_MISMATCH\",\n /** Not JSON at all — wrong host, proxy, error page. */\n NON_JSON_RESPONSE: \"NON_JSON_RESPONSE\",\n ERROR: \"ERROR\",\n} as const;\n","import { TaggedError } from \"@repo/core/tagged-error\";\n\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport type { CliErrorDetails } from \"@/lib/cli/cli-error-details\";\n\n/**\n * A failure the user should read as a message, not a stack trace.\n *\n * `exitCode` is part of the contract for scripts and agents: 1 for a plain\n * failure, 2 for bad usage, 3 for \"the session needs a human\" — so a caller\n * can branch on it without parsing text. `details` carries the same failure in\n * machine form; under `--json` it is what gets printed (see cli-output.ts).\n */\nexport class CliError extends TaggedError<\"CliError\"> {\n readonly exitCode: number;\n readonly details: CliErrorDetails;\n /**\n * A followed session parking on a question is a non-zero outcome AND a result\n * worth reading. Carried here so stdout stays ONE JSON document.\n */\n readonly result?: unknown;\n\n constructor(\n message: string,\n exitCode = 1,\n details: CliErrorDetails = {},\n result?: unknown,\n ) {\n super(\"CliError\", message);\n this.exitCode = exitCode;\n this.details = details;\n if (result !== undefined) {\n this.result = result;\n }\n }\n\n /** The code to report, defaulting to whatever the exit code implies. */\n get code(): string {\n if (this.details.code) {\n return this.details.code;\n }\n if (this.exitCode === 2) {\n return CLI_ERROR_CODES.BAD_USAGE;\n }\n if (this.exitCode === 3) {\n return CLI_ERROR_CODES.NEEDS_HUMAN;\n }\n return CLI_ERROR_CODES.ERROR;\n }\n}\n","export const COLORS: Record<string, string> = {\n reset: \"\\u001b[0m\",\n dim: \"\\u001b[2m\",\n bold: \"\\u001b[1m\",\n red: \"\\u001b[31m\",\n green: \"\\u001b[32m\",\n yellow: \"\\u001b[33m\",\n blue: \"\\u001b[34m\",\n magenta: \"\\u001b[35m\",\n};\n\nexport const STATUS_COLORS: Record<string, string> = {\n running: \"blue\",\n provisioning: \"blue\",\n queued: \"dim\",\n created: \"dim\",\n delivering: \"blue\",\n verifying: \"blue\",\n waiting_human: \"yellow\",\n waiting_external: \"blue\",\n awaiting_approval: \"yellow\",\n completed: \"green\",\n failed: \"red\",\n killed: \"red\",\n abstained: \"yellow\",\n};\n","/** Width is measured on the visible text, so colour never breaks alignment. */\nexport function stripAnsi(text: string): string {\n return text.replace(/\\u001b\\[\\d+m/g, \"\");\n}\n","export function supportsColor(jsonMode: boolean): boolean {\n return (\n process.stdout.isTTY === true &&\n process.env.NO_COLOR === undefined &&\n !jsonMode\n );\n}\n","import type { CliError } from \"./cli-error\";\nimport { COLORS, STATUS_COLORS } from \"@/lib/shared/output-constants\";\nimport { stripAnsi } from \"@/lib/ansi/strip-ansi\";\nimport { supportsColor } from \"@/lib/supports/supports-color\";\n\n/**\n * Two audiences, one command set: humans read the aligned text, agents pass\n * `--json` and parse stdout. Everything a command prints goes through here, so\n * `--json` is never partially honoured.\n */\nexport class CliOutput {\n private jsonMode = false;\n\n /** Declared once per run, before anything can fail. */\n setJson(enabled: boolean): void {\n this.jsonMode = enabled;\n }\n\n isJson(): boolean {\n return this.jsonMode;\n }\n\n json(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n }\n\n line(text = \"\"): void {\n process.stdout.write(`${text}\\n`);\n }\n\n error(text: string): void {\n // Sanitised like everything else: a failure message often carries a\n // session's statusReason, which is agent- or tool-authored text — and an\n // error line is the last thing that should be able to repaint the screen.\n process.stderr.write(`${this.paint(`error: ${this.safe(text)}`, \"red\")}\\n`);\n }\n\n // Progress a long command owes the user; stderr keeps `--json` stdout whole.\n warn(text: string): void {\n process.stderr.write(`${this.paint(this.safe(text), \"yellow\")}\\n`);\n }\n\n /**\n * The one place a failure is reported. Under `--json` stdout must be\n * parseable, and it was not: failures went to stderr as prose. Success keeps\n * its bare shape, so nothing that already parses stdout has to change.\n */\n failure(error: CliError): void {\n if (!this.jsonMode) {\n this.error(error.message);\n return;\n }\n\n this.json({\n ok: false,\n error: {\n ...(error.details.status === undefined\n ? {}\n : { status: error.details.status }),\n code: error.code,\n message: this.safe(error.message),\n ...(error.details.issues ? { issues: error.details.issues } : {}),\n ...(error.details.retryAfterSeconds === undefined\n ? {}\n : { retryAfterSeconds: error.details.retryAfterSeconds }),\n },\n // Inside the envelope, so stdout stays one parseable document.\n ...(error.result === undefined ? {} : { result: error.result }),\n });\n }\n\n paint(text: string, color: string): string {\n if (!supportsColor(this.jsonMode)) {\n return text;\n }\n return `${COLORS[color] ?? \"\"}${text}${COLORS.reset}`;\n }\n\n /**\n * Neutralise terminal control sequences in text the platform gives us.\n *\n * Transcript content, PR titles and question bodies carry model output, tool\n * output and repository contents — none of it trusted. Printed raw, an ESC\n * sequence could repaint or erase what the user already read, or emit an OSC\n * 8 hyperlink pointing somewhere else entirely. Newlines and tabs survive;\n * every other C0/C1 control does not. (`--json` is unaffected: JSON.stringify\n * already escapes control characters.)\n */\n safe(text: string): string {\n return text.replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]/g, \"\");\n }\n\n /** `safe`, flattened to one line — anything going into a table cell. */\n cell(text: string): string {\n return this.safe(text).replace(/\\s+/g, \" \").trim();\n }\n\n status(status: string): string {\n return this.paint(status, STATUS_COLORS[status] ?? \"reset\");\n }\n\n /** Left-aligned two-column block — the shape used by every list command. */\n table(rows: string[][]): void {\n if (rows.length === 0) {\n return;\n }\n const firstRow = rows[0];\n if (firstRow === undefined) {\n return;\n }\n const widths = firstRow.map((_, column) =>\n Math.max(...rows.map((row) => stripAnsi(row[column] ?? \"\").length)),\n );\n for (const row of rows) {\n const line = row\n .map((cell, column) => {\n const width = widths[column];\n if (width === undefined) {\n return cell;\n }\n const padding = width - stripAnsi(cell).length;\n return column === row.length - 1 ? cell : cell + \" \".repeat(padding);\n })\n .join(\" \");\n this.line(line.trimEnd());\n }\n }\n}\n","import { CliOutput } from \"@/lib/cli/cli-output\";\n\nexport const out = new CliOutput();\n","import { chmodSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nimport { CliError } from \"../cli/cli-error\";\nimport { DEFAULT_BASE_URL } from \"@/lib/shared/config-constants\";\nimport type { CliConfig } from \"@/lib/cli/cli-config\";\nimport { CONFIG_PATH } from \"@/lib/path/config-path-constants\";\nimport { readFileAsObject } from \"@/lib/file/read-file-as-object\";\nimport { configReadString } from \"@/lib/string/config-read-string\";\nimport { readUser } from \"@/lib/user/read-user\";\nimport { readHttpUrl } from \"@/lib/http/read-http-url\";\nimport { isSameOrigin } from \"@/lib/same/is-same-origin\";\n\n/**\n * `~/.hepha/config.json` — where a device-flow session lives between runs.\n *\n * Written 0600, because it holds a token that acts as the human. Agents are\n * expected to use HEPHA_API_KEY instead and never touch this file.\n */\nexport const config = {\n path: CONFIG_PATH,\n\n load(): CliConfig {\n const stored = readFileAsObject();\n const storedBaseUrl = readHttpUrl(stored.baseUrl);\n\n // A malformed HEPHA_URL is refused rather than ignored. Falling back would\n // run the command against production — with the production token, since\n // the origin would then match — which is the exact accident the\n // origin-binding below exists to prevent. A malformed value in the config\n // FILE still falls back: the user did not ask for it this run, and\n // bricking every command over a stale file helps nobody.\n const override = configReadString(process.env.HEPHA_URL);\n if (override && !readHttpUrl(override)) {\n throw new CliError(\n `HEPHA_URL is not a valid http(s) URL: \"${override}\".`,\n 2,\n );\n }\n\n const baseUrl = readHttpUrl(override) ?? storedBaseUrl ?? DEFAULT_BASE_URL;\n\n // The stored token is bound to the deployment it was issued by. Pointing\n // HEPHA_URL at staging or somebody else's instance must not send a human\n // bearer token for production to that origin — it would not authenticate\n // there, and it would hand the credential to whoever runs it.\n const token =\n storedBaseUrl && isSameOrigin(storedBaseUrl, baseUrl)\n ? configReadString(stored.token)\n : undefined;\n const user = token ? readUser(stored.user) : undefined;\n\n return {\n baseUrl,\n ...(token ? { token } : {}),\n ...(user ? { user } : {}),\n };\n },\n\n save(next: CliConfig): void {\n mkdirSync(dirname(CONFIG_PATH), { recursive: true, mode: 0o700 });\n writeFileSync(CONFIG_PATH, `${JSON.stringify(next, null, 2)}\\n`, {\n mode: 0o600,\n });\n chmodSync(CONFIG_PATH, 0o600);\n },\n\n clear(): void {\n rmSync(CONFIG_PATH, { force: true });\n },\n};\n","export const DEFAULT_BASE_URL = \"https://hephaistos.impulselab.ai\";\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nexport const CONFIG_PATH = join(homedir(), \".hepha\", \"config.json\");\n","import { readFileSync } from \"node:fs\";\nimport { CONFIG_PATH } from \"@/lib/path/config-path-constants\";\nexport function readFileAsObject(): Record<string, unknown> {\n try {\n const parsed: unknown = JSON.parse(readFileSync(CONFIG_PATH, \"utf8\"));\n // Valid JSON is not necessarily an object: a file holding `null` or a\n // bare string parses fine and then throws on the first property read,\n // taking down every command. Fall back to defaults instead.\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n return parsed as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n","/** A hand-edited file can hold anything; only usable strings get through. */\nexport function configReadString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n","import type { CliConfig } from \"@/lib/cli/cli-config\";\nimport { configReadString } from \"@/lib/string/config-read-string\";\nexport function readUser(value: unknown): CliConfig[\"user\"] {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const candidate = value as Record<string, unknown>;\n const user = {\n id: configReadString(candidate.id),\n name: configReadString(candidate.name),\n email: configReadString(candidate.email),\n };\n\n return user.id && user.name && user.email\n ? { id: user.id, name: user.name, email: user.email }\n : undefined;\n}\n","export function isHttpUrl(value: string): boolean {\n try {\n const parsed = new URL(value);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n","import { isHttpUrl } from \"@/lib/http/is-http-url\";\nimport { configReadString } from \"@/lib/string/config-read-string\";\n/** A usable base URL, or nothing — \"not a url\" would otherwise reach\n * `new URL()` in api.ts and break every command. */\nexport function readHttpUrl(value: unknown): string | undefined {\n const raw = configReadString(value);\n return raw && isHttpUrl(raw) ? raw : undefined;\n}\n","/** Same deployment? Compared on origin, so a trailing slash does not matter. */\nexport function isSameOrigin(a: string, b: string): boolean {\n try {\n return new URL(a).origin === new URL(b).origin;\n } catch {\n return false;\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n/**\n * Read at runtime, not baked in: CI stamps the real version onto package.json\n * when it publishes. Walking up covers both `dist/index.js` (installed) and\n * `src/lib/version.ts` (`pnpm dev`).\n */\nexport function readVersion(): string {\n let directory = dirname(fileURLToPath(import.meta.url));\n\n for (let depth = 0; depth < 5; depth += 1) {\n try {\n const manifest: unknown = JSON.parse(\n readFileSync(join(directory, \"package.json\"), \"utf8\"),\n );\n const version = (manifest as { version?: unknown }).version;\n if (typeof version === \"string\" && version.length > 0) {\n return version;\n }\n } catch {\n // Keep walking: not every ancestor holds a manifest.\n }\n const parent = dirname(directory);\n if (parent === directory) {\n break;\n }\n directory = parent;\n }\n\n return \"unknown\";\n}\n","import { readVersion } from \"@/lib/version/read-version\";\n\nexport const VERSION = readVersion();\n","export const HELP = `hepha — orchestrate Hephaistos sessions from a terminal or an agent.\n\nUSAGE\n hepha <command> [args] [--flags]\n\nTHE LOOP\n hepha run \"<prompt>\" --repo owner/repo --follow\n Start a session and follow it until it finishes or asks you something.\n Exit 0 completed · 3 waiting on a human · 1 failed.\n [--title \"…\"] [--task-type implement|new-project|question|draft|orchestrator]\n [--model <slug>] [--harness claude-code|codex] [--branch <name>]\n [--skill <id>]…\n hepha questions list [--session <id>]\n hepha questions show <batchId>\n hepha questions answer <batchId> --option <questionId>=1,2 --text <questionId>=\"…\"\n [--answers '<json array>']\n hepha questions cancel <batchId>\n hepha approvals list | show <id> | approve <id> | reject <id> --mode rework --feedback \"…\"\n\nSESSIONS\n hepha sessions list [--status active|waiting|done] [--repo owner/repo]\n [--search \"…\"] [--page N] [--limit N] [--all]\n hepha sessions get <id>\n hepha sessions logs <id> [--after <sequence>] [--limit N] [--follow]\n hepha sessions send <id> \"<message>\"\n hepha sessions pause|resume|archive <id>\n hepha sessions kill <id> [--reason \"…\"]\n hepha sessions checks|pr|verify <id>\n\nCATALOG\n hepha repos\n hepha branches <owner/repo>\n hepha models\n hepha skills\n\nAUTH\n hepha login [--url https://…] Device authorization: approve it in a browser.\n hepha logout\n hepha whoami\n hepha keys list\n hepha keys create <name> [--scope sessions:read]… [--expires-in-days 90]\n hepha keys revoke <keyId>\n\nENVIRONMENT\n HEPHA_API_KEY Act as an agent. Takes precedence over a stored login, so\n the human-only commands (approvals approve/reject, keys)\n answer 403 while it is set — unset it to act as yourself.\n HEPHA_TOKEN A device-flow session token, instead of ~/.hepha/config.json.\n HEPHA_URL Platform base URL.\n HEPHA_TIMEOUT_MS Per-request timeout in milliseconds (default 30000).\n HEPHA_FOLLOW_MAX_OUTAGE_SECONDS\n Give up this long after --follow's first failure, with that\n failure as the exit code. Unset, it waits for the platform\n to come back.\n\nGLOBAL FLAGS\n --json Machine-readable output on stdout. Every command that\n returns data honours it; login is interactive and does not.\n Failures print {\"ok\":false,\"error\":{…}} and keep their exit code.\n --quiet Suppress the streamed transcript while following a session.\n --version Print the version and exit.\n --help Print this.\n\nUnknown flags and surplus arguments are refused: for an agent, a typo must\nfail rather than run with default options.\n\n`;\n","import { config } from \"../../lib/shared/config\";\nimport { out } from \"../../lib/output/out\";\nimport { VERSION } from \"../../lib/version/version-constants\";\nimport { HELP } from \"@/commands/help/help-constants\";\n\nexport function helpCommand(): void {\n // Resolved, not a placeholder: the reader can click straight through to the\n // Scalar reference for the platform this CLI is actually pointed at.\n const baseUrl = config.load().baseUrl.replace(/\\/$/, \"\");\n out.line(`${HELP}hepha ${VERSION} · full reference: ${baseUrl}/api/v1/docs`);\n}\n","export const GLOBAL_BOOLEANS = [\"json\", \"help\", \"quiet\"] as const;\n","import { GLOBAL_BOOLEANS } from \"@/lib/args/args-constants\";\nexport const BOOLEAN_FLAGS = new Set<string>([\n ...GLOBAL_BOOLEANS,\n \"follow\",\n \"all\",\n \"version\",\n]);\n","import { BOOLEAN_FLAGS } from \"@/lib/boolean/boolean-flags-constants\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport function parseFlag(\n argv: string[],\n index: number,\n parsed: ParsedArgs,\n): number {\n const token = argv[index];\n if (token === undefined) {\n return index;\n }\n\n const withoutDashes = token.slice(2);\n const equalsAt = withoutDashes.indexOf(\"=\");\n let name: string;\n let value: string | undefined;\n\n if (equalsAt >= 0) {\n name = withoutDashes.slice(0, equalsAt);\n value = withoutDashes.slice(equalsAt + 1);\n // `--json=false` must not become a truthy boolean flag.\n if (BOOLEAN_FLAGS.has(name)) {\n throw new CliError(\n `--${name} is a boolean flag: pass --${name} to enable it, or omit it. \"--${name}=${value}\" is not a value.`,\n 2,\n );\n }\n } else {\n name = withoutDashes;\n const next = argv[index + 1];\n if (\n !BOOLEAN_FLAGS.has(name) &&\n next !== undefined &&\n !next.startsWith(\"--\")\n ) {\n value = next;\n index += 1;\n }\n }\n\n // Empty value flags are typos; accepting `--url=` can select another target.\n if (value === undefined || value.trim() === \"\") {\n if (!BOOLEAN_FLAGS.has(name)) {\n throw new CliError(`--${name} expects a value.`, 2);\n }\n parsed.booleans.add(name);\n return index;\n }\n\n parsed.flags[name] = value;\n (parsed.repeated[name] ??= []).push(value);\n return index;\n}\n","import { CliError } from \"../cli/cli-error\";\nimport { GLOBAL_BOOLEANS } from \"@/lib/args/args-constants\";\nimport type { ArgsSpec } from \"@/lib/args/args-spec\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nimport { parseFlag } from \"@/lib/args/parse-flag\";\n\n/**\n * A deliberately small parser: no dependency, and the grammar stays something an\n * agent can generate blind — `hepha <group> <command> [args] [--flags]`. Strict\n * on purpose: `hepha keys create x --scpoe admin` used to mint a key with the\n * DEFAULT scopes and exit 0.\n */\nexport class ArgsParser {\n parse(argv: string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n positional: [],\n flags: {},\n repeated: {},\n booleans: new Set(),\n };\n\n let flagsEnded = false;\n\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === undefined) {\n break;\n }\n\n // `--` ends option parsing: a prompt or a steering message is allowed to\n // start with dashes, and without this there is no way to send one.\n if (!flagsEnded && token === \"--\") {\n flagsEnded = true;\n continue;\n }\n\n if (flagsEnded || !token.startsWith(\"--\")) {\n parsed.positional.push(token);\n continue;\n }\n\n index = parseFlag(argv, index, parsed);\n }\n\n return parsed;\n }\n\n /**\n * Refuse anything this action does not understand. Called once the action is\n * known, because `sessions list` and `sessions logs` accept different flags.\n */\n expect(parsed: ParsedArgs, spec: ArgsSpec): void {\n const allowed = new Set<string>([\n ...GLOBAL_BOOLEANS,\n ...(spec.flags ?? []),\n ...(spec.booleans ?? []),\n ]);\n\n for (const name of [...Object.keys(parsed.flags), ...parsed.booleans]) {\n if (!allowed.has(name)) {\n throw new CliError(`Unknown flag --${name}.`, 2);\n }\n }\n\n const max = spec.positional ?? 0;\n if (parsed.positional.length > max) {\n const surplus = parsed.positional\n .slice(max)\n .map((value) => `\"${value}\"`)\n .join(\", \");\n throw new CliError(\n `Unexpected argument${parsed.positional.length - max > 1 ? \"s\" : \"\"} ${surplus}.`,\n 2,\n );\n }\n }\n\n /** The action name, validated against what the group actually implements. */\n action(\n parsed: ParsedArgs,\n group: string,\n allowed: readonly string[],\n fallback: string,\n ): string {\n const action = parsed.positional[0] ?? fallback;\n // Checked BEFORE the action's own arguments: `hepha approvals frobnicate`\n // used to ask for a <guardrailRequestId> it was never going to use.\n if (!allowed.includes(action)) {\n throw new CliError(\n `Unknown ${group} command \"${action}\". Expected one of: ${allowed.join(\", \")}.`,\n 2,\n );\n }\n return action;\n }\n\n required(parsed: ParsedArgs, index: number, name: string): string {\n const value = parsed.positional[index];\n if (!value) {\n throw new CliError(`Missing <${name}>.`, 2);\n }\n return value;\n }\n\n /**\n * A whole number inside a range, refused locally: `--page -1` used to come\n * back from the API as a bare \"Input validation failed\".\n */\n integer(\n parsed: ParsedArgs,\n name: string,\n bounds: { min?: number; max?: number } = {},\n ): number | undefined {\n const raw = parsed.flags[name];\n if (raw === undefined) {\n return undefined;\n }\n const trimmed = raw.trim();\n const value = Number(trimmed);\n // Number(\"\") is 0, so an empty `--limit=` would quietly mean zero.\n if (trimmed === \"\" || !Number.isFinite(value)) {\n throw new CliError(`--${name} expects a number, got \"${raw}\".`, 2);\n }\n if (!Number.isInteger(value)) {\n throw new CliError(`--${name} expects a whole number, got \"${raw}\".`, 2);\n }\n if (bounds.min !== undefined && value < bounds.min) {\n throw new CliError(`--${name} must be at least ${bounds.min}.`, 2);\n }\n if (bounds.max !== undefined && value > bounds.max) {\n throw new CliError(`--${name} must be at most ${bounds.max}.`, 2);\n }\n return value;\n }\n\n /** One of a fixed set, named in the error so the fix is obvious. */\n choice<T extends string>(\n parsed: ParsedArgs,\n name: string,\n allowed: readonly T[],\n ): T | undefined {\n const raw = parsed.flags[name];\n if (raw === undefined) {\n return undefined;\n }\n if (!(allowed as readonly string[]).includes(raw)) {\n throw new CliError(\n `--${name} expects one of: ${allowed.join(\", \")}. Got \"${raw}\".`,\n 2,\n );\n }\n return raw as T;\n }\n}\n","import { ArgsParser } from \"@/lib/args/args-parser\";\n\nexport const args = new ArgsParser();\n","/**\n * Was machine output asked for, before anything can fail?\n *\n * The failure path needs to know, and it starts in `main()`'s catch — including\n * for errors raised BY the parser, which is exactly when an agent most needs a\n * parseable answer. Mirrors the parser's own rule: a bare `--json` token, and\n * `--` ends option parsing so a prompt may still contain the word.\n */\nexport function wantsJson(argv: string[]): boolean {\n for (const token of argv) {\n if (token === \"--\") {\n return false;\n }\n if (token === \"--json\") {\n return true;\n }\n }\n return false;\n}\n","export const DEFAULT_TIMEOUT_MS = 30_000;\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { DEFAULT_TIMEOUT_MS } from \"@/lib/api/api-constants\";\nexport function resolveTimeout(override?: number): number {\n if (override !== undefined) {\n return override;\n }\n const raw = process.env.HEPHA_TIMEOUT_MS?.trim();\n if (!raw) {\n return DEFAULT_TIMEOUT_MS;\n }\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new CliError(\n `HEPHA_TIMEOUT_MS expects a positive number of milliseconds, got \"${raw}\".`,\n 2,\n );\n }\n return parsed;\n}\n","import { config } from \"@/lib/shared/config\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport type { RequestOptions } from \"@/lib/request/request-options\";\nexport function authHeaders(as: RequestOptions[\"as\"]): Record<string, string> {\n if (as) {\n return { authorization: `Bearer ${as.token}` };\n }\n\n const apiKey = process.env.HEPHA_API_KEY;\n if (apiKey) {\n // An agent's key wins over any stored human session, so a CI run is never\n // silently attributed to whoever last ran `hepha login` on the machine.\n return { \"x-api-key\": apiKey };\n }\n\n const token = process.env.HEPHA_TOKEN ?? config.load().token;\n if (token) {\n return { authorization: `Bearer ${token}` };\n }\n\n throw new CliError(\n \"Not signed in. Run `hepha login`, or set HEPHA_API_KEY to act as an agent.\",\n 1,\n { code: CLI_ERROR_CODES.NOT_AUTHENTICATED },\n );\n}\n","export function retryAfterSeconds(response: Response): number | undefined {\n // Better Auth answers `x-retry-after`, the public API answers the standard\n // header — read both rather than pick a side.\n const raw =\n response.headers.get(\"retry-after\") ??\n response.headers.get(\"x-retry-after\");\n if (!raw) {\n return undefined;\n }\n const seconds = Number(raw.trim());\n if (Number.isFinite(seconds)) {\n return seconds >= 0 ? seconds : undefined;\n }\n // RFC 9110 allows an HTTP-date instead of a delay, and proxies do send it.\n const date = Date.parse(raw.trim());\n return Number.isNaN(date)\n ? undefined\n : Math.max(0, (date - Date.now()) / 1_000);\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\n\ninterface FetchResponseOptions {\n url: URL;\n method: string;\n headers: HeadersInit;\n body: unknown;\n deadline: number;\n baseUrl: string;\n}\n\nexport async function fetchResponse({\n url,\n method,\n headers,\n body,\n deadline,\n baseUrl,\n}: FetchResponseOptions): Promise<[Response, string]> {\n const controller = new AbortController();\n let abortedBy: \"timeout\" | \"interrupt\" | null = null;\n const timer = setTimeout(() => {\n abortedBy ??= \"timeout\";\n controller.abort();\n }, deadline);\n const onInterrupt = () => {\n abortedBy ??= \"interrupt\";\n controller.abort();\n };\n process.once(\"SIGINT\", onInterrupt);\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n signal: controller.signal,\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n });\n return [response, await response.text()];\n } catch (cause) {\n if (abortedBy === \"interrupt\") {\n throw new CliError(`${method} ${url.pathname} interrupted.`, 130, {\n code: CLI_ERROR_CODES.INTERRUPTED,\n });\n }\n if (abortedBy === \"timeout\") {\n throw new CliError(\n `${method} ${url.pathname} timed out after ${deadline}ms. Raise HEPHA_TIMEOUT_MS if the platform is simply slow.`,\n 1,\n { code: CLI_ERROR_CODES.TIMEOUT },\n );\n }\n throw new CliError(\n `Cannot reach ${baseUrl}. Set HEPHA_URL if the platform lives elsewhere. (${String(cause)})`,\n 1,\n { code: CLI_ERROR_CODES.NETWORK },\n );\n } finally {\n clearTimeout(timer);\n process.removeListener(\"SIGINT\", onInterrupt);\n }\n}\n","import type { RequestOptions } from \"@/lib/request/request-options\";\n\nexport function addQueryParameters(\n url: URL,\n query: RequestOptions[\"query\"],\n): void {\n for (const [key, value] of Object.entries(query ?? {})) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n}\n","import { out } from \"@/lib/output/out\";\n/** Bounded and control-character-free: an HTML error page must not be able to\n * smuggle escape sequences into a terminal through a diagnostic. */\nexport function excerpt(text: string): string {\n const flattened = out.cell(text);\n return flattened.length > 200\n ? `${flattened.slice(0, 200)}\\u2026`\n : flattened;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { excerpt } from \"@/lib/excerpt/excerpt\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\n\nexport function parseResponsePayload(\n response: Response,\n text: string,\n request: { method: string; url: URL; retryAfter: number | undefined },\n): unknown {\n const { method, url, retryAfter } = request;\n\n if (!text) {\n return null;\n }\n\n try {\n return JSON.parse(text);\n } catch {\n const body = excerpt(text);\n const contentType = response.headers.get(\"content-type\") ?? \"unknown\";\n // A non-JSON error is primarily an upstream failure, not a URL diagnosis.\n throw new CliError(\n response.ok\n ? `${method} ${url.pathname} answered ${response.status} with a non-JSON body (${contentType}). Is HEPHA_URL pointing at a Hephaistos deployment?${body ? ` Body: ${body}` : \"\"}`\n : `${method} ${url.pathname} failed with ${response.status} and a non-JSON body (${contentType}).${body ? ` Body: ${body}` : \"\"}`,\n 1,\n {\n status: response.status,\n code: CLI_ERROR_CODES.NON_JSON_RESPONSE,\n ...(retryAfter === undefined ? {} : { retryAfterSeconds: retryAfter }),\n },\n );\n }\n}\n","export function readIssues(payload: unknown): unknown[] | undefined {\n if (!payload || typeof payload !== \"object\") {\n return undefined;\n }\n const data = (payload as { data?: unknown }).data;\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n const issues = (data as { issues?: unknown }).issues;\n return Array.isArray(issues) ? issues : undefined;\n}\n","export function readString(payload: unknown, key: string): string | undefined {\n if (!payload || typeof payload !== \"object\") {\n return undefined;\n }\n const value = (payload as Record<string, unknown>)[key];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n","import { readString } from \"@/lib/string/read-string\";\nexport function messageFrom(status: number, payload: unknown): string {\n const message = readString(payload, \"message\");\n if (message) {\n // A 403 with HEPHA_API_KEY set is almost always the precedence rule biting.\n return status === 403 && process.env.HEPHA_API_KEY\n ? `${message} (HEPHA_API_KEY is set and takes precedence over your \\`hepha login\\` session — unset it to act as yourself.)`\n : message;\n }\n if (status === 401) {\n return \"Unauthorized — your credential is missing, expired or revoked.\";\n }\n return `Request failed with status ${status}.`;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { readIssues } from \"@/lib/issues/read-issues\";\nimport { messageFrom } from \"@/lib/message/message-from\";\nimport { readString } from \"@/lib/string/read-string\";\n\nexport function throwResponseError(\n response: Response,\n payload: unknown,\n retryAfter: number | undefined,\n): never {\n // Pre-router refusals use `error`; oRPC responses take precedence via `code`.\n const code = readString(payload, \"code\") ?? readString(payload, \"error\");\n const issues = readIssues(payload);\n\n throw new CliError(\n messageFrom(response.status, payload) +\n (response.status === 429 && retryAfter !== undefined\n ? ` Retry in ${retryAfter}s.`\n : \"\"),\n 1,\n {\n status: response.status,\n ...(code ? { code } : {}),\n ...(issues ? { issues } : {}),\n ...(retryAfter === undefined ? {} : { retryAfterSeconds: retryAfter }),\n },\n );\n}\n","import { config } from \"../shared/config\";\nimport type { RequestOptions } from \"@/lib/request/request-options\";\nimport { resolveTimeout } from \"@/lib/timeout/resolve-timeout\";\nimport { authHeaders } from \"@/lib/auth/auth-headers\";\nimport { retryAfterSeconds } from \"@/lib/retry/retry-after-seconds\";\nimport { fetchResponse } from \"@/lib/response/fetch-response\";\nimport { addQueryParameters } from \"@/lib/api/add-query-parameters\";\nimport { parseResponsePayload } from \"@/lib/api/parse-response-payload\";\nimport { throwResponseError } from \"@/lib/api/throw-response-error\";\n\n/**\n * The one place the CLI talks to the platform.\n *\n * Every command names its REST path once and gets its types from the router\n * (api-inputs.ts), so there is no generated client to keep in step and no\n * second copy of the API surface.\n */\nexport async function api<T>(\n requestPath: string,\n options: RequestOptions = {},\n): Promise<T> {\n const baseUrl = options.as?.baseUrl ?? config.load().baseUrl;\n const url = new URL(`${baseUrl.replace(/\\/$/, \"\")}/api/v1${requestPath}`);\n addQueryParameters(url, options.query);\n\n // Resolved before the try: a missing credential is a usage error, not a\n // network failure, and must not be reported as one.\n const headers = {\n ...authHeaders(options.as),\n ...(options.body === undefined\n ? {}\n : { \"content-type\": \"application/json\" }),\n };\n\n const method = options.method ?? \"GET\";\n const deadline = resolveTimeout(options.timeoutMs);\n const [response, text] = await fetchResponse({\n url,\n method,\n headers,\n body: options.body,\n deadline,\n baseUrl,\n });\n\n const retryAfter = retryAfterSeconds(response);\n const payload = parseResponsePayload(response, text, {\n method,\n url,\n retryAfter,\n });\n\n if (!response.ok) {\n throwResponseError(response, payload, retryAfter);\n }\n\n return payload as T;\n}\n","/**\n * Build a REST path with every dynamic segment escaped.\n *\n * Session ids, key ids and repository names were interpolated raw, so a value\n * holding `?`, `#`, `/` or `%` silently moved the request to another route or\n * grew a query string the caller never wrote. A tagged template makes the safe\n * form the easy one, and the structural slashes stay in the literal parts.\n */\nexport function path(\n strings: TemplateStringsArray,\n ...values: string[]\n): string {\n return strings.reduce(\n (accumulator, literal, index) =>\n accumulator +\n (index === 0 ? \"\" : encodeURIComponent(values[index - 1] ?? \"\")) +\n literal,\n \"\",\n );\n}\n","export function read(payload: unknown, dotted: string): unknown {\n return dotted.split(\".\").reduce<unknown>((current, key) => {\n if (!current || typeof current !== \"object\") {\n return undefined;\n }\n return (current as Record<string, unknown>)[key];\n }, payload);\n}\n","import { CliError } from \"../cli/cli-error\";\nimport { VERSION } from \"../version/version-constants\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport type { Predicate } from \"@/lib/predicate/predicate\";\nimport { read } from \"@/lib/read/read\";\n\n/**\n * Check a 2xx payload before the command destructures it. The client casts\n * responses to the router's types — a compile-time promise about a server that\n * may be older or newer than this binary. When it did not hold, the first\n * property read threw `Cannot read properties of undefined`.\n */\nexport function expectShape<T>(\n payload: unknown,\n endpoint: string,\n requirements: Record<string, Predicate>,\n): T {\n for (const [field, predicate] of Object.entries(requirements)) {\n if (!predicate(read(payload, field))) {\n throw new CliError(\n `${endpoint} returned a payload this CLI does not understand: \"${field}\" is missing or has the wrong type. hepha ${VERSION} may be out of step with the platform — try \\`npm install -g @impulselab/hepha\\`.`,\n 1,\n { code: CLI_ERROR_CODES.API_SCHEMA_MISMATCH },\n );\n }\n }\n\n return payload as T;\n}\n","/** The handful of shapes the CLI actually destructures. */\nexport const is = {\n string: (value: unknown) => typeof value === \"string\",\n // Absent passes: a field a deployment older than this binary does not send.\n optionalString: (value: unknown) =>\n value === undefined || typeof value === \"string\",\n number: (value: unknown) => typeof value === \"number\",\n array: (value: unknown) => Array.isArray(value),\n object: (value: unknown) =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value),\n};\n","export const ACTIONS = [\"list\", \"show\", \"approve\", \"reject\"] as const;\n\nexport const REJECT_MODES = [\"rework\", \"terminate\"] as const;\n","import { api } from \"@/lib/api/api\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport async function listApprovals(asJson: boolean): Promise<void> {\n const result = expectShape<ApiOutputs[\"approvals\"][\"list\"]>(\n await api(\"/approvals\"),\n \"GET /approvals\",\n { items: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n if (result.items.length === 0) {\n out.line(\"No guardrail waiting on you.\");\n return;\n }\n out.table(\n result.items.map((item) => [\n out.cell(item.id),\n out.cell(item.guardrailKind),\n out.cell(item.repoName ?? \"—\"),\n out.cell(item.summary),\n ]),\n );\n}\n","import { api } from \"../../lib/api/api\";\nimport { path } from \"../../lib/path/path\";\nimport { args } from \"../../lib/args/args\";\nimport { CliError } from \"../../lib/cli/cli-error\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport {\n ACTIONS,\n REJECT_MODES,\n} from \"@/commands/approvals/approvals-constants\";\nimport { listApprovals } from \"@/commands/approvals/list-approvals\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Approving and rejecting require a human session and are refused for an API\n * key: a machine standing in for human validation would defeat the guardrail.\n */\nexport async function approvalsCommand(parsed: ParsedArgs): Promise<void> {\n const action = args.action(parsed, \"approvals\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n if (action === \"list\") {\n args.expect(parsed, { positional: 1 });\n return await listApprovals(asJson);\n }\n\n args.expect(parsed, {\n positional: 2,\n ...(action === \"reject\" ? { flags: [\"mode\", \"feedback\"] } : {}),\n });\n const guardrailId = args.required(parsed, 1, \"guardrailRequestId\");\n\n if (action === \"show\") {\n const detail = expectShape<ApiOutputs[\"approvals\"][\"get\"]>(\n await api(path`/approvals/${guardrailId}`),\n \"GET /approvals/{id}\",\n { guardrailKind: is.string, status: is.string, summary: is.string },\n );\n if (asJson) {\n out.json(detail);\n return;\n }\n out.line(\n `${out.paint(out.cell(detail.guardrailKind), \"bold\")} ${detail.status}`,\n );\n out.line(out.safe(detail.summary));\n out.line();\n out.json(detail.payload);\n return;\n }\n\n if (action === \"approve\") {\n const result = await api<ApiOutputs[\"approvals\"][\"approve\"]>(\n path`/approvals/${guardrailId}/approve`,\n { method: \"POST\", body: {} },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(`${out.paint(\"✓\", \"green\")} Approved ${out.cell(guardrailId)}`);\n return;\n }\n\n const mode = args.choice(parsed, \"mode\", REJECT_MODES) ?? \"rework\";\n if (mode === \"rework\" && !parsed.flags.feedback) {\n throw new CliError(\n \"--feedback is required with --mode rework: the agent needs to know what to change.\",\n 2,\n );\n }\n\n const result = await api<ApiOutputs[\"approvals\"][\"reject\"]>(\n path`/approvals/${guardrailId}/reject`,\n {\n method: \"POST\",\n body: {\n mode,\n ...(parsed.flags.feedback ? { feedback: parsed.flags.feedback } : {}),\n },\n },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n `${out.paint(\"✓\", \"green\")} Rejected ${out.cell(guardrailId)} (${mode})`,\n );\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { out } from \"@/lib/output/out\";\nimport { path } from \"@/lib/path/path\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogBranches(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, { positional: 1 });\n const repoFullName = args.required(parsed, 0, \"owner/repo\");\n const segments = repoFullName.split(\"/\");\n const [owner, repo] = segments;\n if (segments.length !== 2 || !owner || !repo) {\n throw new CliError(\n `Expected a repository as \"owner/repo\", got \"${repoFullName}\".`,\n 2,\n );\n }\n\n const result = await api<ApiOutputs[\"catalog\"][\"branches\"]>(\n path`/repos/${owner}/${repo}/branches`,\n );\n if (!result.result) {\n throw new CliError(`No GitHub installation covers ${repoFullName}.`);\n }\n if (asJson) {\n out.json(result);\n return;\n }\n for (const branch of result.result.branches) {\n out.line(\n branch === result.result.defaultBranch\n ? `${out.cell(branch)} ${out.paint(\"(default)\", \"dim\")}`\n : out.cell(branch),\n );\n }\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogModels(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, {});\n const result = expectShape<ApiOutputs[\"catalog\"][\"models\"]>(\n await api(\"/models\"),\n \"GET /models\",\n { harnesses: is.array, gatewayModels: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(out.paint(\"harnesses\", \"dim\"));\n for (const harness of result.harnesses) {\n out.line(` ${out.cell(harness)}`);\n }\n out.line();\n out.line(out.paint(\"gateway models\", \"dim\"));\n for (const model of result.gatewayModels) {\n out.line(` ${out.cell(model.id)}`);\n }\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Reads a catalog list endpoint: no flags accepted, the response shape checked\n * before anything renders it. Generic in the payload so each command keeps its\n * own contract from `ApiOutputs` and only names the array it expects.\n */\nexport async function readCatalogList<T>(\n parsed: ParsedArgs,\n path: string,\n field: string,\n): Promise<T> {\n args.expect(parsed, {});\n return expectShape<T>(await api(path), `GET ${path}`, { [field]: is.array });\n}\n","import { out } from \"@/lib/output/out\";\nimport { readCatalogList } from \"@/commands/catalog/read-catalog-list\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogRepos(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n const result = await readCatalogList<ApiOutputs[\"catalog\"][\"repos\"]>(\n parsed,\n \"/repos\",\n \"repos\",\n );\n if (asJson) {\n out.json(result);\n return;\n }\n for (const repo of result.repos) {\n out.line(out.cell(repo));\n }\n}\n","import { out } from \"@/lib/output/out\";\nimport { readCatalogList } from \"@/commands/catalog/read-catalog-list\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogSkills(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n const result = await readCatalogList<ApiOutputs[\"catalog\"][\"skills\"]>(\n parsed,\n \"/skills\",\n \"skills\",\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.table(\n result.skills.map((skill) => [\n out.cell(skill.id),\n out.cell(skill.name),\n out.cell(skill.description ?? \"\"),\n ]),\n );\n}\n","import { listCatalogBranches } from \"@/commands/catalog/list-catalog-branches\";\nimport { listCatalogModels } from \"@/commands/catalog/list-catalog-models\";\nimport { listCatalogRepos } from \"@/commands/catalog/list-catalog-repos\";\nimport { listCatalogSkills } from \"@/commands/catalog/list-catalog-skills\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * What `hepha catalog <topic>` can list. A table rather than a chain of\n * comparisons: adding a topic is one line, and the set of topics is readable\n * without following four branches.\n */\nexport const catalogTopics: Record<\n string,\n (parsed: ParsedArgs, asJson: boolean) => Promise<void>\n> = {\n branches: listCatalogBranches,\n models: listCatalogModels,\n repos: listCatalogRepos,\n skills: listCatalogSkills,\n};\n","import { CliError } from \"../../lib/cli/cli-error\";\nimport { catalogTopics } from \"@/commands/catalog/catalog-topics\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Read before creating a session: a repository outside `repos` is refused at\n * creation, and a model outside `models` is not routable.\n */\nexport async function catalogCommand(\n topic: string,\n parsed: ParsedArgs,\n): Promise<void> {\n const list = catalogTopics[topic];\n if (!list) {\n throw new CliError(`Unknown catalog topic \"${topic}\".`, 2);\n }\n await list(parsed, parsed.booleans.has(\"json\"));\n}\n","export const ACTIONS = [\"list\", \"create\", \"revoke\"] as const;\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport type { Scope } from \"@/commands/scope/scope\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function createKey(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, { flags: [\"scope\", \"expires-in-days\"], positional: 2 });\n const name = args.required(parsed, 1, \"name\");\n const scopes = parsed.repeated.scope as Scope;\n const expiresInDays = args.integer(parsed, \"expires-in-days\", {\n min: 1,\n max: 365,\n });\n const created = expectShape<ApiOutputs[\"keys\"][\"create\"]>(\n await api(\"/keys\", {\n method: \"POST\",\n body: {\n name,\n ...(scopes && scopes.length > 0 ? { scopes } : {}),\n ...(expiresInDays !== undefined ? { expiresInDays } : {}),\n },\n }),\n \"POST /keys\",\n { key: is.string, scopes: is.array },\n );\n if (asJson) {\n out.json(created);\n return;\n }\n out.line(\n `${out.paint(\"✓\", \"green\")} Created \"${out.cell(created.name ?? name)}\"`,\n );\n out.line();\n out.line(` ${out.paint(created.key, \"bold\")}`);\n out.line();\n out.line(\n out.paint(\n \" Copy it now — it is hashed at rest and never shown again.\",\n \"dim\",\n ),\n );\n out.line(out.paint(` Scopes: ${created.scopes.join(\" \")}`, \"dim\"));\n}\n","import { api } from \"../../lib/api/api\";\nimport { path } from \"../../lib/path/path\";\nimport { args } from \"../../lib/args/args\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport { ACTIONS } from \"@/commands/keys/keys-constants\";\nimport { createKey } from \"@/commands/key/create-key\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Human sessions only, by design: a key cannot mint or revoke a key, so the\n * whole group fails with a 403 when HEPHA_API_KEY is set.\n */\nexport async function keysCommand(parsed: ParsedArgs): Promise<void> {\n const action = args.action(parsed, \"keys\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n if (action === \"list\") {\n args.expect(parsed, { positional: 1 });\n const result = expectShape<ApiOutputs[\"keys\"][\"list\"]>(\n await api(\"/keys\"),\n \"GET /keys\",\n { keys: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n if (result.keys.length === 0) {\n out.line(\"No keys. Create one with `hepha keys create <name>`.\");\n return;\n }\n out.table([\n [\n out.paint(\"ID\", \"dim\"),\n out.paint(\"NAME\", \"dim\"),\n out.paint(\"PREFIX\", \"dim\"),\n out.paint(\"SCOPES\", \"dim\"),\n ],\n ...result.keys.map((key) => [\n out.cell(key.id),\n out.cell(key.name ?? \"—\"),\n out.cell(key.start ?? \"—\"),\n key.scopes.join(\" \"),\n ]),\n ]);\n return;\n }\n\n if (action === \"create\") {\n return await createKey(parsed, asJson);\n }\n\n args.expect(parsed, { positional: 2 });\n const keyId = args.required(parsed, 1, \"keyId\");\n const result = await api<ApiOutputs[\"keys\"][\"revoke\"]>(path`/keys/${keyId}`, {\n method: \"DELETE\",\n });\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(`${out.paint(\"✓\", \"green\")} Revoked ${out.cell(keyId)}`);\n}\n","import { createAuthClient } from \"better-auth/client\";\nimport { deviceAuthorizationClient } from \"better-auth/client/plugins\";\n\nimport { args } from \"../../lib/args/args\";\nimport { deviceTokenError } from \"../../lib/token/device-token-error\";\nimport { nextPollDelay } from \"../../lib/retry/next-poll-delay\";\nimport { CliError } from \"../../lib/cli/cli-error\";\nimport { openBrowser } from \"../../lib/browser/open-browser\";\nimport { out } from \"../../lib/output/out\";\nimport { MIN_BACKOFF } from \"@/commands/login/login-constants\";\nimport { CLIENT_ID } from \"@/commands/client/client-id-constants\";\nimport { sleep } from \"@/commands/sleep/sleep\";\nimport { completeLogin } from \"@/commands/complete/complete-login\";\nimport { resolveLoginBaseUrl } from \"@/commands/login/resolve-login-base-url\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * `hepha login` — OAuth 2.0 device authorization (RFC 8628).\n *\n * The CLI never sees a password and never asks for a pasted token: it gets a\n * short code, a human approves it in a browser that is already signed in to\n * Hephaistos, and only then does a session token exist. That approval is also\n * what makes a CLI session count as \"a human\" for guardrail decisions.\n */\nexport async function loginCommand(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, { flags: [\"url\"] });\n\n const baseUrl = resolveLoginBaseUrl(parsed);\n\n const authClient = createAuthClient({\n baseURL: baseUrl,\n plugins: [deviceAuthorizationClient()],\n });\n\n const { data: device, error: deviceError } = await authClient.device.code({\n client_id: CLIENT_ID,\n scope: \"openid profile email\",\n });\n\n if (deviceError || !device) {\n throw new CliError(\n deviceError?.error_description ??\n `Could not start a device login against ${baseUrl}.`,\n );\n }\n\n const verificationUrl =\n device.verification_uri_complete ?? device.verification_uri;\n\n out.line();\n out.line(` Code ${out.paint(out.cell(device.user_code), \"bold\")}`);\n out.line(` Open ${out.cell(verificationUrl)}`);\n out.line();\n out.line(out.paint(\" Waiting for approval…\", \"dim\"));\n\n openBrowser(verificationUrl);\n\n let interval = device.interval ?? 5;\n const deadline = Date.now() + (device.expires_in ?? 900) * 1000;\n\n while (Date.now() < deadline) {\n // Never sleep past the code's own expiry (see nextPollDelay).\n const delay = nextPollDelay(interval, (deadline - Date.now()) / 1000);\n if (delay === null) {\n break;\n }\n await sleep(delay);\n\n const { data: token, error } = await authClient.device.token({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: device.device_code,\n client_id: CLIENT_ID,\n });\n\n // A 429 is transient by definition, and giving up on one abandoned a login\n // the human was about to approve — with \"Device authorization failed.\" as\n // the only clue, because the rate limiter answers a plain message and none\n // of the OAuth error codes below. Back off for as long as the server asks\n // (it answers `x-retry-after`), with a floor, and keep polling.\n if (error?.status === 429) {\n interval = Math.max(\n deviceTokenError.retryAfter(error) ?? interval * 2,\n MIN_BACKOFF,\n );\n continue;\n }\n\n if (token?.access_token) {\n await completeLogin(baseUrl, token.access_token);\n return;\n }\n\n if (!error) {\n continue;\n }\n\n switch (error.error) {\n case \"authorization_pending\":\n continue;\n case \"slow_down\":\n interval += 5;\n continue;\n case \"access_denied\":\n throw new CliError(\"Access denied — the request was rejected.\");\n default:\n // The server's own message, when it has one. Collapsing everything\n // that is not an OAuth code into \"Device authorization failed.\" is how\n // a rate-limit refusal looked like a broken device flow.\n throw new CliError(\n error.error_description ||\n deviceTokenError.message(error) ||\n `Device authorization failed (HTTP ${error.status}).`,\n );\n }\n }\n\n throw new CliError(\"The code expired before it was approved. Try again.\");\n}\n","/**\n * The client types this error as the OAuth code set alone, but the refusals that\n * actually broke `hepha login` carry neither — a rate limiter answers a plain\n * message and a status. Hence reading defensively off `unknown`.\n */\nexport const deviceTokenError = {\n /** What the server said, when it said anything at all. */\n message(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const message = (error as { message?: unknown }).message;\n return typeof message === \"string\" && message.length > 0\n ? message\n : undefined;\n },\n\n /** Better Auth answers `X-Retry-After`, the platform the standard header. */\n retryAfter(error: unknown): number | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const headers = (error as { headers?: unknown }).headers;\n if (!(headers instanceof Headers)) {\n return undefined;\n }\n const raw =\n headers.get(\"x-retry-after\") ?? headers.get(\"retry-after\") ?? undefined;\n if (!raw) {\n return undefined;\n }\n const seconds = Number(raw.trim());\n return Number.isFinite(seconds) && seconds > 0 ? seconds : undefined;\n },\n};\n","/**\n * How long to wait before the next attempt, or null when there is no time left.\n * A loop that tests its deadline only BEFORE sleeping slept a grown backoff in\n * full — minutes past the expiry of the device code, or of a follow's budget.\n */\nexport function nextPollDelay(\n interval: number,\n remainingSeconds: number,\n): number | null {\n if (remainingSeconds <= 0) {\n return null;\n }\n return Math.min(interval, remainingSeconds);\n}\n","import { spawn } from \"node:child_process\";\n\n/**\n * Best effort: on a headless box or over SSH there is no browser to open, so a\n * failure here is not an error — the URL is always printed as well.\n */\nexport function openBrowser(url: string): void {\n const command =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"cmd\"\n : \"xdg-open\";\n const commandArgs =\n process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n\n try {\n const child = spawn(command, commandArgs, {\n stdio: \"ignore\",\n detached: true,\n });\n // A missing `xdg-open` (minimal containers, most SSH hosts) surfaces as an\n // ASYNCHRONOUS 'error' event that the try/catch cannot see. Unhandled, it\n // is an uncaught exception that kills the process mid-login — so the CLI\n // would stop polling instead of falling back to the printed URL.\n child.on(\"error\", () => {});\n child.unref();\n } catch {\n // Printing the URL is the fallback, and it already happened.\n }\n}\n","export const MIN_BACKOFF = 10;\n","export const USER_ROLES = {\n ADMIN: \"admin\",\n MEMBER: \"member\",\n} as const;\n\nexport type UserRole = (typeof USER_ROLES)[keyof typeof USER_ROLES];\nexport const ALL_USER_ROLES = Object.values(USER_ROLES);\n\nexport const ALLOWED_EMAIL_DOMAIN = \"@impulselab.ai\";\n\n/**\n * Public API scopes, in `resource:action` form. A Better Auth API key stores\n * them as its `permissions` map; a human session (browser cookie or a CLI\n * device-flow bearer token) implicitly holds every scope and is governed by\n * the user's role instead.\n *\n * Deliberately absent: `approvals:decide` and anything under `keys`. Guardrail\n * decisions (VISION \"never without explicit human validation\") and credential\n * issuance are human-only actions — no key can ever be granted them, so a\n * leaked key can neither approve a merge nor mint another key.\n */\nexport const API_SCOPES = [\n \"sessions:read\",\n \"sessions:write\",\n \"questions:read\",\n \"questions:answer\",\n \"approvals:read\",\n \"catalog:read\",\n \"pull_requests:read\",\n \"browser:read\",\n \"browser:write\",\n] as const;\n\nexport type ApiScope = (typeof API_SCOPES)[number];\n\n/** Read-only, minus the browser vault: it names the services a human uses. */\nexport const DEFAULT_API_SCOPES: readonly ApiScope[] = API_SCOPES.filter(\n (scope) => scope.endsWith(\":read\") && !scope.startsWith(\"browser:\"),\n);\n\n/** Prefix stamped on every issued key, so leaks are greppable. */\nexport const API_KEY_PREFIX = \"hepha_\";\n\n/** Header carrying an API key. Honoured on `/api/v1` only — see\n * utils/strip-api-key-header.ts for why. */\nexport const API_KEY_HEADER = \"x-api-key\";\n\n/**\n * Browser session lifetime. Signing in is always \"remember me\": there is no\n * opt-out in the UI, so every sign-in path writes a PERSISTENT cookie that\n * survives closing the browser. `UPDATE_AGE` slides the expiry forward on use,\n * so an active human never sees the sign-in screen again.\n */\nexport const SESSION = {\n /** Cookie + session row lifetime: 30 days. */\n EXPIRES_IN: 60 * 60 * 24 * 30,\n /** Refresh the expiry at most once a day, to avoid a write per request. */\n UPDATE_AGE: 60 * 60 * 24,\n /** Cache the session row in memory for this long, to avoid a read per request. */\n COOKIE_CACHE_MAX_AGE: 60,\n} as const;\n\n/**\n * OAuth 2.0 device authorization grant (RFC 8628) — how the CLI logs a human\n * in without ever handling their password: it asks for a user code, the human\n * approves it on {BASE_URL}{VERIFICATION_PATH} in an already-signed-in\n * browser, and the CLI exchanges the device code for a session token.\n */\nexport const DEVICE_AUTHORIZATION = {\n /** Only these clients may open a device flow. */\n CLIENT_IDS: [\"hepha-cli\", \"hepha-extension\"],\n /** Lifetime of an unapproved user code. */\n EXPIRES_IN: \"15m\",\n /** Minimum delay the CLI must wait between two token polls. */\n INTERVAL: \"5s\",\n /** Page a human visits to approve a pending device. */\n VERIFICATION_PATH: \"/device\",\n /**\n * Per-IP ceiling on `/device/token`. The window is deliberately SHORTER than\n * INTERVAL: Better Auth only resets its counter when two requests are further\n * apart than the window, so a 5s poll under the default 60s window never reset\n * it and every login 429'd partway through the code's lifetime.\n */\n POLL_RATE_LIMIT: { WINDOW_SECONDS: 4, MAX_REQUESTS: 10 },\n} as const;\n\n// Copied by hand into the extension, which ships no build step and cannot\n// import this; `apps/browser-extension/test/limits-match-server.test.mjs` fails on drift.\nexport const BROWSER_CAPTURE_LIMITS = {\n COOKIES: 300,\n ORIGINS: 25,\n STORAGE_KEYS_PER_ORIGIN: 300,\n NAME_LENGTH: 1024,\n VALUE_LENGTH: 32_768,\n /** `JSON.stringify(state).length`: UTF-16 code units, not bytes. */\n TOTAL_CHARS: 1_000_000,\n LABEL_LENGTH: 120,\n USER_AGENT_LENGTH: 512,\n LOCALE_LENGTH: 64,\n EXTENSION_VERSION_LENGTH: 32,\n DOMAINS_PER_USER: 200,\n} as const;\n\n/**\n * Bounds of a registry skill, shared by every write path so the registry can\n * never hold a skill the edit form refuses to save back.\n *\n * The caps used to be restated per route, so a skill written through one path\n * could violate another's rule and become uneditable for good.\n */\nexport const SKILL_LIMITS = {\n /** Kebab-case slug, matched verbatim by `buildHarnessSkills`. */\n NAME_PATTERN: /^[a-z0-9]+(-[a-z0-9]+)*$/,\n NAME_MAX_LENGTH: 80,\n /** Not a title: the full \"use this when…\" trigger list drives matching. */\n DESCRIPTION_MAX_LENGTH: 2000,\n /** Relative POSIX path of a supporting file bundled with the skill. */\n FILE_PATH_MAX_LENGTH: 200,\n /** One activation scope entry: a repo full name or a channel id. */\n ACTIVATION_SCOPE_MAX_LENGTH: 120,\n} as const;\n\n/** Reserved: the harness materializes the skill body as SKILL.md. */\nexport const SKILL_BODY_FILENAME = \"skill.md\";\n\n/** The auto-maintained global review-lessons skill; per-repo names come from\n * utils/review-lesson-skill-name.ts. */\nexport const REVIEW_LESSONS_SKILL_NAME = \"review-lessons\";\n\n// Derived by Chrome from the RSA key in `apps/browser-extension/manifest.json`.\n// One exact id, never a wildcard: trusted origins also allowlist redirects.\nexport const BROWSER_EXTENSION_ORIGIN =\n \"chrome-extension://ieppdghbneelaninllkeimfcdnccbblj\";\n","import { DEVICE_AUTHORIZATION } from \"@repo/database/constants\";\nexport const CLIENT_ID = DEVICE_AUTHORIZATION.CLIENT_IDS[0];\n","export function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n}\n","import { api } from \"@/lib/api/api\";\nimport { config } from \"@/lib/shared/config\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport async function completeLogin(\n baseUrl: string,\n token: string,\n): Promise<void> {\n const identity = await api<ApiOutputs[\"me\"][\"get\"]>(\"/me\", {\n as: { baseUrl, token },\n });\n config.save({\n baseUrl,\n token,\n user: {\n id: identity.user.id,\n name: identity.user.name,\n email: identity.user.email,\n },\n });\n out.line();\n out.line(\n `${out.paint(\"✓\", \"green\")} Signed in as ${identity.user.email} on ${baseUrl}`,\n );\n out.line(out.paint(` Session stored in ${config.path}`, \"dim\"));\n}\n","import { config } from \"@/lib/shared/config\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { isHttpUrl } from \"@/lib/http/is-http-url\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport function resolveLoginBaseUrl(parsed: ParsedArgs): string {\n const requested = parsed.flags.url?.trim();\n if (requested !== undefined && !isHttpUrl(requested)) {\n throw new CliError(`--url is not a valid http(s) URL: \"${requested}\".`, 2);\n }\n return (requested ?? config.load().baseUrl).replace(/\\/$/, \"\");\n}\n","import { args } from \"../../lib/args/args\";\nimport { config } from \"../../lib/shared/config\";\nimport { out } from \"../../lib/output/out\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/** Forgets the local session only; issued API keys keep working. */\nexport function logoutCommand(parsed: ParsedArgs): void {\n args.expect(parsed, {});\n\n config.clear();\n\n if (parsed.booleans.has(\"json\")) {\n out.json({ signedOut: true });\n return;\n }\n\n out.line(\"Signed out.\");\n}\n","export const LIMITS = {\n QUESTION_ID: 40,\n OPTION_ID: 40,\n OPTIONS_PER_ANSWER: 50,\n FREE_TEXT: 10_000,\n ANSWERS: 50,\n} as const;\n","import { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport { CliError } from \"@/lib/cli/cli-error\";\n\nexport function validateFreeText(\n value: string | undefined,\n label: string,\n): void {\n if (value === undefined) {\n return;\n }\n const freeText = value.trim();\n if (freeText.length === 0) {\n throw new CliError(`${label} has empty free text.`, 2);\n }\n if (freeText.length > LIMITS.FREE_TEXT) {\n throw new CliError(\n `${label} has free text longer than ${LIMITS.FREE_TEXT} characters.`,\n 2,\n );\n }\n}\n","import { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport { CliError } from \"@/lib/cli/cli-error\";\n\nexport function validateSelectedOptionIds(\n options: string[] | undefined,\n label: string,\n): void {\n if (options === undefined) {\n return;\n }\n if (options.length > LIMITS.OPTIONS_PER_ANSWER) {\n throw new CliError(\n `${label} selects more than ${LIMITS.OPTIONS_PER_ANSWER} options.`,\n 2,\n );\n }\n for (const id of options) {\n if (id.trim().length === 0) {\n throw new CliError(`${label} has an empty option id.`, 2);\n }\n if (id.trim().length > LIMITS.OPTION_ID) {\n throw new CliError(\n `${label} has an option id longer than ${LIMITS.OPTION_ID} characters.`,\n 2,\n );\n }\n }\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport type { Answer } from \"@/commands/answer/answer\";\nimport { validateFreeText } from \"@/commands/answer/validate-free-text\";\nimport { validateSelectedOptionIds } from \"@/commands/answer/validate-selected-option-ids\";\n/** `label` names the source — `--answers[2]` or `--option q1=…` — because both\n * entry paths build the same shape and must fail identically. */\nexport function validateAnswer(answer: Answer, label: string): void {\n // The ONE field the server does not trim, so its ceiling applies to the raw\n // value. Emptiness is checked more strictly than the API on purpose: a blank\n // id passes `min(1)` and then matches no question, leaving the round silently\n // unanswered.\n if (answer.questionId.trim().length === 0) {\n throw new CliError(`${label} needs a non-empty \"questionId\".`, 2);\n }\n if (answer.questionId.length > LIMITS.QUESTION_ID) {\n throw new CliError(\n `${label} has a \"questionId\" longer than ${LIMITS.QUESTION_ID} characters.`,\n 2,\n );\n }\n\n const options = answer.selectedOptionIds;\n validateSelectedOptionIds(options, label);\n validateFreeText(answer.freeText, label);\n\n // The server's own rule; `--option q1=,,` reaches exactly this shape.\n if (\n (options === undefined || options.length === 0) &&\n answer.freeText === undefined\n ) {\n throw new CliError(\n `${label} answers nothing. Give it at least one option id or some free text.`,\n 2,\n );\n }\n}\n","import { validateAnswer } from \"@/commands/answer/validate-answer\";\nimport type { Answer } from \"@/commands/answer/answer\";\nimport { CliError } from \"@/lib/cli/cli-error\";\n\nexport function parseAnswerEntry(entry: unknown, label: string): Answer {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new CliError(`${label} must be an object.`, 2);\n }\n\n const answer = entry as Record<string, unknown>;\n if (typeof answer.questionId !== \"string\") {\n throw new CliError(`${label} needs a non-empty \"questionId\".`, 2);\n }\n if (\n answer.selectedOptionIds !== undefined &&\n (!Array.isArray(answer.selectedOptionIds) ||\n answer.selectedOptionIds.some((id) => typeof id !== \"string\"))\n ) {\n throw new CliError(\n `${label}.selectedOptionIds must be an array of strings.`,\n 2,\n );\n }\n if (answer.freeText !== undefined && typeof answer.freeText !== \"string\") {\n throw new CliError(`${label}.freeText must be a string.`, 2);\n }\n\n const parsed = entry as Answer;\n validateAnswer(parsed, label);\n return parsed;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport type { Answers } from \"@/commands/answers/answers\";\nimport { parseAnswerEntry } from \"@/commands/answers/parse-answer-entry\";\n/** `--answers '{}'` used to sail through `JSON.parse` and be posted as\n * `{\"answers\": {}}`, contradicting the CLI's own error message. */\nexport function parseAnswersFlag(raw: string): Answers {\n let decoded: unknown;\n try {\n decoded = JSON.parse(raw);\n } catch {\n throw new CliError(\"--answers expects a JSON array.\", 2);\n }\n\n if (!Array.isArray(decoded) || decoded.length === 0) {\n throw new CliError(\n '--answers expects a non-empty JSON array, e.g. \\'[{\"questionId\":\"q1\",\"selectedOptionIds\":[\"1\"]}]\\'.',\n 2,\n );\n }\n\n if (decoded.length > LIMITS.ANSWERS) {\n throw new CliError(\n `--answers carries more than ${LIMITS.ANSWERS} entries.`,\n 2,\n );\n }\n\n for (const [index, entry] of decoded.entries()) {\n parseAnswerEntry(entry, `--answers[${index}]`);\n }\n\n return decoded as Answers;\n}\n","import { CliError } from \"../../lib/cli/cli-error\";\nimport { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport type { Answers } from \"@/commands/answers/answers\";\nimport type { Answer } from \"@/commands/answer/answer\";\nimport { validateAnswer } from \"@/commands/answer/validate-answer\";\nimport { parseAnswersFlag } from \"@/commands/answers/parse-answers-flag\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/** `--option <questionId>=1,2` and `--text <questionId>=…`, or `--answers <json>`. */\nexport function collectAnswers(parsed: ParsedArgs): Answers {\n if (parsed.flags.answers) {\n return parseAnswersFlag(parsed.flags.answers);\n }\n\n const byQuestion = new Map<string, Answer>();\n\n const put = (pair: string, apply: (entry: Answer) => void) => {\n const equalsAt = pair.indexOf(\"=\");\n if (equalsAt < 0) {\n throw new CliError(`Expected <questionId>=<value>, got \"${pair}\".`, 2);\n }\n const questionId = pair.slice(0, equalsAt);\n const entry = byQuestion.get(questionId) ?? { questionId };\n apply(entry);\n byQuestion.set(questionId, entry);\n };\n\n for (const pair of parsed.repeated.option ?? []) {\n put(pair, (entry) => {\n entry.selectedOptionIds = pair\n .slice(pair.indexOf(\"=\") + 1)\n .split(\",\")\n .map((id) => id.trim())\n .filter(Boolean);\n });\n }\n\n for (const pair of parsed.repeated.text ?? []) {\n put(pair, (entry) => {\n entry.freeText = pair.slice(pair.indexOf(\"=\") + 1);\n });\n }\n\n const answers = [...byQuestion.values()];\n if (answers.length === 0) {\n throw new CliError(\n \"Nothing to submit. Use --option <questionId>=<ids>, --text <questionId>=<answer>, or --answers <json>.\",\n 2,\n );\n }\n if (answers.length > LIMITS.ANSWERS) {\n throw new CliError(\n `More than ${LIMITS.ANSWERS} answers in one submission.`,\n 2,\n );\n }\n\n for (const answer of answers) {\n validateAnswer(answer, `--option/--text ${answer.questionId}`);\n }\n\n return answers;\n}\n","export const ACTIONS = [\"list\", \"show\", \"answer\", \"cancel\"] as const;\n","import { api } from \"@/lib/api/api\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport { path } from \"@/lib/path/path\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport async function listQuestions(\n sessionId: string | undefined,\n asJson: boolean,\n): Promise<void> {\n const result = expectShape<ApiOutputs[\"questions\"][\"list\"]>(\n await api(\n sessionId ? path`/sessions/${sessionId}/questions` : \"/questions\",\n ),\n \"GET /questions\",\n { items: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n if (result.items.length === 0) {\n out.line(\"Nothing waiting on you.\");\n return;\n }\n out.table(\n result.items.map((batch) => [\n out.cell(batch.id),\n out.cell(batch.sessionId),\n `${batch.questions.length} question(s)`,\n out.cell(batch.sessionTitle),\n ]),\n );\n}\n","import type { Batch } from \"@/commands/batch/batch\";\nimport { out } from \"@/lib/output/out\";\n\nexport function printBatchQuestion(question: Batch[\"questions\"][number]): void {\n out.line();\n if (question.header) {\n out.line(out.paint(out.cell(question.header), \"dim\"));\n }\n out.line(\n `${out.paint(out.cell(question.id), \"dim\")} ${out.safe(question.body)}`,\n );\n if (question.image) {\n out.line(out.paint(` (image) ${out.cell(question.image)}`, \"dim\"));\n }\n for (const option of question.options) {\n const recommended = option.id === question.recommendedOptionId;\n // Image-only options still need an identifiable terminal label.\n const label = option.label\n ? out.cell(option.label)\n : option.image\n ? out.paint(`(image) ${out.cell(option.image)}`, \"dim\")\n : out.paint(\"(no label)\", \"dim\");\n out.line(\n ` ${out.cell(option.id)}) ${label}${recommended ? out.paint(\" ← recommended\", \"green\") : \"\"}`,\n );\n }\n if (question.allowFreeText) {\n out.line(out.paint(\" free text accepted\", \"dim\"));\n }\n}\n","import { out } from \"@/lib/output/out\";\nimport type { Batch } from \"@/commands/batch/batch\";\nimport { printBatchQuestion } from \"@/commands/batch/print-batch-question\";\nexport function printBatch(batch: Batch): void {\n // Questions are agent-authored text — sanitise before printing (out.safe).\n out.line(\n `${out.paint(out.cell(batch.sessionTitle), \"bold\")} ${out.paint(`round ${batch.round}`, \"dim\")}`,\n );\n out.line(\n out.paint(\n `batch ${out.cell(batch.id)} · session ${out.cell(batch.sessionId)}`,\n \"dim\",\n ),\n );\n\n for (const question of batch.questions) {\n printBatchQuestion(question);\n }\n}\n","import { api } from \"../../lib/api/api\";\nimport { path } from \"../../lib/path/path\";\nimport { args } from \"../../lib/args/args\";\nimport { collectAnswers } from \"../answers/collect-answers\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport { ACTIONS } from \"@/commands/questions/questions-constants\";\nimport type { Batch } from \"@/commands/batch/batch\";\nimport { listQuestions } from \"@/commands/questions/list-questions\";\nimport { printBatch } from \"@/commands/batch/print-batch\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * A session with an unanswered round parks forever. Answering is a normal\n * scope, so an agent can do it; only guardrail decisions need a human.\n */\nexport async function questionsCommand(parsed: ParsedArgs): Promise<void> {\n const action = args.action(parsed, \"questions\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n if (action === \"list\") {\n args.expect(parsed, { flags: [\"session\"], positional: 1 });\n return await listQuestions(parsed.flags.session, asJson);\n }\n\n args.expect(parsed, {\n positional: 2,\n ...(action === \"answer\" ? { flags: [\"option\", \"text\", \"answers\"] } : {}),\n });\n const batchId = args.required(parsed, 1, \"batchId\");\n\n if (action === \"show\") {\n const batch = expectShape<Batch>(\n await api(path`/questions/${batchId}`),\n \"GET /questions/{id}\",\n { id: is.string, questions: is.array, sessionTitle: is.string },\n );\n if (asJson) {\n out.json(batch);\n return;\n }\n printBatch(batch);\n return;\n }\n\n if (action === \"answer\") {\n const result = expectShape<ApiOutputs[\"questions\"][\"submit\"]>(\n await api(path`/questions/${batchId}/submit`, {\n method: \"POST\",\n body: { answers: collectAnswers(parsed) },\n }),\n \"POST /questions/{id}/submit\",\n { answeredCount: is.number },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n `${out.paint(\"✓\", \"green\")} Answered ${result.answeredCount} question(s); the session resumes.`,\n );\n return;\n }\n\n const result = await api<ApiOutputs[\"questions\"][\"cancel\"]>(\n path`/questions/${batchId}/cancel`,\n { method: \"POST\", body: {} },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n 'Round cancelled. The session stays parked — send a message to steer it: `hepha sessions send <id> \"…\"`',\n );\n}\n","export const POLL_SECONDS = 3;\n\nexport const PAGE_SIZE = 200;\n","import { out } from \"@/lib/output/out\";\n/** Sanitised first: transcript text is model, tool and repository output. */\nexport function truncate(text: string, max = 2000): string {\n const trimmed = out.safe(text).trim();\n return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;\n}\n","import { out } from \"../output/out\";\nimport type { TranscriptEvent } from \"@/lib/event/transcript-event\";\nimport { truncate } from \"@/lib/truncate/truncate\";\n\n/**\n * One transcript event as one readable block.\n *\n * The transcript is the only honest account of what the agent did, so the\n * shapes that matter to a reviewer — tool calls, file changes, questions,\n * guardrails, errors — each keep a distinct marker instead of collapsing into\n * prose.\n */\nexport function formatEvent(event: TranscriptEvent): string | null {\n const part = event.part;\n\n switch (part.kind) {\n case \"text\":\n if (part.authorUserId) {\n return `${out.paint(\"you\", \"magenta\")} ${truncate(part.text)}`;\n }\n // Text with no author but a source was injected by the platform (an\n // integration trigger, an inbox event): the transcript contract says it\n // must never be attributed to the model.\n if (part.source) {\n return out.paint(`system ${truncate(part.text, 400)}`, \"dim\");\n }\n return `${out.paint(\"agent\", \"blue\")} ${truncate(part.text)}`;\n case \"reasoning\":\n return out.paint(`think ${truncate(part.text, 400)}`, \"dim\");\n case \"tool\":\n return `${out.paint(\"tool\", \"dim\")} ${out.cell(part.toolName)} ${out.paint(`(${part.status})`, \"dim\")}`;\n case \"file_change\":\n return `${out.paint(\"file\", \"dim\")} ${part.changeType.padEnd(8)} ${out.cell(part.path)}`;\n case \"question\":\n return out.paint(\n `ask question round ${part.questionBatchId} — answer with \\`hepha questions answer ${part.questionBatchId}\\``,\n \"yellow\",\n );\n // No CLI verb decides a plan: the accept/refuse pair lives in the app.\n case \"plan\":\n return out.paint(\n `plan plan ${part.planProposalId} awaits accept/refuse in the app`,\n \"yellow\",\n );\n case \"approval\":\n return out.paint(\n `gate guardrail ${part.guardrailRequestId} needs a human — \\`hepha approvals show ${part.guardrailRequestId}\\``,\n \"yellow\",\n );\n case \"media\": {\n // The signed URL is why this part exists: a screenshot or a recording is\n // the session's proof, and a reader who cannot open it has nothing.\n const target = part.url ?? part.pathname;\n return `${out.paint(\"media\", \"dim\")} ${part.mediaType}${part.caption ? ` — ${out.cell(part.caption)}` : \"\"}${target ? `\\n ${out.cell(target)}` : \"\"}`;\n }\n case \"error\":\n return out.paint(`error ${truncate(part.message)}`, \"red\");\n case \"external_event\":\n return `${out.paint(\"event\", \"dim\")} ${out.cell(part.title)}${part.conclusion ? ` — ${out.cell(part.conclusion)}` : \"\"}`;\n case \"system\":\n return out.paint(`system ${truncate(part.text, 300)}`, \"dim\");\n case \"verification\":\n return `${out.paint(\"check\", \"dim\")} ${out.cell(part.name)} ${out.paint(`(${part.status})`, \"dim\")}`;\n default:\n return null;\n }\n}\n","import { formatEvent } from \"@/lib/event/format-event\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport function consumeSessionEvents(\n events: ApiOutputs[\"sessions\"][\"events\"][\"items\"],\n cursor: number,\n quiet: boolean | undefined,\n): number {\n for (const event of events) {\n cursor = Math.max(cursor, event.sequence);\n if (quiet) {\n continue;\n }\n const line = formatEvent(event);\n if (line) {\n out.line(line);\n }\n }\n return cursor;\n}\n","export function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n}\n","// setTimeout stores its delay in a signed 32-bit int and fires AT ONCE past it.\nexport const MAX_TIMER_MS = 2_147_483_647;\n","import { MAX_TIMER_MS } from \"./sleep-constants\";\n\n/** A wait a timer can actually hold: longer means \"as long as it can\". */\nexport function timerDelayMs(seconds: number): number {\n return Math.min(Math.max(0, seconds) * 1_000, MAX_TIMER_MS);\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport { timerDelayMs } from \"./timer-delay-ms\";\n\nexport function interruptibleSleep(seconds: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const onInterrupt = () => {\n clearTimeout(timer);\n reject(\n new CliError(\"Follow interrupted.\", 130, {\n code: CLI_ERROR_CODES.INTERRUPTED,\n }),\n );\n };\n const timer = setTimeout(() => {\n process.removeListener(\"SIGINT\", onInterrupt);\n resolve();\n }, timerDelayMs(seconds));\n process.once(\"SIGINT\", onInterrupt);\n });\n}\n","import { api } from \"@/lib/api/api\";\nimport { out } from \"@/lib/output/out\";\nimport { sleep } from \"@/lib/sleep/sleep\";\nimport { interruptibleSleep } from \"@/lib/sleep/interruptible-sleep\";\nimport type { FollowSessionDependencies } from \"./follow-session-dependencies\";\n\nexport const defaultFollowSessionDependencies: FollowSessionDependencies = {\n request: api,\n pollSleep: sleep,\n retrySleep: interruptibleSleep,\n random: Math.random,\n // Monotonic: an NTP step backwards must not hand the outage budget more time\n // to burn, nor mute the periodic reminder until the clock catches up.\n now: () => performance.now(),\n warn: (message) => out.warn(message),\n};\n","export function followOutageMessage(warned: boolean): string {\n return warned\n ? \"Hepha API still unavailable; retrying follow.\"\n : \"Hepha API unavailable; retrying follow.\";\n}\n","export const FOLLOW_RETRY_CAP_SECONDS = 22.5;\nexport const FOLLOW_OUTAGE_FEEDBACK_MS = 5 * 60 * 1_000;\n// The platform's own transient class, kept identical: see TRANSIENT_STATUS in\n// packages/tasks/src/lib/failure/classify/classify-harness-failure-constants.ts.\nexport const RETRYABLE_FOLLOW_STATUS = new Set([\n 408, 425, 429, 500, 502, 503, 504,\n]);\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { FOLLOW_RETRY_CAP_SECONDS } from \"./follow-retry-constants\";\n\nexport function followRetryDelay(\n error: CliError,\n failures: number,\n random: () => number,\n): number {\n const exponential = Math.min(\n FOLLOW_RETRY_CAP_SECONDS,\n 2 ** Math.min(failures - 1, 30),\n );\n const jittered = exponential / 2 + random() * (exponential / 2);\n // Retry-After is the server telling us when it will be ready: honoured whole,\n // and merely spread on top so followers do not wake as one.\n const retryAfter = Math.max(0, error.details.retryAfterSeconds ?? 0);\n return Math.max(jittered, retryAfter + random() * (exponential / 2));\n}\n","/** Infinity when no budget was set: the follow then waits any outage out. */\nexport function remainingOutageSeconds(\n outageStartedAt: number,\n now: number,\n maxOutageMs: number | null,\n): number {\n if (maxOutageMs === null) {\n return Number.POSITIVE_INFINITY;\n }\n return (maxOutageMs - (now - outageStartedAt)) / 1_000;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport { RETRYABLE_FOLLOW_STATUS } from \"./follow-retry-constants\";\n\nexport function retryableFollowError(error: unknown): error is CliError {\n return (\n error instanceof CliError &&\n (RETRYABLE_FOLLOW_STATUS.has(error.details.status ?? 0) ||\n error.details.code === CLI_ERROR_CODES.NETWORK ||\n error.details.code === CLI_ERROR_CODES.TIMEOUT)\n );\n}\n","import { FOLLOW_OUTAGE_FEEDBACK_MS } from \"./follow-retry-constants\";\n\nexport function shouldReportFollowOutage(\n lastWarnedAt: number | null,\n now: number,\n): boolean {\n return (\n lastWarnedAt === null || now - lastWarnedAt >= FOLLOW_OUTAGE_FEEDBACK_MS\n );\n}\n","import { nextPollDelay } from \"@/lib/retry/next-poll-delay\";\nimport type { FollowSessionDependencies } from \"../follow-session-dependencies\";\nimport { followOutageMessage } from \"./follow-outage-message\";\nimport { followRetryDelay } from \"./follow-retry-delay\";\nimport type { FollowRetryState } from \"./follow-retry-state\";\nimport { remainingOutageSeconds } from \"./remaining-outage-seconds\";\nimport { retryableFollowError } from \"./retryable-follow-error\";\nimport { shouldReportFollowOutage } from \"./should-report-follow-outage\";\n\n/** Wait out one failure, or rethrow the ones a follow cannot sit through. */\nexport async function waitForFollowRetry(params: {\n error: unknown;\n retry: FollowRetryState;\n maxOutageMs: number | null;\n dependencies: FollowSessionDependencies;\n}): Promise<void> {\n const { error, retry, dependencies } = params;\n if (!retryableFollowError(error)) {\n throw error;\n }\n retry.failures += 1;\n const now = dependencies.now();\n retry.outageStartedAt ??= now;\n // Unbudgeted, a follow waits any outage out; budgeted, the sleep stops at the\n // deadline and the last failure reaches the caller as its exit code.\n const delay = nextPollDelay(\n followRetryDelay(error, retry.failures, dependencies.random),\n remainingOutageSeconds(retry.outageStartedAt, now, params.maxOutageMs),\n );\n if (delay === null) {\n throw error;\n }\n if (shouldReportFollowOutage(retry.lastWarnedAt, now)) {\n dependencies.warn(followOutageMessage(retry.warned));\n retry.warned = true;\n retry.lastWarnedAt = now;\n }\n await dependencies.retrySleep(delay);\n // Waking up on the deadline itself: fail with the real failure rather than\n // spend the caller's last millisecond on a request that cannot land.\n if (\n remainingOutageSeconds(\n retry.outageStartedAt,\n dependencies.now(),\n params.maxOutageMs,\n ) <= 0\n ) {\n throw error;\n }\n}\n","import type { FollowSessionDependencies } from \"../follow-session-dependencies\";\nimport type { FollowRetryState } from \"./follow-retry-state\";\nimport { waitForFollowRetry } from \"./wait-for-follow-retry\";\n\nexport async function requestWithFollowRetry<T>(params: {\n operation: () => Promise<T>;\n retry: FollowRetryState;\n maxOutageMs: number | null;\n dependencies: FollowSessionDependencies;\n}): Promise<T> {\n for (;;) {\n try {\n const result = await params.operation();\n if (params.retry.warned) {\n params.dependencies.warn(\"Hepha API recovered; continuing follow.\");\n }\n params.retry.failures = 0;\n params.retry.warned = false;\n params.retry.lastWarnedAt = null;\n params.retry.outageStartedAt = null;\n return result;\n } catch (error) {\n await waitForFollowRetry({\n error,\n retry: params.retry,\n maxOutageMs: params.maxOutageMs,\n dependencies: params.dependencies,\n });\n }\n }\n}\n","export const BLOCKED = new Set([\"waiting_human\", \"awaiting_approval\"]);\n","export const TERMINAL = new Set([\"completed\", \"failed\", \"killed\", \"abstained\"]);\n","import { BLOCKED } from \"@/lib/blocked/blocked-constants\";\nimport { TERMINAL } from \"@/lib/terminal/terminal-constants\";\n\n// Undefined is a deployment too old to report the status on an events page.\nexport function isFollowStopStatus(status: string | undefined): boolean {\n return status !== undefined && (TERMINAL.has(status) || BLOCKED.has(status));\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\n\n/** Unset means forever: only a caller with no Ctrl-C needs an exit code. */\nexport function resolveFollowOutageBudget(): number | null {\n const raw = process.env.HEPHA_FOLLOW_MAX_OUTAGE_SECONDS?.trim();\n if (!raw) {\n return null;\n }\n // Checked in milliseconds: a finite 1e306 seconds overflows to an Infinity\n // budget, which would silently never expire.\n const budgetMs = Number(raw) * 1_000;\n if (!Number.isFinite(budgetMs) || budgetMs <= 0) {\n throw new CliError(\n `HEPHA_FOLLOW_MAX_OUTAGE_SECONDS expects a positive number of seconds, got \"${raw}\".`,\n 2,\n );\n }\n return budgetMs;\n}\n","import { resolveTimeout } from \"@/lib/timeout/resolve-timeout\";\nimport type { FollowRetryState } from \"./follow-retry-state\";\nimport { remainingOutageSeconds } from \"./remaining-outage-seconds\";\n\n/** A request may not outlive the outage budget it is being retried under. */\nexport function followRequestTimeoutMs(\n retry: FollowRetryState,\n maxOutageMs: number | null,\n now: number,\n): number {\n if (retry.outageStartedAt === null) {\n return resolveTimeout();\n }\n const remainingMs =\n remainingOutageSeconds(retry.outageStartedAt, now, maxOutageMs) * 1_000;\n return Math.max(1, Math.min(resolveTimeout(), remainingMs));\n}\n","import { path } from \"../path/path\";\nimport { expectShape } from \"../expect/expect-shape\";\nimport { is } from \"../is/is\";\nimport { POLL_SECONDS, PAGE_SIZE } from \"@/lib/follow/follow-constants\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\nimport { consumeSessionEvents } from \"@/lib/session/consume-session-events\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { FollowRetryState } from \"@/lib/session/retry/follow-retry-state\";\nimport type { FollowSessionDependencies } from \"@/lib/session/follow-session-dependencies\";\nimport { defaultFollowSessionDependencies } from \"@/lib/session/default-follow-session-dependencies\";\nimport { requestWithFollowRetry } from \"@/lib/session/retry/request-with-follow-retry\";\nimport { isFollowStopStatus } from \"@/lib/session/is-follow-stop-status\";\nimport { resolveFollowOutageBudget } from \"@/lib/session/retry/resolve-follow-outage-budget\";\nimport { followRequestTimeoutMs } from \"@/lib/session/retry/follow-request-timeout-ms\";\n\n/**\n * Follow a session until it finishes or needs a person.\n *\n * Stopping on `waiting_human` / `awaiting_approval` is the important part: the\n * agent parks there and burns nothing, so a follower that kept waiting would\n * hang forever. The caller turns that into a distinct exit code, which is what\n * lets an orchestrating agent branch on \"it asked me something\".\n */\nexport async function followSession(\n sessionId: string,\n options: { quiet?: boolean; after?: number } = {},\n dependencies: FollowSessionDependencies = defaultFollowSessionDependencies,\n): Promise<SessionDetail> {\n // Resuming a follow starts where the caller left off, so `--after` does not\n // replay (and reprint) the whole transcript.\n let cursor = options.after ?? 0;\n let emptyPolls = 0;\n const retry: FollowRetryState = {\n failures: 0,\n warned: false,\n lastWarnedAt: null,\n outageStartedAt: null,\n };\n const maxOutageMs = resolveFollowOutageBudget();\n\n for (;;) {\n const page = await requestWithFollowRetry({\n retry,\n maxOutageMs,\n dependencies,\n operation: async () =>\n expectShape<\n Omit<ApiOutputs[\"sessions\"][\"events\"], \"status\"> & { status?: string }\n >(\n await dependencies.request(path`/sessions/${sessionId}/events`, {\n query: { after: cursor || undefined, limit: PAGE_SIZE },\n timeoutMs: followRequestTimeoutMs(\n retry,\n maxOutageMs,\n dependencies.now(),\n ),\n }),\n \"GET /sessions/{id}/events\",\n {\n items: is.array,\n hasMore: (value) => typeof value === \"boolean\",\n nextCursor: (value) => value === null || is.number(value),\n // Optional: a deployment older than this binary omits it, and a\n // missing field here would be a non-retryable schema mismatch.\n status: is.optionalString,\n },\n ),\n });\n\n cursor = consumeSessionEvents(page.items, cursor, options.quiet);\n\n // Advance on the SERVER's cursor, not on what we could render. The API\n // paginates raw rows and drops the ones with no transcript representation,\n // so a page can come back empty with hasMore true — following the items\n // alone would re-request the same page forever, without even sleeping.\n if (page.nextCursor !== null) {\n cursor = Math.max(cursor, page.nextCursor);\n }\n\n if (page.hasMore) {\n continue;\n }\n\n emptyPolls = page.items.length === 0 ? emptyPolls + 1 : 0;\n if (\n isFollowStopStatus(page.status) ||\n page.items.length > 0 ||\n emptyPolls >= 3\n ) {\n const session = await requestWithFollowRetry({\n retry,\n maxOutageMs,\n dependencies,\n operation: async () =>\n expectShape<SessionDetail>(\n await dependencies.request(path`/sessions/${sessionId}`, {\n timeoutMs: followRequestTimeoutMs(\n retry,\n maxOutageMs,\n dependencies.now(),\n ),\n }),\n \"GET /sessions/{id}\",\n { status: is.string },\n ),\n });\n emptyPolls = 0;\n if (isFollowStopStatus(session.status)) {\n return session;\n }\n }\n\n await dependencies.pollSleep(POLL_SECONDS);\n }\n}\n","import { out } from \"@/lib/output/out\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\n\nexport function buildSessionDetailRows(session: SessionDetail): string[][] {\n const rows: string[][] = [[\"id\", out.cell(session.id)]];\n if (session.statusReason) {\n rows.push([\"reason\", out.cell(session.statusReason)]);\n }\n if (session.repoFullName) {\n const branch = session.repos.find(\n (repo) => repo.repoFullName === session.repoFullName,\n )?.branch;\n rows.push([\n \"repo\",\n out.cell(session.repoFullName + (branch ? ` @ ${branch}` : \"\")),\n ]);\n }\n rows.push([\"task\", session.taskType]);\n if (session.model) {\n rows.push([\"model\", out.cell(session.model)]);\n }\n if (session.prUrl) {\n rows.push([\n \"pr\",\n out.cell(\n `${session.prUrl}${session.prState ? ` (${session.prState})` : \"\"}`,\n ),\n ]);\n }\n for (const deliverable of session.deliverables) {\n if (deliverable.url && deliverable.url !== session.prUrl) {\n rows.push([out.cell(deliverable.type), out.cell(deliverable.url)]);\n }\n }\n return rows;\n}\n","import { out } from \"@/lib/output/out\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\n\nexport function printPlaybookSteps(\n steps: NonNullable<SessionDetail[\"playbook\"]>[\"steps\"],\n): void {\n if (steps.length === 0) {\n return;\n }\n out.line();\n for (const step of steps) {\n const done = step.todos.filter(\n (todo) => todo.status === \"completed\",\n ).length;\n const marker =\n done === step.todos.length && step.todos.length > 0 ? \"✓\" : \"·\";\n out.line(\n ` ${marker} ${out.cell(step.title)} ${out.paint(`${done}/${step.todos.length}`, \"dim\")}`,\n );\n }\n}\n","import { out } from \"../output/out\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\nimport { buildSessionDetailRows } from \"@/lib/session/build-session-detail-rows\";\nimport { printPlaybookSteps } from \"@/lib/session/print-playbook-steps\";\n\n/** The single-session view shared by `get`, `run` and every control command. */\nexport function printSession(session: SessionDetail): void {\n // Titles, reasons, URLs and step names are agent-authored: sanitise before\n // they reach a terminal (see out.safe).\n out.line(\n `${out.paint(out.cell(session.title), \"bold\")} ${out.status(session.status)}`,\n );\n\n const rows = buildSessionDetailRows(session);\n\n out.table(\n rows.map(([label, value]) => [out.paint(label ?? \"\", \"dim\"), value ?? \"\"]),\n );\n\n printPlaybookSteps(session.playbook?.steps ?? []);\n}\n","import { CliError } from \"../cli/cli-error\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\n\n/**\n * What a followed session means for the caller's exit code.\n *\n * `followSession` returns on two very different conditions — the work is over,\n * or it needs a person — and both `run --follow` and `sessions logs --follow`\n * have to tell them apart the same way. Returns null when the session\n * completed (exit 0), a CliError carrying 3 when a human is needed, and 1 for\n * a real failure. The session rides on the error so `--json` can emit one\n * document holding both the outcome and what it applies to.\n */\nexport function sessionOutcome(session: SessionDetail): CliError | null {\n switch (session.status) {\n case \"completed\":\n return null;\n case \"waiting_human\":\n return new CliError(\n `Waiting on an answer — \\`hepha questions list --session ${session.id}\\``,\n 3,\n {},\n session,\n );\n case \"awaiting_approval\":\n return new CliError(\n \"Waiting on a guardrail approval — `hepha approvals list`\",\n 3,\n {},\n session,\n );\n default:\n return new CliError(\n `Session ended ${session.status}${session.statusReason ? `: ${session.statusReason}` : \".\"}`,\n 1,\n {},\n session,\n );\n }\n}\n","import { out } from \"../output/out\";\nimport { printSession } from \"./print-session\";\nimport { sessionOutcome } from \"./session-outcome\";\nimport type { SessionDetail } from \"./session-detail\";\n\nexport function writeFollowedSessionOutcome(\n session: SessionDetail,\n asJson: boolean,\n): void {\n const outcome = sessionOutcome(session);\n\n if (asJson) {\n if (!outcome) out.json(session);\n } else {\n out.line();\n printSession(session);\n }\n\n if (outcome) throw outcome;\n}\n","import type { CreateInput } from \"@/commands/create/create-input\";\nexport const HARNESSES = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n] as const satisfies readonly NonNullable<CreateInput[\"harnessPin\"]>[];\n","import type { CreateInput } from \"@/commands/create/create-input\";\n/**\n * Validated locally so a typo names itself, instead of travelling to the API\n * and coming back as a bare \"Input validation failed\" that says nothing about\n * which flag was wrong.\n *\n * `satisfies` against the router's own input type is what keeps these lists\n * honest: adding a task type server-side without updating this one is a\n * `types:check` failure, not a CLI that quietly refuses a valid value.\n */\nexport const TASK_TYPES = [\n \"implement\",\n \"new-project\",\n \"question\",\n \"draft\",\n \"orchestrator\",\n] as const satisfies readonly NonNullable<CreateInput[\"taskType\"]>[];\n","import { args } from \"@/lib/args/args\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nimport type { CreateInput } from \"@/commands/create/create-input\";\nimport { HARNESSES } from \"@/commands/harnesses/harnesses-constants\";\nimport { TASK_TYPES } from \"@/commands/task/task-types-constants\";\n\nexport function createRunInput(\n parsed: ParsedArgs,\n prompt: string,\n): CreateInput {\n const taskType = args.choice(parsed, \"task-type\", TASK_TYPES);\n const harness = args.choice(parsed, \"harness\", HARNESSES);\n\n return {\n prompt,\n ...(parsed.flags.title ? { title: parsed.flags.title } : {}),\n ...(taskType ? { taskType } : {}),\n ...(parsed.flags.model ? { modelSelection: parsed.flags.model } : {}),\n ...(harness ? { harnessPin: harness } : {}),\n ...(parsed.flags.repo ? { repoFullName: parsed.flags.repo } : {}),\n ...(parsed.flags.branch ? { branch: parsed.flags.branch } : {}),\n ...(parsed.repeated.skill ? { pinnedSkillIds: parsed.repeated.skill } : {}),\n };\n}\n","import { api } from \"../../lib/api/api\";\nimport { args } from \"../../lib/args/args\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { followSession } from \"../../lib/session/follow-session\";\nimport { out } from \"../../lib/output/out\";\nimport { printSession } from \"../../lib/session/print-session\";\nimport { writeFollowedSessionOutcome } from \"../../lib/session/write-followed-session-outcome\";\nimport { createRunInput } from \"@/commands/command/create-run-input\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Exit code carries the outcome — 0 done, 3 waiting on a human, 1 failed — so\n * a caller can drive the loop without parsing text.\n */\nexport async function runCommand(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {\n flags: [\n \"title\",\n \"task-type\",\n \"model\",\n \"harness\",\n \"repo\",\n \"branch\",\n \"skill\",\n ],\n booleans: [\"follow\"],\n positional: 1,\n });\n\n const prompt = args.required(parsed, 0, \"prompt\");\n const asJson = parsed.booleans.has(\"json\");\n const body = createRunInput(parsed, prompt);\n\n const session = expectShape<ApiOutputs[\"sessions\"][\"create\"]>(\n await api(\"/sessions\", { method: \"POST\", body }),\n \"POST /sessions\",\n { id: is.string, title: is.string, status: is.string },\n );\n\n if (!parsed.booleans.has(\"follow\")) {\n if (asJson) {\n out.json(session);\n return;\n }\n printSession(session);\n out.line();\n out.line(out.paint(` hepha sessions logs ${session.id} --follow`, \"dim\"));\n return;\n }\n\n const quiet = asJson || parsed.booleans.has(\"quiet\");\n\n if (!quiet) {\n out.line(out.paint(`session ${session.id}`, \"dim\"));\n out.line();\n }\n\n const final = await followSession(session.id, { quiet });\n writeFollowedSessionOutcome(final, asJson);\n}\n","import { is } from \"@/lib/is/is\";\n\nexport const ACTIONS = [\n \"list\",\n \"get\",\n \"logs\",\n \"send\",\n \"pause\",\n \"resume\",\n \"kill\",\n \"archive\",\n \"checks\",\n \"pr\",\n \"verify\",\n] as const;\n\nexport const CONTROL_PATHS: Record<string, string> = {\n pause: \"pause\",\n resume: \"resume\",\n kill: \"kill\",\n archive: \"archive\",\n};\n\nexport const STATUS_GROUPS = [\"active\", \"waiting\", \"done\"] as const;\n\nexport const SESSION_FIELDS = {\n id: is.string,\n title: is.string,\n status: is.string,\n taskType: is.string,\n repos: is.array,\n deliverables: is.array,\n};\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport { STATUS_GROUPS } from \"@/commands/sessions/sessions-constants\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nexport async function listSessions(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {\n flags: [\"status\", \"repo\", \"search\", \"page\", \"limit\"],\n booleans: [\"all\"],\n positional: 1,\n });\n\n const result = expectShape<ApiOutputs[\"sessions\"][\"list\"]>(\n await api(\"/sessions\", {\n query: {\n statusGroup: args.choice(parsed, \"status\", STATUS_GROUPS),\n repoFullName: parsed.flags.repo,\n search: parsed.flags.search,\n page: args.integer(parsed, \"page\", { min: 1 }),\n limit: args.integer(parsed, \"limit\", { min: 1, max: 100 }),\n scope: parsed.booleans.has(\"all\") ? \"all\" : undefined,\n },\n }),\n \"GET /sessions\",\n { data: is.array, \"pagination.page\": is.number },\n );\n\n if (parsed.booleans.has(\"json\")) {\n out.json(result);\n return;\n }\n\n if (result.data.length === 0) {\n out.line(\"No sessions.\");\n return;\n }\n\n if (result.pagination.hasNextPage) {\n out.line(\n out.paint(\n `page ${result.pagination.page}/${result.pagination.totalPages} — --page ${result.pagination.page + 1} for more`,\n \"dim\",\n ),\n );\n out.line();\n }\n\n out.table(\n result.data.map((session) => [\n out.cell(session.id),\n out.status(session.status),\n out.cell(session.repoFullName ?? \"—\"),\n out.cell(session.title),\n ]),\n );\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport { path } from \"@/lib/path/path\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function sendSessionMessage(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, { positional: 3 });\n const sessionId = args.required(parsed, 1, \"sessionId\");\n const message = args.required(parsed, 2, \"message\");\n const result = expectShape<ApiOutputs[\"sessions\"][\"sendMessage\"]>(\n await api(path`/sessions/${sessionId}/messages`, {\n method: \"POST\",\n body: { message },\n }),\n \"POST /sessions/{id}/messages\",\n { delivery: is.string },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n result.delivery === \"interrupt\"\n ? \"Delivered to the running agent.\"\n : \"Queued — the agent picks it up at the end of its turn.\",\n );\n}\n","import type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nimport { followSession } from \"@/lib/session/follow-session\";\nimport { writeFollowedSessionOutcome } from \"@/lib/session/write-followed-session-outcome\";\n\nexport async function followSessionLogs(\n parsed: ParsedArgs,\n sessionId: string,\n after: number | undefined,\n asJson: boolean,\n): Promise<void> {\n // JSON mode suppresses the transcript so stdout remains one document.\n const session = await followSession(sessionId, {\n quiet: asJson || parsed.booleans.has(\"quiet\"),\n ...(after !== undefined ? { after } : {}),\n });\n writeFollowedSessionOutcome(session, asJson);\n}\n","import { api } from \"@/lib/api/api\";\nimport { path } from \"@/lib/path/path\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { formatEvent } from \"@/lib/event/format-event\";\nimport { out } from \"@/lib/output/out\";\nimport { followSessionLogs } from \"@/commands/show/follow-session-logs\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nexport async function showLogs(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {\n flags: [\"after\", \"limit\"],\n booleans: [\"follow\"],\n positional: 2,\n });\n\n const sessionId = args.required(parsed, 1, \"sessionId\");\n const asJson = parsed.booleans.has(\"json\");\n const after = args.integer(parsed, \"after\", { min: 0 });\n\n if (parsed.booleans.has(\"follow\")) {\n await followSessionLogs(parsed, sessionId, after, asJson);\n return;\n }\n\n const page = expectShape<ApiOutputs[\"sessions\"][\"events\"]>(\n await api(path`/sessions/${sessionId}/events`, {\n query: {\n after,\n limit: args.integer(parsed, \"limit\", { min: 1, max: 200 }),\n },\n }),\n \"GET /sessions/{id}/events\",\n { items: is.array },\n );\n\n if (asJson) {\n out.json(page);\n return;\n }\n\n for (const event of page.items) {\n const line = formatEvent(event);\n if (line) {\n out.line(line);\n }\n }\n\n // Never let a truncated transcript look complete. Formatted events do not\n // carry their sequence, so the continuation cursor has to be spelled out.\n if (page.hasMore && page.nextCursor !== null) {\n out.line();\n out.line(\n out.paint(\n `more events — hepha sessions logs ${sessionId} --after ${page.nextCursor}`,\n \"dim\",\n ),\n );\n }\n}\n","import { listSessions } from \"@/commands/sessions/list-sessions\";\nimport { sendSessionMessage } from \"@/commands/session/send-session-message\";\nimport { showLogs } from \"@/commands/show/show-logs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * The session actions with their own command. Anything absent here is a\n * per-session operation and goes through `runSessionOperation`, which resolves\n * the session id first.\n */\nexport const sessionActions: Record<\n string,\n (parsed: ParsedArgs, asJson: boolean) => Promise<void>\n> = {\n list: (parsed) => listSessions(parsed),\n logs: (parsed) => showLogs(parsed),\n send: sendSessionMessage,\n};\n","import { expectShape } from \"@/lib/expect/expect-shape\";\nimport { SESSION_FIELDS } from \"@/commands/sessions/sessions-constants\";\nimport type { SessionDetail } from \"@/commands/session/session-detail\";\nexport function detail(payload: unknown, endpoint: string): SessionDetail {\n return expectShape<SessionDetail>(payload, endpoint, SESSION_FIELDS);\n}\n","import { api } from \"@/lib/api/api\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { path } from \"@/lib/path/path\";\nimport { out } from \"@/lib/output/out\";\nimport { printSession } from \"@/lib/session/print-session\";\nimport { detail } from \"@/commands/detail/detail\";\nimport { CONTROL_PATHS } from \"@/commands/sessions/sessions-constants\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function runSessionControlAction(\n parsed: ParsedArgs,\n action: string,\n sessionId: string,\n asJson: boolean,\n): Promise<void> {\n const controlPath = CONTROL_PATHS[action];\n if (controlPath === undefined) {\n throw new CliError(`Unknown session action: ${action}`, 2);\n }\n const session = detail(\n await api(path`/sessions/${sessionId}/${controlPath}`, {\n method: \"POST\",\n body:\n action === \"kill\" && parsed.flags.reason\n ? { reason: parsed.flags.reason }\n : {},\n }),\n `POST /sessions/{id}/${controlPath}`,\n );\n if (asJson) {\n out.json(session);\n return;\n }\n printSession(session);\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { path } from \"@/lib/path/path\";\nimport { out } from \"@/lib/output/out\";\nimport { printSession } from \"@/lib/session/print-session\";\nimport { runSessionControlAction } from \"@/commands/command/run-session-control-action\";\nimport { detail } from \"@/commands/detail/detail\";\nimport { CONTROL_PATHS } from \"@/commands/sessions/sessions-constants\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function runSessionOperation(\n parsed: ParsedArgs,\n action: string,\n asJson: boolean,\n): Promise<void> {\n // Only kill consumes --reason; the other operations must reject it.\n args.expect(parsed, {\n positional: 2,\n ...(action === \"kill\" ? { flags: [\"reason\"] } : {}),\n });\n\n const sessionId = args.required(parsed, 1, \"sessionId\");\n\n if (action === \"get\") {\n const session = detail(\n await api(path`/sessions/${sessionId}`),\n \"GET /sessions/{id}\",\n );\n if (asJson) {\n out.json(session);\n return;\n }\n printSession(session);\n return;\n }\n\n // Avoid inherited keys such as `toString` becoming control paths.\n if (Object.hasOwn(CONTROL_PATHS, action)) {\n await runSessionControlAction(parsed, action, sessionId, asJson);\n return;\n }\n\n if (action === \"checks\") {\n out.json(\n await api<ApiOutputs[\"sessions\"][\"runChecks\"]>(\n path`/sessions/${sessionId}/checks`,\n { method: \"POST\", body: {} },\n ),\n );\n return;\n }\n\n if (action === \"pr\") {\n out.json(\n await api<ApiOutputs[\"sessions\"][\"prChecks\"]>(\n path`/sessions/${sessionId}/pr-checks`,\n ),\n );\n return;\n }\n\n out.json(\n await api<ApiOutputs[\"sessions\"][\"verification\"]>(\n path`/sessions/${sessionId}/verification`,\n ),\n );\n}\n","import { args } from \"../../lib/args/args\";\nimport { ACTIONS } from \"@/commands/sessions/sessions-constants\";\nimport { sessionActions } from \"@/commands/sessions/session-actions\";\nimport { runSessionOperation } from \"@/commands/command/run-session-operation\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function sessionsCommand(parsed: ParsedArgs): Promise<void> {\n // The action is validated FIRST, so `hepha sessions frobnicate <id>` names\n // the real problem instead of asking for an argument it would never use.\n const action = args.action(parsed, \"sessions\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n const dedicated = sessionActions[action];\n if (dedicated) {\n return await dedicated(parsed, asJson);\n }\n await runSessionOperation(parsed, action, asJson);\n}\n","import { api } from \"../../lib/api/api\";\nimport { args } from \"../../lib/args/args\";\nimport { config } from \"../../lib/shared/config\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function whoamiCommand(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {});\n\n const identity = expectShape<ApiOutputs[\"me\"][\"get\"]>(\n await api(\"/me\"),\n \"GET /me\",\n {\n \"user.name\": is.string,\n \"user.email\": is.string,\n \"auth.method\": is.string,\n \"auth.scopes\": is.array,\n },\n );\n\n if (parsed.booleans.has(\"json\")) {\n out.json(identity);\n return;\n }\n\n out.table([\n [\n out.paint(\"user\", \"dim\"),\n out.cell(`${identity.user.name} <${identity.user.email}>`),\n ],\n [out.paint(\"role\", \"dim\"), out.cell(identity.user.role ?? \"member\")],\n [\n out.paint(\"auth\", \"dim\"),\n out.cell(\n identity.auth.method === \"api_key\"\n ? `api key${identity.auth.keyName ? ` \"${identity.auth.keyName}\"` : \"\"}`\n : \"session\",\n ),\n ],\n [out.paint(\"scopes\", \"dim\"), identity.auth.scopes.join(\" \")],\n [out.paint(\"url\", \"dim\"), config.load().baseUrl],\n ]);\n}\n","export const CATALOG_TOPICS = new Set([\n \"repos\",\n \"branches\",\n \"models\",\n \"skills\",\n]);\n","import { approvalsCommand } from \"@/commands/command/approvals-command\";\nimport { catalogCommand } from \"@/commands/command/catalog-command\";\nimport { helpCommand } from \"@/commands/command/help-command\";\nimport { keysCommand } from \"@/commands/command/keys-command\";\nimport { loginCommand } from \"@/commands/command/login-command\";\nimport { logoutCommand } from \"@/commands/command/logout-command\";\nimport { questionsCommand } from \"@/commands/command/questions-command\";\nimport { runCommand } from \"@/commands/command/run-command\";\nimport { sessionsCommand } from \"@/commands/command/sessions-command\";\nimport { whoamiCommand } from \"@/commands/command/whoami-command\";\nimport { args } from \"@/lib/args/args\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { CATALOG_TOPICS } from \"@/catalog-topics-constants\";\nexport async function dispatch(command: string, argv: string[]): Promise<void> {\n const parsed = args.parse(argv);\n\n if (parsed.booleans.has(\"help\")) {\n helpCommand();\n return;\n }\n\n if (CATALOG_TOPICS.has(command)) {\n return await catalogCommand(command, parsed);\n }\n\n switch (command) {\n case \"login\":\n return await loginCommand(parsed);\n case \"logout\":\n return logoutCommand(parsed);\n case \"whoami\":\n return await whoamiCommand(parsed);\n case \"keys\":\n return await keysCommand(parsed);\n case \"run\":\n return await runCommand(parsed);\n case \"sessions\":\n return await sessionsCommand(parsed);\n case \"questions\":\n return await questionsCommand(parsed);\n case \"approvals\":\n return await approvalsCommand(parsed);\n default:\n helpCommand();\n throw new CliError(`Unknown command \"${command}\".`, 2);\n }\n}\n","import { helpCommand } from \"@/commands/command/help-command\";\nimport { args } from \"@/lib/args/args\";\nimport { out } from \"@/lib/output/out\";\nimport { VERSION } from \"@/lib/version/version-constants\";\nimport { wantsJson } from \"@/lib/wants/wants-json\";\nimport { dispatch } from \"@/dispatch\";\nexport async function main(): Promise<void> {\n const argv = process.argv.slice(2);\n out.setJson(wantsJson(argv));\n\n const [command, ...rest] = argv;\n\n if (!command || command === \"help\" || command === \"--help\") {\n helpCommand();\n return;\n }\n\n // Answered early, but NOT before the arguments are checked: returning ahead\n // of the parser would exempt this command from the strictness every other one\n // applies.\n if (command === \"--version\" || command === \"-v\" || command === \"version\") {\n args.expect(args.parse(rest), {});\n if (out.isJson()) {\n out.json({ version: VERSION });\n } else {\n out.line(VERSION);\n }\n return;\n }\n\n await dispatch(command, rest);\n}\n","import { CliError } from \"./lib/cli/cli-error\";\nimport { out } from \"./lib/output/out\";\nimport { main } from \"@/main\";\n\nexport async function cliEntry() {\n try {\n await main();\n } catch (error: unknown) {\n const failure =\n error instanceof CliError\n ? error\n : new CliError(error instanceof Error ? error.message : String(error));\n\n out.failure(failure);\n process.exit(failure.exitCode);\n }\n}\n\nvoid cliEntry();\n"],"mappings":"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","names":["readFileSync","dirname","join","detail","result","path","ACTIONS","ACTIONS","result","ACTIONS","ACTIONS","result","sleep","sleep","ACTIONS","ACTIONS"]}
|
|
1
|
+
{"version":3,"sources":["../../../packages/core/src/tagged-error.ts","../src/lib/shared/errors-constants.ts","../src/lib/cli/cli-error.ts","../src/lib/shared/output-constants.ts","../src/lib/ansi/strip-ansi.ts","../src/lib/supports/supports-color.ts","../src/lib/cli/cli-output.ts","../src/lib/output/out.ts","../src/lib/shared/config.ts","../src/lib/shared/config-constants.ts","../src/lib/path/config-path-constants.ts","../src/lib/file/read-file-as-object.ts","../src/lib/string/config-read-string.ts","../src/lib/user/read-user.ts","../src/lib/http/is-http-url.ts","../src/lib/http/read-http-url.ts","../src/lib/same/is-same-origin.ts","../src/lib/version/read-version.ts","../src/lib/version/version-constants.ts","../src/commands/help/help-constants.ts","../src/commands/command/help-command.ts","../src/lib/args/args-constants.ts","../src/lib/boolean/boolean-flags-constants.ts","../src/lib/args/parse-flag.ts","../src/lib/args/args-parser.ts","../src/lib/args/args.ts","../src/lib/wants/wants-json.ts","../src/lib/api/api-constants.ts","../src/lib/timeout/resolve-timeout.ts","../src/lib/auth/auth-headers.ts","../src/lib/retry/retry-after-seconds.ts","../src/lib/response/fetch-response.ts","../src/lib/api/add-query-parameters.ts","../src/lib/excerpt/excerpt.ts","../src/lib/api/parse-response-payload.ts","../src/lib/issues/read-issues.ts","../src/lib/string/read-string.ts","../src/lib/message/message-from.ts","../src/lib/api/throw-response-error.ts","../src/lib/api/api.ts","../src/lib/path/path.ts","../src/lib/read/read.ts","../src/lib/expect/expect-shape.ts","../src/lib/is/is.ts","../src/commands/approvals/approvals-constants.ts","../src/commands/approvals/list-approvals.ts","../src/commands/command/approvals-command.ts","../src/commands/catalog/list-catalog-branches.ts","../src/commands/catalog/list-catalog-models.ts","../src/commands/catalog/read-catalog-list.ts","../src/commands/catalog/list-catalog-repos.ts","../src/commands/catalog/list-catalog-skills.ts","../src/commands/catalog/catalog-topics.ts","../src/commands/command/catalog-command.ts","../src/commands/keys/keys-constants.ts","../src/commands/key/create-key.ts","../src/commands/command/keys-command.ts","../src/commands/command/login-command.ts","../src/lib/token/device-token-error.ts","../src/lib/retry/next-poll-delay.ts","../src/lib/browser/open-browser.ts","../src/commands/login/login-constants.ts","../../../packages/database/shared/constants.ts","../src/commands/client/client-id-constants.ts","../src/commands/sleep/sleep.ts","../src/commands/complete/complete-login.ts","../src/commands/login/resolve-login-base-url.ts","../src/commands/command/logout-command.ts","../src/commands/answers/collect-answers-constants.ts","../src/commands/answer/validate-free-text.ts","../src/commands/answer/validate-selected-option-ids.ts","../src/commands/answer/validate-answer.ts","../src/commands/answers/parse-answer-entry.ts","../src/commands/answers/parse-answers-flag.ts","../src/commands/answers/collect-answers.ts","../src/commands/questions/questions-constants.ts","../src/commands/questions/list-questions.ts","../src/commands/batch/print-batch-question.ts","../src/commands/batch/print-batch.ts","../src/commands/command/questions-command.ts","../src/lib/follow/follow-constants.ts","../src/lib/truncate/truncate.ts","../src/lib/event/format-event.ts","../src/lib/session/consume-session-events.ts","../src/lib/sleep/sleep.ts","../src/lib/sleep/sleep-constants.ts","../src/lib/sleep/timer-delay-ms.ts","../src/lib/sleep/interruptible-sleep.ts","../src/lib/session/default-follow-session-dependencies.ts","../src/lib/session/retry/follow-outage-message.ts","../src/lib/session/retry/follow-retry-constants.ts","../src/lib/session/retry/follow-retry-delay.ts","../src/lib/session/retry/remaining-outage-seconds.ts","../src/lib/session/retry/retryable-follow-error.ts","../src/lib/session/retry/should-report-follow-outage.ts","../src/lib/session/retry/wait-for-follow-retry.ts","../src/lib/session/retry/request-with-follow-retry.ts","../src/lib/blocked/blocked-constants.ts","../src/lib/terminal/terminal-constants.ts","../src/lib/session/is-follow-stop-status.ts","../src/lib/session/retry/resolve-follow-outage-budget.ts","../src/lib/session/retry/follow-request-timeout-ms.ts","../src/lib/session/follow-session.ts","../src/lib/session/build-session-detail-rows.ts","../src/lib/session/print-playbook-steps.ts","../src/lib/session/print-session.ts","../src/lib/session/session-outcome.ts","../src/lib/session/write-followed-session-outcome.ts","../src/commands/harnesses/harnesses-constants.ts","../src/commands/task/task-types-constants.ts","../src/commands/command/create-run-input.ts","../src/commands/command/run-command.ts","../src/commands/sessions/sessions-constants.ts","../src/commands/sessions/list-sessions.ts","../src/commands/session/send-session-message.ts","../src/commands/show/follow-session-logs.ts","../src/commands/show/show-logs.ts","../src/commands/sessions/session-actions.ts","../src/commands/detail/detail.ts","../src/commands/command/run-session-control-action.ts","../src/commands/command/run-session-operation.ts","../src/commands/command/sessions-command.ts","../src/commands/command/whoami-command.ts","../src/catalog-topics-constants.ts","../src/dispatch.ts","../src/main.ts","../src/cli-entry.ts"],"sourcesContent":["/**\n * Base for error kinds recognised across bundle boundaries. `instanceof` is\n * unreliable there — server and tasks bundle their own copy of a shared class —\n * so classification reads the `_tag` literal instead.\n */\nexport abstract class TaggedError<Tag extends string = string> extends Error {\n readonly _tag: Tag;\n\n constructor(tag: Tag, message: string, options?: ErrorOptions) {\n super(message, options);\n this._tag = tag;\n this.name = tag;\n }\n\n static is(value: unknown): value is TaggedError {\n return (\n value instanceof Error &&\n \"_tag\" in value &&\n typeof value._tag === \"string\"\n );\n }\n\n static hasTag<Expected extends string>(\n value: unknown,\n tag: Expected,\n ): value is TaggedError<Expected> {\n return TaggedError.is(value) && value._tag === tag;\n }\n}\n","export const CLI_ERROR_CODES = {\n BAD_USAGE: \"BAD_USAGE\",\n /** The session needs a person — the exit-3 family. */\n NEEDS_HUMAN: \"NEEDS_HUMAN\",\n NOT_AUTHENTICATED: \"NOT_AUTHENTICATED\",\n NETWORK: \"NETWORK\",\n TIMEOUT: \"TIMEOUT\",\n /** Ctrl-C: a cancellation, not a failure of ours. */\n INTERRUPTED: \"INTERRUPTED\",\n /** A 2xx whose shape this CLI version does not understand. */\n API_SCHEMA_MISMATCH: \"API_SCHEMA_MISMATCH\",\n /** Not JSON at all — wrong host, proxy, error page. */\n NON_JSON_RESPONSE: \"NON_JSON_RESPONSE\",\n ERROR: \"ERROR\",\n} as const;\n","import { TaggedError } from \"@repo/core/tagged-error\";\n\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport type { CliErrorDetails } from \"@/lib/cli/cli-error-details\";\n\n/**\n * A failure the user should read as a message, not a stack trace.\n *\n * `exitCode` is part of the contract for scripts and agents: 1 for a plain\n * failure, 2 for bad usage, 3 for \"the session needs a human\" — so a caller\n * can branch on it without parsing text. `details` carries the same failure in\n * machine form; under `--json` it is what gets printed (see cli-output.ts).\n */\nexport class CliError extends TaggedError<\"CliError\"> {\n readonly exitCode: number;\n readonly details: CliErrorDetails;\n /**\n * A followed session parking on a question is a non-zero outcome AND a result\n * worth reading. Carried here so stdout stays ONE JSON document.\n */\n readonly result?: unknown;\n\n constructor(\n message: string,\n exitCode = 1,\n details: CliErrorDetails = {},\n result?: unknown,\n ) {\n super(\"CliError\", message);\n this.exitCode = exitCode;\n this.details = details;\n if (result !== undefined) {\n this.result = result;\n }\n }\n\n /** The code to report, defaulting to whatever the exit code implies. */\n get code(): string {\n if (this.details.code) {\n return this.details.code;\n }\n if (this.exitCode === 2) {\n return CLI_ERROR_CODES.BAD_USAGE;\n }\n if (this.exitCode === 3) {\n return CLI_ERROR_CODES.NEEDS_HUMAN;\n }\n return CLI_ERROR_CODES.ERROR;\n }\n}\n","export const COLORS: Record<string, string> = {\n reset: \"\\u001b[0m\",\n dim: \"\\u001b[2m\",\n bold: \"\\u001b[1m\",\n red: \"\\u001b[31m\",\n green: \"\\u001b[32m\",\n yellow: \"\\u001b[33m\",\n blue: \"\\u001b[34m\",\n magenta: \"\\u001b[35m\",\n};\n\nexport const STATUS_COLORS: Record<string, string> = {\n running: \"blue\",\n provisioning: \"blue\",\n queued: \"dim\",\n created: \"dim\",\n delivering: \"blue\",\n verifying: \"blue\",\n waiting_human: \"yellow\",\n waiting_external: \"blue\",\n awaiting_approval: \"yellow\",\n completed: \"green\",\n failed: \"red\",\n killed: \"red\",\n abstained: \"yellow\",\n};\n","/** Width is measured on the visible text, so colour never breaks alignment. */\nexport function stripAnsi(text: string): string {\n return text.replace(/\\u001b\\[\\d+m/g, \"\");\n}\n","export function supportsColor(jsonMode: boolean): boolean {\n return (\n process.stdout.isTTY === true &&\n process.env.NO_COLOR === undefined &&\n !jsonMode\n );\n}\n","import type { CliError } from \"./cli-error\";\nimport { COLORS, STATUS_COLORS } from \"@/lib/shared/output-constants\";\nimport { stripAnsi } from \"@/lib/ansi/strip-ansi\";\nimport { supportsColor } from \"@/lib/supports/supports-color\";\n\n/**\n * Two audiences, one command set: humans read the aligned text, agents pass\n * `--json` and parse stdout. Everything a command prints goes through here, so\n * `--json` is never partially honoured.\n */\nexport class CliOutput {\n private jsonMode = false;\n\n /** Declared once per run, before anything can fail. */\n setJson(enabled: boolean): void {\n this.jsonMode = enabled;\n }\n\n isJson(): boolean {\n return this.jsonMode;\n }\n\n json(value: unknown): void {\n process.stdout.write(`${JSON.stringify(value, null, 2)}\\n`);\n }\n\n line(text = \"\"): void {\n process.stdout.write(`${text}\\n`);\n }\n\n error(text: string): void {\n // Sanitised like everything else: a failure message often carries a\n // session's statusReason, which is agent- or tool-authored text — and an\n // error line is the last thing that should be able to repaint the screen.\n process.stderr.write(`${this.paint(`error: ${this.safe(text)}`, \"red\")}\\n`);\n }\n\n // Progress a long command owes the user; stderr keeps `--json` stdout whole.\n warn(text: string): void {\n process.stderr.write(`${this.paint(this.safe(text), \"yellow\")}\\n`);\n }\n\n /**\n * The one place a failure is reported. Under `--json` stdout must be\n * parseable, and it was not: failures went to stderr as prose. Success keeps\n * its bare shape, so nothing that already parses stdout has to change.\n */\n failure(error: CliError): void {\n if (!this.jsonMode) {\n this.error(error.message);\n return;\n }\n\n this.json({\n ok: false,\n error: {\n ...(error.details.status === undefined\n ? {}\n : { status: error.details.status }),\n code: error.code,\n message: this.safe(error.message),\n ...(error.details.issues ? { issues: error.details.issues } : {}),\n ...(error.details.retryAfterSeconds === undefined\n ? {}\n : { retryAfterSeconds: error.details.retryAfterSeconds }),\n },\n // Inside the envelope, so stdout stays one parseable document.\n ...(error.result === undefined ? {} : { result: error.result }),\n });\n }\n\n paint(text: string, color: string): string {\n if (!supportsColor(this.jsonMode)) {\n return text;\n }\n return `${COLORS[color] ?? \"\"}${text}${COLORS.reset}`;\n }\n\n /**\n * Neutralise terminal control sequences in text the platform gives us.\n *\n * Transcript content, PR titles and question bodies carry model output, tool\n * output and repository contents — none of it trusted. Printed raw, an ESC\n * sequence could repaint or erase what the user already read, or emit an OSC\n * 8 hyperlink pointing somewhere else entirely. Newlines and tabs survive;\n * every other C0/C1 control does not. (`--json` is unaffected: JSON.stringify\n * already escapes control characters.)\n */\n safe(text: string): string {\n return text.replace(/[\\u0000-\\u0008\\u000b-\\u001f\\u007f-\\u009f]/g, \"\");\n }\n\n /** `safe`, flattened to one line — anything going into a table cell. */\n cell(text: string): string {\n return this.safe(text).replace(/\\s+/g, \" \").trim();\n }\n\n status(status: string): string {\n return this.paint(status, STATUS_COLORS[status] ?? \"reset\");\n }\n\n /** Left-aligned two-column block — the shape used by every list command. */\n table(rows: string[][]): void {\n if (rows.length === 0) {\n return;\n }\n const firstRow = rows[0];\n if (firstRow === undefined) {\n return;\n }\n const widths = firstRow.map((_, column) =>\n Math.max(...rows.map((row) => stripAnsi(row[column] ?? \"\").length)),\n );\n for (const row of rows) {\n const line = row\n .map((cell, column) => {\n const width = widths[column];\n if (width === undefined) {\n return cell;\n }\n const padding = width - stripAnsi(cell).length;\n return column === row.length - 1 ? cell : cell + \" \".repeat(padding);\n })\n .join(\" \");\n this.line(line.trimEnd());\n }\n }\n}\n","import { CliOutput } from \"@/lib/cli/cli-output\";\n\nexport const out = new CliOutput();\n","import { chmodSync, mkdirSync, rmSync, writeFileSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\n\nimport { CliError } from \"../cli/cli-error\";\nimport { DEFAULT_BASE_URL } from \"@/lib/shared/config-constants\";\nimport type { CliConfig } from \"@/lib/cli/cli-config\";\nimport { CONFIG_PATH } from \"@/lib/path/config-path-constants\";\nimport { readFileAsObject } from \"@/lib/file/read-file-as-object\";\nimport { configReadString } from \"@/lib/string/config-read-string\";\nimport { readUser } from \"@/lib/user/read-user\";\nimport { readHttpUrl } from \"@/lib/http/read-http-url\";\nimport { isSameOrigin } from \"@/lib/same/is-same-origin\";\n\n/**\n * `~/.hepha/config.json` — where a device-flow session lives between runs.\n *\n * Written 0600, because it holds a token that acts as the human. Agents are\n * expected to use HEPHA_API_KEY instead and never touch this file.\n */\nexport const config = {\n path: CONFIG_PATH,\n\n load(): CliConfig {\n const stored = readFileAsObject();\n const storedBaseUrl = readHttpUrl(stored.baseUrl);\n\n // A malformed HEPHA_URL is refused rather than ignored. Falling back would\n // run the command against production — with the production token, since\n // the origin would then match — which is the exact accident the\n // origin-binding below exists to prevent. A malformed value in the config\n // FILE still falls back: the user did not ask for it this run, and\n // bricking every command over a stale file helps nobody.\n const override = configReadString(process.env.HEPHA_URL);\n if (override && !readHttpUrl(override)) {\n throw new CliError(\n `HEPHA_URL is not a valid http(s) URL: \"${override}\".`,\n 2,\n );\n }\n\n const baseUrl = readHttpUrl(override) ?? storedBaseUrl ?? DEFAULT_BASE_URL;\n\n // The stored token is bound to the deployment it was issued by. Pointing\n // HEPHA_URL at staging or somebody else's instance must not send a human\n // bearer token for production to that origin — it would not authenticate\n // there, and it would hand the credential to whoever runs it.\n const token =\n storedBaseUrl && isSameOrigin(storedBaseUrl, baseUrl)\n ? configReadString(stored.token)\n : undefined;\n const user = token ? readUser(stored.user) : undefined;\n\n return {\n baseUrl,\n ...(token ? { token } : {}),\n ...(user ? { user } : {}),\n };\n },\n\n save(next: CliConfig): void {\n mkdirSync(dirname(CONFIG_PATH), { recursive: true, mode: 0o700 });\n writeFileSync(CONFIG_PATH, `${JSON.stringify(next, null, 2)}\\n`, {\n mode: 0o600,\n });\n chmodSync(CONFIG_PATH, 0o600);\n },\n\n clear(): void {\n rmSync(CONFIG_PATH, { force: true });\n },\n};\n","export const DEFAULT_BASE_URL = \"https://hephaistos.impulselab.ai\";\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nexport const CONFIG_PATH = join(homedir(), \".hepha\", \"config.json\");\n","import { readFileSync } from \"node:fs\";\nimport { CONFIG_PATH } from \"@/lib/path/config-path-constants\";\nexport function readFileAsObject(): Record<string, unknown> {\n try {\n const parsed: unknown = JSON.parse(readFileSync(CONFIG_PATH, \"utf8\"));\n // Valid JSON is not necessarily an object: a file holding `null` or a\n // bare string parses fine and then throws on the first property read,\n // taking down every command. Fall back to defaults instead.\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n return parsed as Record<string, unknown>;\n } catch {\n return {};\n }\n}\n","/** A hand-edited file can hold anything; only usable strings get through. */\nexport function configReadString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim() ? value.trim() : undefined;\n}\n","import type { CliConfig } from \"@/lib/cli/cli-config\";\nimport { configReadString } from \"@/lib/string/config-read-string\";\nexport function readUser(value: unknown): CliConfig[\"user\"] {\n if (!value || typeof value !== \"object\") {\n return undefined;\n }\n const candidate = value as Record<string, unknown>;\n const user = {\n id: configReadString(candidate.id),\n name: configReadString(candidate.name),\n email: configReadString(candidate.email),\n };\n\n return user.id && user.name && user.email\n ? { id: user.id, name: user.name, email: user.email }\n : undefined;\n}\n","export function isHttpUrl(value: string): boolean {\n try {\n const parsed = new URL(value);\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n } catch {\n return false;\n }\n}\n","import { isHttpUrl } from \"@/lib/http/is-http-url\";\nimport { configReadString } from \"@/lib/string/config-read-string\";\n/** A usable base URL, or nothing — \"not a url\" would otherwise reach\n * `new URL()` in api.ts and break every command. */\nexport function readHttpUrl(value: unknown): string | undefined {\n const raw = configReadString(value);\n return raw && isHttpUrl(raw) ? raw : undefined;\n}\n","/** Same deployment? Compared on origin, so a trailing slash does not matter. */\nexport function isSameOrigin(a: string, b: string): boolean {\n try {\n return new URL(a).origin === new URL(b).origin;\n } catch {\n return false;\n }\n}\n","import { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n/**\n * Read at runtime, not baked in: CI stamps the real version onto package.json\n * when it publishes. Walking up covers both `dist/index.js` (installed) and\n * `src/lib/version.ts` (`pnpm dev`).\n */\nexport function readVersion(): string {\n let directory = dirname(fileURLToPath(import.meta.url));\n\n for (let depth = 0; depth < 5; depth += 1) {\n try {\n const manifest: unknown = JSON.parse(\n readFileSync(join(directory, \"package.json\"), \"utf8\"),\n );\n const version = (manifest as { version?: unknown }).version;\n if (typeof version === \"string\" && version.length > 0) {\n return version;\n }\n } catch {\n // Keep walking: not every ancestor holds a manifest.\n }\n const parent = dirname(directory);\n if (parent === directory) {\n break;\n }\n directory = parent;\n }\n\n return \"unknown\";\n}\n","import { readVersion } from \"@/lib/version/read-version\";\n\nexport const VERSION = readVersion();\n","export const HELP = `hepha — orchestrate Hephaistos sessions from a terminal or an agent.\n\nUSAGE\n hepha <command> [args] [--flags]\n\nTHE LOOP\n hepha run \"<prompt>\" --repo owner/repo --follow\n Start a session and follow it until it finishes or asks you something.\n Exit 0 completed · 3 waiting on a human · 1 failed.\n [--title \"…\"] [--task-type implement|new-project|question|draft|orchestrator]\n [--model <slug>] [--harness claude-code|codex] [--branch <name>]\n [--skill <id>]…\n hepha questions list [--session <id>]\n hepha questions show <batchId>\n hepha questions answer <batchId> --option <questionId>=1,2 --text <questionId>=\"…\"\n [--answers '<json array>']\n hepha questions cancel <batchId>\n hepha approvals list | show <id> | approve <id> | reject <id> --mode rework --feedback \"…\"\n\nSESSIONS\n hepha sessions list [--status active|waiting|done] [--repo owner/repo]\n [--search \"…\"] [--page N] [--limit N] [--all]\n hepha sessions get <id>\n hepha sessions logs <id> [--after <sequence>] [--limit N] [--follow]\n hepha sessions send <id> \"<message>\"\n hepha sessions pause|resume|archive <id>\n hepha sessions kill <id> [--reason \"…\"]\n hepha sessions checks|pr|verify <id>\n\nCATALOG\n hepha repos\n hepha branches <owner/repo>\n hepha models\n hepha skills\n\nAUTH\n hepha login [--url https://…] Device authorization: approve it in a browser.\n hepha logout\n hepha whoami\n hepha keys list\n hepha keys create <name> [--scope sessions:read]… [--expires-in-days 90]\n hepha keys revoke <keyId>\n\nENVIRONMENT\n HEPHA_API_KEY Act as an agent. Takes precedence over a stored login, so\n the human-only commands (approvals approve/reject, keys)\n answer 403 while it is set — unset it to act as yourself.\n HEPHA_TOKEN A device-flow session token, instead of ~/.hepha/config.json.\n HEPHA_URL Platform base URL.\n HEPHA_TIMEOUT_MS Per-request timeout in milliseconds (default 30000).\n HEPHA_FOLLOW_MAX_OUTAGE_SECONDS\n Give up this long after --follow's first failure, with that\n failure as the exit code. Unset, it waits for the platform\n to come back.\n\nGLOBAL FLAGS\n --json Machine-readable output on stdout. Every command that\n returns data honours it; login is interactive and does not.\n Failures print {\"ok\":false,\"error\":{…}} and keep their exit code.\n --quiet Suppress the streamed transcript while following a session.\n --version Print the version and exit.\n --help Print this.\n\nUnknown flags and surplus arguments are refused: for an agent, a typo must\nfail rather than run with default options.\n\n`;\n","import { config } from \"../../lib/shared/config\";\nimport { out } from \"../../lib/output/out\";\nimport { VERSION } from \"../../lib/version/version-constants\";\nimport { HELP } from \"@/commands/help/help-constants\";\n\nexport function helpCommand(): void {\n // Resolved, not a placeholder: the reader can click straight through to the\n // Scalar reference for the platform this CLI is actually pointed at.\n const baseUrl = config.load().baseUrl.replace(/\\/$/, \"\");\n out.line(`${HELP}hepha ${VERSION} · full reference: ${baseUrl}/api/v1/docs`);\n}\n","export const GLOBAL_BOOLEANS = [\"json\", \"help\", \"quiet\"] as const;\n","import { GLOBAL_BOOLEANS } from \"@/lib/args/args-constants\";\nexport const BOOLEAN_FLAGS = new Set<string>([\n ...GLOBAL_BOOLEANS,\n \"follow\",\n \"all\",\n \"version\",\n]);\n","import { BOOLEAN_FLAGS } from \"@/lib/boolean/boolean-flags-constants\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport function parseFlag(\n argv: string[],\n index: number,\n parsed: ParsedArgs,\n): number {\n const token = argv[index];\n if (token === undefined) {\n return index;\n }\n\n const withoutDashes = token.slice(2);\n const equalsAt = withoutDashes.indexOf(\"=\");\n let name: string;\n let value: string | undefined;\n\n if (equalsAt >= 0) {\n name = withoutDashes.slice(0, equalsAt);\n value = withoutDashes.slice(equalsAt + 1);\n // `--json=false` must not become a truthy boolean flag.\n if (BOOLEAN_FLAGS.has(name)) {\n throw new CliError(\n `--${name} is a boolean flag: pass --${name} to enable it, or omit it. \"--${name}=${value}\" is not a value.`,\n 2,\n );\n }\n } else {\n name = withoutDashes;\n const next = argv[index + 1];\n if (\n !BOOLEAN_FLAGS.has(name) &&\n next !== undefined &&\n !next.startsWith(\"--\")\n ) {\n value = next;\n index += 1;\n }\n }\n\n // Empty value flags are typos; accepting `--url=` can select another target.\n if (value === undefined || value.trim() === \"\") {\n if (!BOOLEAN_FLAGS.has(name)) {\n throw new CliError(`--${name} expects a value.`, 2);\n }\n parsed.booleans.add(name);\n return index;\n }\n\n parsed.flags[name] = value;\n (parsed.repeated[name] ??= []).push(value);\n return index;\n}\n","import { CliError } from \"../cli/cli-error\";\nimport { GLOBAL_BOOLEANS } from \"@/lib/args/args-constants\";\nimport type { ArgsSpec } from \"@/lib/args/args-spec\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nimport { parseFlag } from \"@/lib/args/parse-flag\";\n\n/**\n * A deliberately small parser: no dependency, and the grammar stays something an\n * agent can generate blind — `hepha <group> <command> [args] [--flags]`. Strict\n * on purpose: `hepha keys create x --scpoe admin` used to mint a key with the\n * DEFAULT scopes and exit 0.\n */\nexport class ArgsParser {\n parse(argv: string[]): ParsedArgs {\n const parsed: ParsedArgs = {\n positional: [],\n flags: {},\n repeated: {},\n booleans: new Set(),\n };\n\n let flagsEnded = false;\n\n for (let index = 0; index < argv.length; index += 1) {\n const token = argv[index];\n if (token === undefined) {\n break;\n }\n\n // `--` ends option parsing: a prompt or a steering message is allowed to\n // start with dashes, and without this there is no way to send one.\n if (!flagsEnded && token === \"--\") {\n flagsEnded = true;\n continue;\n }\n\n if (flagsEnded || !token.startsWith(\"--\")) {\n parsed.positional.push(token);\n continue;\n }\n\n index = parseFlag(argv, index, parsed);\n }\n\n return parsed;\n }\n\n /**\n * Refuse anything this action does not understand. Called once the action is\n * known, because `sessions list` and `sessions logs` accept different flags.\n */\n expect(parsed: ParsedArgs, spec: ArgsSpec): void {\n const allowed = new Set<string>([\n ...GLOBAL_BOOLEANS,\n ...(spec.flags ?? []),\n ...(spec.booleans ?? []),\n ]);\n\n for (const name of [...Object.keys(parsed.flags), ...parsed.booleans]) {\n if (!allowed.has(name)) {\n throw new CliError(`Unknown flag --${name}.`, 2);\n }\n }\n\n const max = spec.positional ?? 0;\n if (parsed.positional.length > max) {\n const surplus = parsed.positional\n .slice(max)\n .map((value) => `\"${value}\"`)\n .join(\", \");\n throw new CliError(\n `Unexpected argument${parsed.positional.length - max > 1 ? \"s\" : \"\"} ${surplus}.`,\n 2,\n );\n }\n }\n\n /** The action name, validated against what the group actually implements. */\n action(\n parsed: ParsedArgs,\n group: string,\n allowed: readonly string[],\n fallback: string,\n ): string {\n const action = parsed.positional[0] ?? fallback;\n // Checked BEFORE the action's own arguments: `hepha approvals frobnicate`\n // used to ask for a <guardrailRequestId> it was never going to use.\n if (!allowed.includes(action)) {\n throw new CliError(\n `Unknown ${group} command \"${action}\". Expected one of: ${allowed.join(\", \")}.`,\n 2,\n );\n }\n return action;\n }\n\n required(parsed: ParsedArgs, index: number, name: string): string {\n const value = parsed.positional[index];\n if (!value) {\n throw new CliError(`Missing <${name}>.`, 2);\n }\n return value;\n }\n\n /**\n * A whole number inside a range, refused locally: `--page -1` used to come\n * back from the API as a bare \"Input validation failed\".\n */\n integer(\n parsed: ParsedArgs,\n name: string,\n bounds: { min?: number; max?: number } = {},\n ): number | undefined {\n const raw = parsed.flags[name];\n if (raw === undefined) {\n return undefined;\n }\n const trimmed = raw.trim();\n const value = Number(trimmed);\n // Number(\"\") is 0, so an empty `--limit=` would quietly mean zero.\n if (trimmed === \"\" || !Number.isFinite(value)) {\n throw new CliError(`--${name} expects a number, got \"${raw}\".`, 2);\n }\n if (!Number.isInteger(value)) {\n throw new CliError(`--${name} expects a whole number, got \"${raw}\".`, 2);\n }\n if (bounds.min !== undefined && value < bounds.min) {\n throw new CliError(`--${name} must be at least ${bounds.min}.`, 2);\n }\n if (bounds.max !== undefined && value > bounds.max) {\n throw new CliError(`--${name} must be at most ${bounds.max}.`, 2);\n }\n return value;\n }\n\n /** One of a fixed set, named in the error so the fix is obvious. */\n choice<T extends string>(\n parsed: ParsedArgs,\n name: string,\n allowed: readonly T[],\n ): T | undefined {\n const raw = parsed.flags[name];\n if (raw === undefined) {\n return undefined;\n }\n if (!(allowed as readonly string[]).includes(raw)) {\n throw new CliError(\n `--${name} expects one of: ${allowed.join(\", \")}. Got \"${raw}\".`,\n 2,\n );\n }\n return raw as T;\n }\n}\n","import { ArgsParser } from \"@/lib/args/args-parser\";\n\nexport const args = new ArgsParser();\n","/**\n * Was machine output asked for, before anything can fail?\n *\n * The failure path needs to know, and it starts in `main()`'s catch — including\n * for errors raised BY the parser, which is exactly when an agent most needs a\n * parseable answer. Mirrors the parser's own rule: a bare `--json` token, and\n * `--` ends option parsing so a prompt may still contain the word.\n */\nexport function wantsJson(argv: string[]): boolean {\n for (const token of argv) {\n if (token === \"--\") {\n return false;\n }\n if (token === \"--json\") {\n return true;\n }\n }\n return false;\n}\n","export const DEFAULT_TIMEOUT_MS = 30_000;\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { DEFAULT_TIMEOUT_MS } from \"@/lib/api/api-constants\";\nexport function resolveTimeout(override?: number): number {\n if (override !== undefined) {\n return override;\n }\n const raw = process.env.HEPHA_TIMEOUT_MS?.trim();\n if (!raw) {\n return DEFAULT_TIMEOUT_MS;\n }\n const parsed = Number(raw);\n if (!Number.isFinite(parsed) || parsed <= 0) {\n throw new CliError(\n `HEPHA_TIMEOUT_MS expects a positive number of milliseconds, got \"${raw}\".`,\n 2,\n );\n }\n return parsed;\n}\n","import { config } from \"@/lib/shared/config\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport type { RequestOptions } from \"@/lib/request/request-options\";\nexport function authHeaders(as: RequestOptions[\"as\"]): Record<string, string> {\n if (as) {\n return { authorization: `Bearer ${as.token}` };\n }\n\n const apiKey = process.env.HEPHA_API_KEY;\n if (apiKey) {\n // An agent's key wins over any stored human session, so a CI run is never\n // silently attributed to whoever last ran `hepha login` on the machine.\n return { \"x-api-key\": apiKey };\n }\n\n const token = process.env.HEPHA_TOKEN ?? config.load().token;\n if (token) {\n return { authorization: `Bearer ${token}` };\n }\n\n throw new CliError(\n \"Not signed in. Run `hepha login`, or set HEPHA_API_KEY to act as an agent.\",\n 1,\n { code: CLI_ERROR_CODES.NOT_AUTHENTICATED },\n );\n}\n","export function retryAfterSeconds(response: Response): number | undefined {\n // Better Auth answers `x-retry-after`, the public API answers the standard\n // header — read both rather than pick a side.\n const raw =\n response.headers.get(\"retry-after\") ??\n response.headers.get(\"x-retry-after\");\n if (!raw) {\n return undefined;\n }\n const seconds = Number(raw.trim());\n if (Number.isFinite(seconds)) {\n return seconds >= 0 ? seconds : undefined;\n }\n // RFC 9110 allows an HTTP-date instead of a delay, and proxies do send it.\n const date = Date.parse(raw.trim());\n return Number.isNaN(date)\n ? undefined\n : Math.max(0, (date - Date.now()) / 1_000);\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\n\ninterface FetchResponseOptions {\n url: URL;\n method: string;\n headers: HeadersInit;\n body: unknown;\n deadline: number;\n baseUrl: string;\n}\n\nexport async function fetchResponse({\n url,\n method,\n headers,\n body,\n deadline,\n baseUrl,\n}: FetchResponseOptions): Promise<[Response, string]> {\n const controller = new AbortController();\n let abortedBy: \"timeout\" | \"interrupt\" | null = null;\n const timer = setTimeout(() => {\n abortedBy ??= \"timeout\";\n controller.abort();\n }, deadline);\n const onInterrupt = () => {\n abortedBy ??= \"interrupt\";\n controller.abort();\n };\n process.once(\"SIGINT\", onInterrupt);\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n signal: controller.signal,\n ...(body === undefined ? {} : { body: JSON.stringify(body) }),\n });\n return [response, await response.text()];\n } catch (cause) {\n if (abortedBy === \"interrupt\") {\n throw new CliError(`${method} ${url.pathname} interrupted.`, 130, {\n code: CLI_ERROR_CODES.INTERRUPTED,\n });\n }\n if (abortedBy === \"timeout\") {\n throw new CliError(\n `${method} ${url.pathname} timed out after ${deadline}ms. Raise HEPHA_TIMEOUT_MS if the platform is simply slow.`,\n 1,\n { code: CLI_ERROR_CODES.TIMEOUT },\n );\n }\n throw new CliError(\n `Cannot reach ${baseUrl}. Set HEPHA_URL if the platform lives elsewhere. (${String(cause)})`,\n 1,\n { code: CLI_ERROR_CODES.NETWORK },\n );\n } finally {\n clearTimeout(timer);\n process.removeListener(\"SIGINT\", onInterrupt);\n }\n}\n","import type { RequestOptions } from \"@/lib/request/request-options\";\n\nexport function addQueryParameters(\n url: URL,\n query: RequestOptions[\"query\"],\n): void {\n for (const [key, value] of Object.entries(query ?? {})) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value));\n }\n }\n}\n","import { out } from \"@/lib/output/out\";\n/** Bounded and control-character-free: an HTML error page must not be able to\n * smuggle escape sequences into a terminal through a diagnostic. */\nexport function excerpt(text: string): string {\n const flattened = out.cell(text);\n return flattened.length > 200\n ? `${flattened.slice(0, 200)}\\u2026`\n : flattened;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { excerpt } from \"@/lib/excerpt/excerpt\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\n\nexport function parseResponsePayload(\n response: Response,\n text: string,\n request: { method: string; url: URL; retryAfter: number | undefined },\n): unknown {\n const { method, url, retryAfter } = request;\n\n if (!text) {\n return null;\n }\n\n try {\n return JSON.parse(text);\n } catch {\n const body = excerpt(text);\n const contentType = response.headers.get(\"content-type\") ?? \"unknown\";\n // A non-JSON error is primarily an upstream failure, not a URL diagnosis.\n throw new CliError(\n response.ok\n ? `${method} ${url.pathname} answered ${response.status} with a non-JSON body (${contentType}). Is HEPHA_URL pointing at a Hephaistos deployment?${body ? ` Body: ${body}` : \"\"}`\n : `${method} ${url.pathname} failed with ${response.status} and a non-JSON body (${contentType}).${body ? ` Body: ${body}` : \"\"}`,\n 1,\n {\n status: response.status,\n code: CLI_ERROR_CODES.NON_JSON_RESPONSE,\n ...(retryAfter === undefined ? {} : { retryAfterSeconds: retryAfter }),\n },\n );\n }\n}\n","export function readIssues(payload: unknown): unknown[] | undefined {\n if (!payload || typeof payload !== \"object\") {\n return undefined;\n }\n const data = (payload as { data?: unknown }).data;\n if (!data || typeof data !== \"object\") {\n return undefined;\n }\n const issues = (data as { issues?: unknown }).issues;\n return Array.isArray(issues) ? issues : undefined;\n}\n","export function readString(payload: unknown, key: string): string | undefined {\n if (!payload || typeof payload !== \"object\") {\n return undefined;\n }\n const value = (payload as Record<string, unknown>)[key];\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n","import { readString } from \"@/lib/string/read-string\";\nexport function messageFrom(status: number, payload: unknown): string {\n const message = readString(payload, \"message\");\n if (message) {\n // A 403 with HEPHA_API_KEY set is almost always the precedence rule biting.\n return status === 403 && process.env.HEPHA_API_KEY\n ? `${message} (HEPHA_API_KEY is set and takes precedence over your \\`hepha login\\` session — unset it to act as yourself.)`\n : message;\n }\n if (status === 401) {\n return \"Unauthorized — your credential is missing, expired or revoked.\";\n }\n return `Request failed with status ${status}.`;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { readIssues } from \"@/lib/issues/read-issues\";\nimport { messageFrom } from \"@/lib/message/message-from\";\nimport { readString } from \"@/lib/string/read-string\";\n\nexport function throwResponseError(\n response: Response,\n payload: unknown,\n retryAfter: number | undefined,\n): never {\n // Pre-router refusals use `error`; oRPC responses take precedence via `code`.\n const code = readString(payload, \"code\") ?? readString(payload, \"error\");\n const issues = readIssues(payload);\n\n throw new CliError(\n messageFrom(response.status, payload) +\n (response.status === 429 && retryAfter !== undefined\n ? ` Retry in ${retryAfter}s.`\n : \"\"),\n 1,\n {\n status: response.status,\n ...(code ? { code } : {}),\n ...(issues ? { issues } : {}),\n ...(retryAfter === undefined ? {} : { retryAfterSeconds: retryAfter }),\n },\n );\n}\n","import { config } from \"../shared/config\";\nimport type { RequestOptions } from \"@/lib/request/request-options\";\nimport { resolveTimeout } from \"@/lib/timeout/resolve-timeout\";\nimport { authHeaders } from \"@/lib/auth/auth-headers\";\nimport { retryAfterSeconds } from \"@/lib/retry/retry-after-seconds\";\nimport { fetchResponse } from \"@/lib/response/fetch-response\";\nimport { addQueryParameters } from \"@/lib/api/add-query-parameters\";\nimport { parseResponsePayload } from \"@/lib/api/parse-response-payload\";\nimport { throwResponseError } from \"@/lib/api/throw-response-error\";\n\n/**\n * The one place the CLI talks to the platform.\n *\n * Every command names its REST path once and gets its types from the router\n * (api-inputs.ts), so there is no generated client to keep in step and no\n * second copy of the API surface.\n */\nexport async function api<T>(\n requestPath: string,\n options: RequestOptions = {},\n): Promise<T> {\n const baseUrl = options.as?.baseUrl ?? config.load().baseUrl;\n const url = new URL(`${baseUrl.replace(/\\/$/, \"\")}/api/v1${requestPath}`);\n addQueryParameters(url, options.query);\n\n // Resolved before the try: a missing credential is a usage error, not a\n // network failure, and must not be reported as one.\n const headers = {\n ...authHeaders(options.as),\n ...(options.body === undefined\n ? {}\n : { \"content-type\": \"application/json\" }),\n };\n\n const method = options.method ?? \"GET\";\n const deadline = resolveTimeout(options.timeoutMs);\n const [response, text] = await fetchResponse({\n url,\n method,\n headers,\n body: options.body,\n deadline,\n baseUrl,\n });\n\n const retryAfter = retryAfterSeconds(response);\n const payload = parseResponsePayload(response, text, {\n method,\n url,\n retryAfter,\n });\n\n if (!response.ok) {\n throwResponseError(response, payload, retryAfter);\n }\n\n return payload as T;\n}\n","/**\n * Build a REST path with every dynamic segment escaped.\n *\n * Session ids, key ids and repository names were interpolated raw, so a value\n * holding `?`, `#`, `/` or `%` silently moved the request to another route or\n * grew a query string the caller never wrote. A tagged template makes the safe\n * form the easy one, and the structural slashes stay in the literal parts.\n */\nexport function path(\n strings: TemplateStringsArray,\n ...values: string[]\n): string {\n return strings.reduce(\n (accumulator, literal, index) =>\n accumulator +\n (index === 0 ? \"\" : encodeURIComponent(values[index - 1] ?? \"\")) +\n literal,\n \"\",\n );\n}\n","export function read(payload: unknown, dotted: string): unknown {\n return dotted.split(\".\").reduce<unknown>((current, key) => {\n if (!current || typeof current !== \"object\") {\n return undefined;\n }\n return (current as Record<string, unknown>)[key];\n }, payload);\n}\n","import { CliError } from \"../cli/cli-error\";\nimport { VERSION } from \"../version/version-constants\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport type { Predicate } from \"@/lib/predicate/predicate\";\nimport { read } from \"@/lib/read/read\";\n\n/**\n * Check a 2xx payload before the command destructures it. The client casts\n * responses to the router's types — a compile-time promise about a server that\n * may be older or newer than this binary. When it did not hold, the first\n * property read threw `Cannot read properties of undefined`.\n */\nexport function expectShape<T>(\n payload: unknown,\n endpoint: string,\n requirements: Record<string, Predicate>,\n): T {\n for (const [field, predicate] of Object.entries(requirements)) {\n if (!predicate(read(payload, field))) {\n throw new CliError(\n `${endpoint} returned a payload this CLI does not understand: \"${field}\" is missing or has the wrong type. hepha ${VERSION} may be out of step with the platform — try \\`npm install -g @impulselab/hepha\\`.`,\n 1,\n { code: CLI_ERROR_CODES.API_SCHEMA_MISMATCH },\n );\n }\n }\n\n return payload as T;\n}\n","/** The handful of shapes the CLI actually destructures. */\nexport const is = {\n string: (value: unknown) => typeof value === \"string\",\n // Absent passes: a field a deployment older than this binary does not send.\n optionalString: (value: unknown) =>\n value === undefined || typeof value === \"string\",\n number: (value: unknown) => typeof value === \"number\",\n array: (value: unknown) => Array.isArray(value),\n object: (value: unknown) =>\n Boolean(value) && typeof value === \"object\" && !Array.isArray(value),\n};\n","export const ACTIONS = [\"list\", \"show\", \"approve\", \"reject\"] as const;\n\nexport const REJECT_MODES = [\"rework\", \"terminate\"] as const;\n","import { api } from \"@/lib/api/api\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport async function listApprovals(asJson: boolean): Promise<void> {\n const result = expectShape<ApiOutputs[\"approvals\"][\"list\"]>(\n await api(\"/approvals\"),\n \"GET /approvals\",\n { items: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n if (result.items.length === 0) {\n out.line(\"No guardrail waiting on you.\");\n return;\n }\n out.table(\n result.items.map((item) => [\n out.cell(item.id),\n out.cell(item.guardrailKind),\n out.cell(item.repoName ?? \"—\"),\n out.cell(item.summary),\n ]),\n );\n}\n","import { api } from \"../../lib/api/api\";\nimport { path } from \"../../lib/path/path\";\nimport { args } from \"../../lib/args/args\";\nimport { CliError } from \"../../lib/cli/cli-error\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport {\n ACTIONS,\n REJECT_MODES,\n} from \"@/commands/approvals/approvals-constants\";\nimport { listApprovals } from \"@/commands/approvals/list-approvals\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Approving and rejecting require a human session and are refused for an API\n * key: a machine standing in for human validation would defeat the guardrail.\n */\nexport async function approvalsCommand(parsed: ParsedArgs): Promise<void> {\n const action = args.action(parsed, \"approvals\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n if (action === \"list\") {\n args.expect(parsed, { positional: 1 });\n return await listApprovals(asJson);\n }\n\n args.expect(parsed, {\n positional: 2,\n ...(action === \"reject\" ? { flags: [\"mode\", \"feedback\"] } : {}),\n });\n const guardrailId = args.required(parsed, 1, \"guardrailRequestId\");\n\n if (action === \"show\") {\n const detail = expectShape<ApiOutputs[\"approvals\"][\"get\"]>(\n await api(path`/approvals/${guardrailId}`),\n \"GET /approvals/{id}\",\n { guardrailKind: is.string, status: is.string, summary: is.string },\n );\n if (asJson) {\n out.json(detail);\n return;\n }\n out.line(\n `${out.paint(out.cell(detail.guardrailKind), \"bold\")} ${detail.status}`,\n );\n out.line(out.safe(detail.summary));\n out.line();\n out.json(detail.payload);\n return;\n }\n\n if (action === \"approve\") {\n const result = await api<ApiOutputs[\"approvals\"][\"approve\"]>(\n path`/approvals/${guardrailId}/approve`,\n { method: \"POST\", body: {} },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(`${out.paint(\"✓\", \"green\")} Approved ${out.cell(guardrailId)}`);\n return;\n }\n\n const mode = args.choice(parsed, \"mode\", REJECT_MODES) ?? \"rework\";\n if (mode === \"rework\" && !parsed.flags.feedback) {\n throw new CliError(\n \"--feedback is required with --mode rework: the agent needs to know what to change.\",\n 2,\n );\n }\n\n const result = await api<ApiOutputs[\"approvals\"][\"reject\"]>(\n path`/approvals/${guardrailId}/reject`,\n {\n method: \"POST\",\n body: {\n mode,\n ...(parsed.flags.feedback ? { feedback: parsed.flags.feedback } : {}),\n },\n },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n `${out.paint(\"✓\", \"green\")} Rejected ${out.cell(guardrailId)} (${mode})`,\n );\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { out } from \"@/lib/output/out\";\nimport { path } from \"@/lib/path/path\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogBranches(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, { positional: 1 });\n const repoFullName = args.required(parsed, 0, \"owner/repo\");\n const segments = repoFullName.split(\"/\");\n const [owner, repo] = segments;\n if (segments.length !== 2 || !owner || !repo) {\n throw new CliError(\n `Expected a repository as \"owner/repo\", got \"${repoFullName}\".`,\n 2,\n );\n }\n\n const result = await api<ApiOutputs[\"catalog\"][\"branches\"]>(\n path`/repos/${owner}/${repo}/branches`,\n );\n if (!result.result) {\n throw new CliError(`No GitHub installation covers ${repoFullName}.`);\n }\n if (asJson) {\n out.json(result);\n return;\n }\n for (const branch of result.result.branches) {\n out.line(\n branch === result.result.defaultBranch\n ? `${out.cell(branch)} ${out.paint(\"(default)\", \"dim\")}`\n : out.cell(branch),\n );\n }\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogModels(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, {});\n const result = expectShape<ApiOutputs[\"catalog\"][\"models\"]>(\n await api(\"/models\"),\n \"GET /models\",\n { harnesses: is.array, gatewayModels: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(out.paint(\"harnesses\", \"dim\"));\n for (const harness of result.harnesses) {\n out.line(` ${out.cell(harness)}`);\n }\n out.line();\n out.line(out.paint(\"gateway models\", \"dim\"));\n for (const model of result.gatewayModels) {\n out.line(` ${out.cell(model.id)}`);\n }\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Reads a catalog list endpoint: no flags accepted, the response shape checked\n * before anything renders it. Generic in the payload so each command keeps its\n * own contract from `ApiOutputs` and only names the array it expects.\n */\nexport async function readCatalogList<T>(\n parsed: ParsedArgs,\n path: string,\n field: string,\n): Promise<T> {\n args.expect(parsed, {});\n return expectShape<T>(await api(path), `GET ${path}`, { [field]: is.array });\n}\n","import { out } from \"@/lib/output/out\";\nimport { readCatalogList } from \"@/commands/catalog/read-catalog-list\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogRepos(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n const result = await readCatalogList<ApiOutputs[\"catalog\"][\"repos\"]>(\n parsed,\n \"/repos\",\n \"repos\",\n );\n if (asJson) {\n out.json(result);\n return;\n }\n for (const repo of result.repos) {\n out.line(out.cell(repo));\n }\n}\n","import { out } from \"@/lib/output/out\";\nimport { readCatalogList } from \"@/commands/catalog/read-catalog-list\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function listCatalogSkills(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n const result = await readCatalogList<ApiOutputs[\"catalog\"][\"skills\"]>(\n parsed,\n \"/skills\",\n \"skills\",\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.table(\n result.skills.map((skill) => [\n out.cell(skill.id),\n out.cell(skill.name),\n out.cell(skill.description ?? \"\"),\n ]),\n );\n}\n","import { listCatalogBranches } from \"@/commands/catalog/list-catalog-branches\";\nimport { listCatalogModels } from \"@/commands/catalog/list-catalog-models\";\nimport { listCatalogRepos } from \"@/commands/catalog/list-catalog-repos\";\nimport { listCatalogSkills } from \"@/commands/catalog/list-catalog-skills\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * What `hepha catalog <topic>` can list. A table rather than a chain of\n * comparisons: adding a topic is one line, and the set of topics is readable\n * without following four branches.\n */\nexport const catalogTopics: Record<\n string,\n (parsed: ParsedArgs, asJson: boolean) => Promise<void>\n> = {\n branches: listCatalogBranches,\n models: listCatalogModels,\n repos: listCatalogRepos,\n skills: listCatalogSkills,\n};\n","import { CliError } from \"../../lib/cli/cli-error\";\nimport { catalogTopics } from \"@/commands/catalog/catalog-topics\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Read before creating a session: a repository outside `repos` is refused at\n * creation, and a model outside `models` is not routable.\n */\nexport async function catalogCommand(\n topic: string,\n parsed: ParsedArgs,\n): Promise<void> {\n const list = catalogTopics[topic];\n if (!list) {\n throw new CliError(`Unknown catalog topic \"${topic}\".`, 2);\n }\n await list(parsed, parsed.booleans.has(\"json\"));\n}\n","export const ACTIONS = [\"list\", \"create\", \"revoke\"] as const;\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport type { Scope } from \"@/commands/scope/scope\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function createKey(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, { flags: [\"scope\", \"expires-in-days\"], positional: 2 });\n const name = args.required(parsed, 1, \"name\");\n const scopes = parsed.repeated.scope as Scope;\n const expiresInDays = args.integer(parsed, \"expires-in-days\", {\n min: 1,\n max: 365,\n });\n const created = expectShape<ApiOutputs[\"keys\"][\"create\"]>(\n await api(\"/keys\", {\n method: \"POST\",\n body: {\n name,\n ...(scopes && scopes.length > 0 ? { scopes } : {}),\n ...(expiresInDays !== undefined ? { expiresInDays } : {}),\n },\n }),\n \"POST /keys\",\n { key: is.string, scopes: is.array },\n );\n if (asJson) {\n out.json(created);\n return;\n }\n out.line(\n `${out.paint(\"✓\", \"green\")} Created \"${out.cell(created.name ?? name)}\"`,\n );\n out.line();\n out.line(` ${out.paint(created.key, \"bold\")}`);\n out.line();\n out.line(\n out.paint(\n \" Copy it now — it is hashed at rest and never shown again.\",\n \"dim\",\n ),\n );\n out.line(out.paint(` Scopes: ${created.scopes.join(\" \")}`, \"dim\"));\n}\n","import { api } from \"../../lib/api/api\";\nimport { path } from \"../../lib/path/path\";\nimport { args } from \"../../lib/args/args\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport { ACTIONS } from \"@/commands/keys/keys-constants\";\nimport { createKey } from \"@/commands/key/create-key\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Human sessions only, by design: a key cannot mint or revoke a key, so the\n * whole group fails with a 403 when HEPHA_API_KEY is set.\n */\nexport async function keysCommand(parsed: ParsedArgs): Promise<void> {\n const action = args.action(parsed, \"keys\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n if (action === \"list\") {\n args.expect(parsed, { positional: 1 });\n const result = expectShape<ApiOutputs[\"keys\"][\"list\"]>(\n await api(\"/keys\"),\n \"GET /keys\",\n { keys: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n if (result.keys.length === 0) {\n out.line(\"No keys. Create one with `hepha keys create <name>`.\");\n return;\n }\n out.table([\n [\n out.paint(\"ID\", \"dim\"),\n out.paint(\"NAME\", \"dim\"),\n out.paint(\"PREFIX\", \"dim\"),\n out.paint(\"SCOPES\", \"dim\"),\n ],\n ...result.keys.map((key) => [\n out.cell(key.id),\n out.cell(key.name ?? \"—\"),\n out.cell(key.start ?? \"—\"),\n key.scopes.join(\" \"),\n ]),\n ]);\n return;\n }\n\n if (action === \"create\") {\n return await createKey(parsed, asJson);\n }\n\n args.expect(parsed, { positional: 2 });\n const keyId = args.required(parsed, 1, \"keyId\");\n const result = await api<ApiOutputs[\"keys\"][\"revoke\"]>(path`/keys/${keyId}`, {\n method: \"DELETE\",\n });\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(`${out.paint(\"✓\", \"green\")} Revoked ${out.cell(keyId)}`);\n}\n","import { createAuthClient } from \"better-auth/client\";\nimport { deviceAuthorizationClient } from \"better-auth/client/plugins\";\n\nimport { args } from \"../../lib/args/args\";\nimport { deviceTokenError } from \"../../lib/token/device-token-error\";\nimport { nextPollDelay } from \"../../lib/retry/next-poll-delay\";\nimport { CliError } from \"../../lib/cli/cli-error\";\nimport { openBrowser } from \"../../lib/browser/open-browser\";\nimport { out } from \"../../lib/output/out\";\nimport { MIN_BACKOFF } from \"@/commands/login/login-constants\";\nimport { CLIENT_ID } from \"@/commands/client/client-id-constants\";\nimport { sleep } from \"@/commands/sleep/sleep\";\nimport { completeLogin } from \"@/commands/complete/complete-login\";\nimport { resolveLoginBaseUrl } from \"@/commands/login/resolve-login-base-url\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * `hepha login` — OAuth 2.0 device authorization (RFC 8628).\n *\n * The CLI never sees a password and never asks for a pasted token: it gets a\n * short code, a human approves it in a browser that is already signed in to\n * Hephaistos, and only then does a session token exist. That approval is also\n * what makes a CLI session count as \"a human\" for guardrail decisions.\n */\nexport async function loginCommand(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, { flags: [\"url\"] });\n\n const baseUrl = resolveLoginBaseUrl(parsed);\n\n const authClient = createAuthClient({\n baseURL: baseUrl,\n plugins: [deviceAuthorizationClient()],\n });\n\n const { data: device, error: deviceError } = await authClient.device.code({\n client_id: CLIENT_ID,\n scope: \"openid profile email\",\n });\n\n if (deviceError || !device) {\n throw new CliError(\n deviceError?.error_description ??\n `Could not start a device login against ${baseUrl}.`,\n );\n }\n\n const verificationUrl =\n device.verification_uri_complete ?? device.verification_uri;\n\n out.line();\n out.line(` Code ${out.paint(out.cell(device.user_code), \"bold\")}`);\n out.line(` Open ${out.cell(verificationUrl)}`);\n out.line();\n out.line(out.paint(\" Waiting for approval…\", \"dim\"));\n\n openBrowser(verificationUrl);\n\n let interval = device.interval ?? 5;\n const deadline = Date.now() + (device.expires_in ?? 900) * 1000;\n\n while (Date.now() < deadline) {\n // Never sleep past the code's own expiry (see nextPollDelay).\n const delay = nextPollDelay(interval, (deadline - Date.now()) / 1000);\n if (delay === null) {\n break;\n }\n await sleep(delay);\n\n const { data: token, error } = await authClient.device.token({\n grant_type: \"urn:ietf:params:oauth:grant-type:device_code\",\n device_code: device.device_code,\n client_id: CLIENT_ID,\n });\n\n // A 429 is transient by definition, and giving up on one abandoned a login\n // the human was about to approve — with \"Device authorization failed.\" as\n // the only clue, because the rate limiter answers a plain message and none\n // of the OAuth error codes below. Back off for as long as the server asks\n // (it answers `x-retry-after`), with a floor, and keep polling.\n if (error?.status === 429) {\n interval = Math.max(\n deviceTokenError.retryAfter(error) ?? interval * 2,\n MIN_BACKOFF,\n );\n continue;\n }\n\n if (token?.access_token) {\n await completeLogin(baseUrl, token.access_token);\n return;\n }\n\n if (!error) {\n continue;\n }\n\n switch (error.error) {\n case \"authorization_pending\":\n continue;\n case \"slow_down\":\n interval += 5;\n continue;\n case \"access_denied\":\n throw new CliError(\"Access denied — the request was rejected.\");\n default:\n // The server's own message, when it has one. Collapsing everything\n // that is not an OAuth code into \"Device authorization failed.\" is how\n // a rate-limit refusal looked like a broken device flow.\n throw new CliError(\n error.error_description ||\n deviceTokenError.message(error) ||\n `Device authorization failed (HTTP ${error.status}).`,\n );\n }\n }\n\n throw new CliError(\"The code expired before it was approved. Try again.\");\n}\n","/**\n * The client types this error as the OAuth code set alone, but the refusals that\n * actually broke `hepha login` carry neither — a rate limiter answers a plain\n * message and a status. Hence reading defensively off `unknown`.\n */\nexport const deviceTokenError = {\n /** What the server said, when it said anything at all. */\n message(error: unknown): string | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const message = (error as { message?: unknown }).message;\n return typeof message === \"string\" && message.length > 0\n ? message\n : undefined;\n },\n\n /** Better Auth answers `X-Retry-After`, the platform the standard header. */\n retryAfter(error: unknown): number | undefined {\n if (!error || typeof error !== \"object\") {\n return undefined;\n }\n const headers = (error as { headers?: unknown }).headers;\n if (!(headers instanceof Headers)) {\n return undefined;\n }\n const raw =\n headers.get(\"x-retry-after\") ?? headers.get(\"retry-after\") ?? undefined;\n if (!raw) {\n return undefined;\n }\n const seconds = Number(raw.trim());\n return Number.isFinite(seconds) && seconds > 0 ? seconds : undefined;\n },\n};\n","/**\n * How long to wait before the next attempt, or null when there is no time left.\n * A loop that tests its deadline only BEFORE sleeping slept a grown backoff in\n * full — minutes past the expiry of the device code, or of a follow's budget.\n */\nexport function nextPollDelay(\n interval: number,\n remainingSeconds: number,\n): number | null {\n if (remainingSeconds <= 0) {\n return null;\n }\n return Math.min(interval, remainingSeconds);\n}\n","import { spawn } from \"node:child_process\";\n\n/**\n * Best effort: on a headless box or over SSH there is no browser to open, so a\n * failure here is not an error — the URL is always printed as well.\n */\nexport function openBrowser(url: string): void {\n const command =\n process.platform === \"darwin\"\n ? \"open\"\n : process.platform === \"win32\"\n ? \"cmd\"\n : \"xdg-open\";\n const commandArgs =\n process.platform === \"win32\" ? [\"/c\", \"start\", \"\", url] : [url];\n\n try {\n const child = spawn(command, commandArgs, {\n stdio: \"ignore\",\n detached: true,\n });\n // A missing `xdg-open` (minimal containers, most SSH hosts) surfaces as an\n // ASYNCHRONOUS 'error' event that the try/catch cannot see. Unhandled, it\n // is an uncaught exception that kills the process mid-login — so the CLI\n // would stop polling instead of falling back to the printed URL.\n child.on(\"error\", () => {});\n child.unref();\n } catch {\n // Printing the URL is the fallback, and it already happened.\n }\n}\n","export const MIN_BACKOFF = 10;\n","export const USER_ROLES = {\n ADMIN: \"admin\",\n MEMBER: \"member\",\n} as const;\n\nexport type UserRole = (typeof USER_ROLES)[keyof typeof USER_ROLES];\nexport const ALL_USER_ROLES = Object.values(USER_ROLES);\n\nexport const ALLOWED_EMAIL_DOMAIN = \"@impulselab.ai\";\n\n/**\n * Public API scopes, in `resource:action` form. A Better Auth API key stores\n * them as its `permissions` map; a human session (browser cookie or a CLI\n * device-flow bearer token) implicitly holds every scope and is governed by\n * the user's role instead.\n *\n * Deliberately absent: `approvals:decide` and anything under `keys`. Guardrail\n * decisions (VISION \"never without explicit human validation\") and credential\n * issuance are human-only actions — no key can ever be granted them, so a\n * leaked key can neither approve a merge nor mint another key.\n */\nexport const API_SCOPES = [\n \"sessions:read\",\n \"sessions:write\",\n \"questions:read\",\n \"questions:answer\",\n \"approvals:read\",\n \"catalog:read\",\n \"pull_requests:read\",\n \"browser:read\",\n \"browser:write\",\n] as const;\n\nexport type ApiScope = (typeof API_SCOPES)[number];\n\n/** Read-only, minus the browser vault: it names the services a human uses. */\nexport const DEFAULT_API_SCOPES: readonly ApiScope[] = API_SCOPES.filter(\n (scope) => scope.endsWith(\":read\") && !scope.startsWith(\"browser:\"),\n);\n\n/** Prefix stamped on every issued key, so leaks are greppable. */\nexport const API_KEY_PREFIX = \"hepha_\";\n\n/** Header carrying an API key. Honoured on `/api/v1` only — see\n * utils/strip-api-key-header.ts for why. */\nexport const API_KEY_HEADER = \"x-api-key\";\n\n/**\n * Browser session lifetime. Signing in is always \"remember me\": there is no\n * opt-out in the UI, so every sign-in path writes a PERSISTENT cookie that\n * survives closing the browser. `UPDATE_AGE` slides the expiry forward on use,\n * so an active human never sees the sign-in screen again.\n */\nexport const SESSION = {\n /** Cookie + session row lifetime: 30 days. */\n EXPIRES_IN: 60 * 60 * 24 * 30,\n /** Refresh the expiry at most once a day, to avoid a write per request. */\n UPDATE_AGE: 60 * 60 * 24,\n /** Cache the session row in memory for this long, to avoid a read per request. */\n COOKIE_CACHE_MAX_AGE: 60,\n} as const;\n\n/**\n * OAuth 2.0 device authorization grant (RFC 8628) — how the CLI logs a human\n * in without ever handling their password: it asks for a user code, the human\n * approves it on {BASE_URL}{VERIFICATION_PATH} in an already-signed-in\n * browser, and the CLI exchanges the device code for a session token.\n */\nexport const DEVICE_AUTHORIZATION = {\n /** Only these clients may open a device flow. */\n CLIENT_IDS: [\"hepha-cli\", \"hepha-extension\"],\n /** Lifetime of an unapproved user code. */\n EXPIRES_IN: \"15m\",\n /** Minimum delay the CLI must wait between two token polls. */\n INTERVAL: \"5s\",\n /** Page a human visits to approve a pending device. */\n VERIFICATION_PATH: \"/device\",\n /**\n * Per-IP ceiling on `/device/token`. The window is deliberately SHORTER than\n * INTERVAL: Better Auth only resets its counter when two requests are further\n * apart than the window, so a 5s poll under the default 60s window never reset\n * it and every login 429'd partway through the code's lifetime.\n */\n POLL_RATE_LIMIT: { WINDOW_SECONDS: 4, MAX_REQUESTS: 10 },\n} as const;\n\n// Copied by hand into the extension, which ships no build step and cannot\n// import this; `apps/browser-extension/test/limits-match-server.test.mjs` fails on drift.\nexport const BROWSER_CAPTURE_LIMITS = {\n COOKIES: 300,\n ORIGINS: 25,\n STORAGE_KEYS_PER_ORIGIN: 300,\n NAME_LENGTH: 1024,\n VALUE_LENGTH: 32_768,\n /** `JSON.stringify(state).length`: UTF-16 code units, not bytes. */\n TOTAL_CHARS: 1_000_000,\n LABEL_LENGTH: 120,\n USER_AGENT_LENGTH: 512,\n LOCALE_LENGTH: 64,\n EXTENSION_VERSION_LENGTH: 32,\n DOMAINS_PER_USER: 200,\n} as const;\n\n/**\n * Bounds of a registry skill, shared by every write path so the registry can\n * never hold a skill the edit form refuses to save back.\n *\n * The caps used to be restated per route, so a skill written through one path\n * could violate another's rule and become uneditable for good.\n */\nexport const SKILL_LIMITS = {\n /** Kebab-case slug, matched verbatim by `buildHarnessSkills`. */\n NAME_PATTERN: /^[a-z0-9]+(-[a-z0-9]+)*$/,\n NAME_MAX_LENGTH: 80,\n /** Not a title: the full \"use this when…\" trigger list drives matching. */\n DESCRIPTION_MAX_LENGTH: 2000,\n /** Relative POSIX path of a supporting file bundled with the skill. */\n FILE_PATH_MAX_LENGTH: 200,\n /** One activation scope entry: a repo full name or a channel id. */\n ACTIVATION_SCOPE_MAX_LENGTH: 120,\n} as const;\n\n/** Reserved: the harness materializes the skill body as SKILL.md. */\nexport const SKILL_BODY_FILENAME = \"skill.md\";\n\n/** The auto-maintained global review-lessons skill; per-repo names come from\n * utils/review-lesson-skill-name.ts. */\nexport const REVIEW_LESSONS_SKILL_NAME = \"review-lessons\";\n\n// Derived by Chrome from the RSA key in `apps/browser-extension/manifest.json`.\n// One exact id, never a wildcard: trusted origins also allowlist redirects.\nexport const BROWSER_EXTENSION_ORIGIN =\n \"chrome-extension://ieppdghbneelaninllkeimfcdnccbblj\";\n","import { DEVICE_AUTHORIZATION } from \"@repo/database/constants\";\nexport const CLIENT_ID = DEVICE_AUTHORIZATION.CLIENT_IDS[0];\n","export function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n}\n","import { api } from \"@/lib/api/api\";\nimport { config } from \"@/lib/shared/config\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport async function completeLogin(\n baseUrl: string,\n token: string,\n): Promise<void> {\n const identity = await api<ApiOutputs[\"me\"][\"get\"]>(\"/me\", {\n as: { baseUrl, token },\n });\n config.save({\n baseUrl,\n token,\n user: {\n id: identity.user.id,\n name: identity.user.name,\n email: identity.user.email,\n },\n });\n out.line();\n out.line(\n `${out.paint(\"✓\", \"green\")} Signed in as ${identity.user.email} on ${baseUrl}`,\n );\n out.line(out.paint(` Session stored in ${config.path}`, \"dim\"));\n}\n","import { config } from \"@/lib/shared/config\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { isHttpUrl } from \"@/lib/http/is-http-url\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport function resolveLoginBaseUrl(parsed: ParsedArgs): string {\n const requested = parsed.flags.url?.trim();\n if (requested !== undefined && !isHttpUrl(requested)) {\n throw new CliError(`--url is not a valid http(s) URL: \"${requested}\".`, 2);\n }\n return (requested ?? config.load().baseUrl).replace(/\\/$/, \"\");\n}\n","import { args } from \"../../lib/args/args\";\nimport { config } from \"../../lib/shared/config\";\nimport { out } from \"../../lib/output/out\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/** Forgets the local session only; issued API keys keep working. */\nexport function logoutCommand(parsed: ParsedArgs): void {\n args.expect(parsed, {});\n\n config.clear();\n\n if (parsed.booleans.has(\"json\")) {\n out.json({ signedOut: true });\n return;\n }\n\n out.line(\"Signed out.\");\n}\n","export const LIMITS = {\n QUESTION_ID: 40,\n OPTION_ID: 40,\n OPTIONS_PER_ANSWER: 50,\n FREE_TEXT: 10_000,\n ANSWERS: 50,\n} as const;\n","import { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport { CliError } from \"@/lib/cli/cli-error\";\n\nexport function validateFreeText(\n value: string | undefined,\n label: string,\n): void {\n if (value === undefined) {\n return;\n }\n const freeText = value.trim();\n if (freeText.length === 0) {\n throw new CliError(`${label} has empty free text.`, 2);\n }\n if (freeText.length > LIMITS.FREE_TEXT) {\n throw new CliError(\n `${label} has free text longer than ${LIMITS.FREE_TEXT} characters.`,\n 2,\n );\n }\n}\n","import { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport { CliError } from \"@/lib/cli/cli-error\";\n\nexport function validateSelectedOptionIds(\n options: string[] | undefined,\n label: string,\n): void {\n if (options === undefined) {\n return;\n }\n if (options.length > LIMITS.OPTIONS_PER_ANSWER) {\n throw new CliError(\n `${label} selects more than ${LIMITS.OPTIONS_PER_ANSWER} options.`,\n 2,\n );\n }\n for (const id of options) {\n if (id.trim().length === 0) {\n throw new CliError(`${label} has an empty option id.`, 2);\n }\n if (id.trim().length > LIMITS.OPTION_ID) {\n throw new CliError(\n `${label} has an option id longer than ${LIMITS.OPTION_ID} characters.`,\n 2,\n );\n }\n }\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport type { Answer } from \"@/commands/answer/answer\";\nimport { validateFreeText } from \"@/commands/answer/validate-free-text\";\nimport { validateSelectedOptionIds } from \"@/commands/answer/validate-selected-option-ids\";\n/** `label` names the source — `--answers[2]` or `--option q1=…` — because both\n * entry paths build the same shape and must fail identically. */\nexport function validateAnswer(answer: Answer, label: string): void {\n // The ONE field the server does not trim, so its ceiling applies to the raw\n // value. Emptiness is checked more strictly than the API on purpose: a blank\n // id passes `min(1)` and then matches no question, leaving the round silently\n // unanswered.\n if (answer.questionId.trim().length === 0) {\n throw new CliError(`${label} needs a non-empty \"questionId\".`, 2);\n }\n if (answer.questionId.length > LIMITS.QUESTION_ID) {\n throw new CliError(\n `${label} has a \"questionId\" longer than ${LIMITS.QUESTION_ID} characters.`,\n 2,\n );\n }\n\n const options = answer.selectedOptionIds;\n validateSelectedOptionIds(options, label);\n validateFreeText(answer.freeText, label);\n\n // The server's own rule; `--option q1=,,` reaches exactly this shape.\n if (\n (options === undefined || options.length === 0) &&\n answer.freeText === undefined\n ) {\n throw new CliError(\n `${label} answers nothing. Give it at least one option id or some free text.`,\n 2,\n );\n }\n}\n","import { validateAnswer } from \"@/commands/answer/validate-answer\";\nimport type { Answer } from \"@/commands/answer/answer\";\nimport { CliError } from \"@/lib/cli/cli-error\";\n\nexport function parseAnswerEntry(entry: unknown, label: string): Answer {\n if (!entry || typeof entry !== \"object\" || Array.isArray(entry)) {\n throw new CliError(`${label} must be an object.`, 2);\n }\n\n const answer = entry as Record<string, unknown>;\n if (typeof answer.questionId !== \"string\") {\n throw new CliError(`${label} needs a non-empty \"questionId\".`, 2);\n }\n if (\n answer.selectedOptionIds !== undefined &&\n (!Array.isArray(answer.selectedOptionIds) ||\n answer.selectedOptionIds.some((id) => typeof id !== \"string\"))\n ) {\n throw new CliError(\n `${label}.selectedOptionIds must be an array of strings.`,\n 2,\n );\n }\n if (answer.freeText !== undefined && typeof answer.freeText !== \"string\") {\n throw new CliError(`${label}.freeText must be a string.`, 2);\n }\n\n const parsed = entry as Answer;\n validateAnswer(parsed, label);\n return parsed;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport type { Answers } from \"@/commands/answers/answers\";\nimport { parseAnswerEntry } from \"@/commands/answers/parse-answer-entry\";\n/** `--answers '{}'` used to sail through `JSON.parse` and be posted as\n * `{\"answers\": {}}`, contradicting the CLI's own error message. */\nexport function parseAnswersFlag(raw: string): Answers {\n let decoded: unknown;\n try {\n decoded = JSON.parse(raw);\n } catch {\n throw new CliError(\"--answers expects a JSON array.\", 2);\n }\n\n if (!Array.isArray(decoded) || decoded.length === 0) {\n throw new CliError(\n '--answers expects a non-empty JSON array, e.g. \\'[{\"questionId\":\"q1\",\"selectedOptionIds\":[\"1\"]}]\\'.',\n 2,\n );\n }\n\n if (decoded.length > LIMITS.ANSWERS) {\n throw new CliError(\n `--answers carries more than ${LIMITS.ANSWERS} entries.`,\n 2,\n );\n }\n\n for (const [index, entry] of decoded.entries()) {\n parseAnswerEntry(entry, `--answers[${index}]`);\n }\n\n return decoded as Answers;\n}\n","import { CliError } from \"../../lib/cli/cli-error\";\nimport { LIMITS } from \"@/commands/answers/collect-answers-constants\";\nimport type { Answers } from \"@/commands/answers/answers\";\nimport type { Answer } from \"@/commands/answer/answer\";\nimport { validateAnswer } from \"@/commands/answer/validate-answer\";\nimport { parseAnswersFlag } from \"@/commands/answers/parse-answers-flag\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/** `--option <questionId>=1,2` and `--text <questionId>=…`, or `--answers <json>`. */\nexport function collectAnswers(parsed: ParsedArgs): Answers {\n if (parsed.flags.answers) {\n return parseAnswersFlag(parsed.flags.answers);\n }\n\n const byQuestion = new Map<string, Answer>();\n\n const put = (pair: string, apply: (entry: Answer) => void) => {\n const equalsAt = pair.indexOf(\"=\");\n if (equalsAt < 0) {\n throw new CliError(`Expected <questionId>=<value>, got \"${pair}\".`, 2);\n }\n const questionId = pair.slice(0, equalsAt);\n const entry = byQuestion.get(questionId) ?? { questionId };\n apply(entry);\n byQuestion.set(questionId, entry);\n };\n\n for (const pair of parsed.repeated.option ?? []) {\n put(pair, (entry) => {\n entry.selectedOptionIds = pair\n .slice(pair.indexOf(\"=\") + 1)\n .split(\",\")\n .map((id) => id.trim())\n .filter(Boolean);\n });\n }\n\n for (const pair of parsed.repeated.text ?? []) {\n put(pair, (entry) => {\n entry.freeText = pair.slice(pair.indexOf(\"=\") + 1);\n });\n }\n\n const answers = [...byQuestion.values()];\n if (answers.length === 0) {\n throw new CliError(\n \"Nothing to submit. Use --option <questionId>=<ids>, --text <questionId>=<answer>, or --answers <json>.\",\n 2,\n );\n }\n if (answers.length > LIMITS.ANSWERS) {\n throw new CliError(\n `More than ${LIMITS.ANSWERS} answers in one submission.`,\n 2,\n );\n }\n\n for (const answer of answers) {\n validateAnswer(answer, `--option/--text ${answer.questionId}`);\n }\n\n return answers;\n}\n","export const ACTIONS = [\"list\", \"show\", \"answer\", \"cancel\"] as const;\n","import { api } from \"@/lib/api/api\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport { path } from \"@/lib/path/path\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport async function listQuestions(\n sessionId: string | undefined,\n asJson: boolean,\n): Promise<void> {\n const result = expectShape<ApiOutputs[\"questions\"][\"list\"]>(\n await api(\n sessionId ? path`/sessions/${sessionId}/questions` : \"/questions\",\n ),\n \"GET /questions\",\n { items: is.array },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n if (result.items.length === 0) {\n out.line(\"Nothing waiting on you.\");\n return;\n }\n out.table(\n result.items.map((batch) => [\n out.cell(batch.id),\n out.cell(batch.sessionId),\n `${batch.questions.length} question(s)`,\n out.cell(batch.sessionTitle),\n ]),\n );\n}\n","import type { Batch } from \"@/commands/batch/batch\";\nimport { out } from \"@/lib/output/out\";\n\nexport function printBatchQuestion(question: Batch[\"questions\"][number]): void {\n out.line();\n if (question.header) {\n out.line(out.paint(out.cell(question.header), \"dim\"));\n }\n out.line(\n `${out.paint(out.cell(question.id), \"dim\")} ${out.safe(question.body)}`,\n );\n if (question.image) {\n out.line(out.paint(` (image) ${out.cell(question.image)}`, \"dim\"));\n }\n for (const option of question.options) {\n const recommended = option.id === question.recommendedOptionId;\n // Image-only options still need an identifiable terminal label.\n const label = option.label\n ? out.cell(option.label)\n : option.image\n ? out.paint(`(image) ${out.cell(option.image)}`, \"dim\")\n : out.paint(\"(no label)\", \"dim\");\n out.line(\n ` ${out.cell(option.id)}) ${label}${recommended ? out.paint(\" ← recommended\", \"green\") : \"\"}`,\n );\n }\n if (question.allowFreeText) {\n out.line(out.paint(\" free text accepted\", \"dim\"));\n }\n}\n","import { out } from \"@/lib/output/out\";\nimport type { Batch } from \"@/commands/batch/batch\";\nimport { printBatchQuestion } from \"@/commands/batch/print-batch-question\";\nexport function printBatch(batch: Batch): void {\n // Questions are agent-authored text — sanitise before printing (out.safe).\n out.line(\n `${out.paint(out.cell(batch.sessionTitle), \"bold\")} ${out.paint(`round ${batch.round}`, \"dim\")}`,\n );\n out.line(\n out.paint(\n `batch ${out.cell(batch.id)} · session ${out.cell(batch.sessionId)}`,\n \"dim\",\n ),\n );\n\n for (const question of batch.questions) {\n printBatchQuestion(question);\n }\n}\n","import { api } from \"../../lib/api/api\";\nimport { path } from \"../../lib/path/path\";\nimport { args } from \"../../lib/args/args\";\nimport { collectAnswers } from \"../answers/collect-answers\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport { ACTIONS } from \"@/commands/questions/questions-constants\";\nimport type { Batch } from \"@/commands/batch/batch\";\nimport { listQuestions } from \"@/commands/questions/list-questions\";\nimport { printBatch } from \"@/commands/batch/print-batch\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * A session with an unanswered round parks forever. Answering is a normal\n * scope, so an agent can do it; only guardrail decisions need a human.\n */\nexport async function questionsCommand(parsed: ParsedArgs): Promise<void> {\n const action = args.action(parsed, \"questions\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n if (action === \"list\") {\n args.expect(parsed, { flags: [\"session\"], positional: 1 });\n return await listQuestions(parsed.flags.session, asJson);\n }\n\n args.expect(parsed, {\n positional: 2,\n ...(action === \"answer\" ? { flags: [\"option\", \"text\", \"answers\"] } : {}),\n });\n const batchId = args.required(parsed, 1, \"batchId\");\n\n if (action === \"show\") {\n const batch = expectShape<Batch>(\n await api(path`/questions/${batchId}`),\n \"GET /questions/{id}\",\n { id: is.string, questions: is.array, sessionTitle: is.string },\n );\n if (asJson) {\n out.json(batch);\n return;\n }\n printBatch(batch);\n return;\n }\n\n if (action === \"answer\") {\n const result = expectShape<ApiOutputs[\"questions\"][\"submit\"]>(\n await api(path`/questions/${batchId}/submit`, {\n method: \"POST\",\n body: { answers: collectAnswers(parsed) },\n }),\n \"POST /questions/{id}/submit\",\n { answeredCount: is.number },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n `${out.paint(\"✓\", \"green\")} Answered ${result.answeredCount} question(s); the session resumes.`,\n );\n return;\n }\n\n const result = await api<ApiOutputs[\"questions\"][\"cancel\"]>(\n path`/questions/${batchId}/cancel`,\n { method: \"POST\", body: {} },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n 'Round cancelled. The session stays parked — send a message to steer it: `hepha sessions send <id> \"…\"`',\n );\n}\n","export const POLL_SECONDS = 3;\n\nexport const PAGE_SIZE = 200;\n","import { out } from \"@/lib/output/out\";\n/** Sanitised first: transcript text is model, tool and repository output. */\nexport function truncate(text: string, max = 2000): string {\n const trimmed = out.safe(text).trim();\n return trimmed.length > max ? `${trimmed.slice(0, max)}…` : trimmed;\n}\n","import { out } from \"../output/out\";\nimport type { TranscriptEvent } from \"@/lib/event/transcript-event\";\nimport { truncate } from \"@/lib/truncate/truncate\";\n\n/**\n * One transcript event as one readable block.\n *\n * The transcript is the only honest account of what the agent did, so the\n * shapes that matter to a reviewer — tool calls, file changes, questions,\n * guardrails, errors — each keep a distinct marker instead of collapsing into\n * prose.\n */\nexport function formatEvent(event: TranscriptEvent): string | null {\n const part = event.part;\n\n switch (part.kind) {\n case \"text\":\n if (part.authorUserId) {\n return `${out.paint(\"you\", \"magenta\")} ${truncate(part.text)}`;\n }\n // Text with no author but a source was injected by the platform (an\n // integration trigger, an inbox event): the transcript contract says it\n // must never be attributed to the model.\n if (part.source) {\n return out.paint(`system ${truncate(part.text, 400)}`, \"dim\");\n }\n return `${out.paint(\"agent\", \"blue\")} ${truncate(part.text)}`;\n case \"reasoning\":\n return out.paint(`think ${truncate(part.text, 400)}`, \"dim\");\n case \"tool\":\n return `${out.paint(\"tool\", \"dim\")} ${out.cell(part.toolName)} ${out.paint(`(${part.status})`, \"dim\")}`;\n case \"file_change\":\n return `${out.paint(\"file\", \"dim\")} ${part.changeType.padEnd(8)} ${out.cell(part.path)}`;\n case \"question\":\n return out.paint(\n `ask question round ${part.questionBatchId} — answer with \\`hepha questions answer ${part.questionBatchId}\\``,\n \"yellow\",\n );\n // No CLI verb decides a plan: the accept/refuse pair lives in the app.\n case \"plan\":\n return out.paint(\n `plan plan ${part.planProposalId} awaits accept/refuse in the app`,\n \"yellow\",\n );\n case \"approval\":\n return out.paint(\n `gate guardrail ${part.guardrailRequestId} needs a human — \\`hepha approvals show ${part.guardrailRequestId}\\``,\n \"yellow\",\n );\n case \"media\": {\n // The signed URL is why this part exists: a screenshot or a recording is\n // the session's proof, and a reader who cannot open it has nothing.\n const target = part.url ?? part.pathname;\n return `${out.paint(\"media\", \"dim\")} ${part.mediaType}${part.caption ? ` — ${out.cell(part.caption)}` : \"\"}${target ? `\\n ${out.cell(target)}` : \"\"}`;\n }\n case \"error\":\n return out.paint(`error ${truncate(part.message)}`, \"red\");\n case \"external_event\":\n return `${out.paint(\"event\", \"dim\")} ${out.cell(part.title)}${part.conclusion ? ` — ${out.cell(part.conclusion)}` : \"\"}`;\n case \"system\":\n return out.paint(`system ${truncate(part.text, 300)}`, \"dim\");\n // The session's opening row: with the fenced prompt hidden, this is the\n // only place a CLI reader sees what the run was asked to do.\n case \"source_context\":\n return `${out.paint(\"source\", \"dim\")} ${out.cell(\n [part.reference, part.title].filter(Boolean).join(\" \"),\n )}${part.url ? ` — ${out.cell(part.url)}` : \"\"}${\n part.body ? `\\n ${truncate(part.body, 400)}` : \"\"\n }`;\n case \"verification\":\n return `${out.paint(\"check\", \"dim\")} ${out.cell(part.name)} ${out.paint(`(${part.status})`, \"dim\")}`;\n default:\n return null;\n }\n}\n","import { formatEvent } from \"@/lib/event/format-event\";\nimport { out } from \"@/lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\n\nexport function consumeSessionEvents(\n events: ApiOutputs[\"sessions\"][\"events\"][\"items\"],\n cursor: number,\n quiet: boolean | undefined,\n): number {\n for (const event of events) {\n cursor = Math.max(cursor, event.sequence);\n if (quiet) {\n continue;\n }\n const line = formatEvent(event);\n if (line) {\n out.line(line);\n }\n }\n return cursor;\n}\n","export function sleep(seconds: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, seconds * 1000));\n}\n","// setTimeout stores its delay in a signed 32-bit int and fires AT ONCE past it.\nexport const MAX_TIMER_MS = 2_147_483_647;\n","import { MAX_TIMER_MS } from \"./sleep-constants\";\n\n/** A wait a timer can actually hold: longer means \"as long as it can\". */\nexport function timerDelayMs(seconds: number): number {\n return Math.min(Math.max(0, seconds) * 1_000, MAX_TIMER_MS);\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport { timerDelayMs } from \"./timer-delay-ms\";\n\nexport function interruptibleSleep(seconds: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const onInterrupt = () => {\n clearTimeout(timer);\n reject(\n new CliError(\"Follow interrupted.\", 130, {\n code: CLI_ERROR_CODES.INTERRUPTED,\n }),\n );\n };\n const timer = setTimeout(() => {\n process.removeListener(\"SIGINT\", onInterrupt);\n resolve();\n }, timerDelayMs(seconds));\n process.once(\"SIGINT\", onInterrupt);\n });\n}\n","import { api } from \"@/lib/api/api\";\nimport { out } from \"@/lib/output/out\";\nimport { sleep } from \"@/lib/sleep/sleep\";\nimport { interruptibleSleep } from \"@/lib/sleep/interruptible-sleep\";\nimport type { FollowSessionDependencies } from \"./follow-session-dependencies\";\n\nexport const defaultFollowSessionDependencies: FollowSessionDependencies = {\n request: api,\n pollSleep: sleep,\n retrySleep: interruptibleSleep,\n random: Math.random,\n // Monotonic: an NTP step backwards must not hand the outage budget more time\n // to burn, nor mute the periodic reminder until the clock catches up.\n now: () => performance.now(),\n warn: (message) => out.warn(message),\n};\n","export function followOutageMessage(warned: boolean): string {\n return warned\n ? \"Hepha API still unavailable; retrying follow.\"\n : \"Hepha API unavailable; retrying follow.\";\n}\n","export const FOLLOW_RETRY_CAP_SECONDS = 22.5;\nexport const FOLLOW_OUTAGE_FEEDBACK_MS = 5 * 60 * 1_000;\n// The platform's own transient class, kept identical: see TRANSIENT_STATUS in\n// packages/tasks/src/lib/failure/classify/classify-harness-failure-constants.ts.\nexport const RETRYABLE_FOLLOW_STATUS = new Set([\n 408, 425, 429, 500, 502, 503, 504,\n]);\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { FOLLOW_RETRY_CAP_SECONDS } from \"./follow-retry-constants\";\n\nexport function followRetryDelay(\n error: CliError,\n failures: number,\n random: () => number,\n): number {\n const exponential = Math.min(\n FOLLOW_RETRY_CAP_SECONDS,\n 2 ** Math.min(failures - 1, 30),\n );\n const jittered = exponential / 2 + random() * (exponential / 2);\n // Retry-After is the server telling us when it will be ready: honoured whole,\n // and merely spread on top so followers do not wake as one.\n const retryAfter = Math.max(0, error.details.retryAfterSeconds ?? 0);\n return Math.max(jittered, retryAfter + random() * (exponential / 2));\n}\n","/** Infinity when no budget was set: the follow then waits any outage out. */\nexport function remainingOutageSeconds(\n outageStartedAt: number,\n now: number,\n maxOutageMs: number | null,\n): number {\n if (maxOutageMs === null) {\n return Number.POSITIVE_INFINITY;\n }\n return (maxOutageMs - (now - outageStartedAt)) / 1_000;\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\nimport { CLI_ERROR_CODES } from \"@/lib/shared/errors-constants\";\nimport { RETRYABLE_FOLLOW_STATUS } from \"./follow-retry-constants\";\n\nexport function retryableFollowError(error: unknown): error is CliError {\n return (\n error instanceof CliError &&\n (RETRYABLE_FOLLOW_STATUS.has(error.details.status ?? 0) ||\n error.details.code === CLI_ERROR_CODES.NETWORK ||\n error.details.code === CLI_ERROR_CODES.TIMEOUT)\n );\n}\n","import { FOLLOW_OUTAGE_FEEDBACK_MS } from \"./follow-retry-constants\";\n\nexport function shouldReportFollowOutage(\n lastWarnedAt: number | null,\n now: number,\n): boolean {\n return (\n lastWarnedAt === null || now - lastWarnedAt >= FOLLOW_OUTAGE_FEEDBACK_MS\n );\n}\n","import { nextPollDelay } from \"@/lib/retry/next-poll-delay\";\nimport type { FollowSessionDependencies } from \"../follow-session-dependencies\";\nimport { followOutageMessage } from \"./follow-outage-message\";\nimport { followRetryDelay } from \"./follow-retry-delay\";\nimport type { FollowRetryState } from \"./follow-retry-state\";\nimport { remainingOutageSeconds } from \"./remaining-outage-seconds\";\nimport { retryableFollowError } from \"./retryable-follow-error\";\nimport { shouldReportFollowOutage } from \"./should-report-follow-outage\";\n\n/** Wait out one failure, or rethrow the ones a follow cannot sit through. */\nexport async function waitForFollowRetry(params: {\n error: unknown;\n retry: FollowRetryState;\n maxOutageMs: number | null;\n dependencies: FollowSessionDependencies;\n}): Promise<void> {\n const { error, retry, dependencies } = params;\n if (!retryableFollowError(error)) {\n throw error;\n }\n retry.failures += 1;\n const now = dependencies.now();\n retry.outageStartedAt ??= now;\n // Unbudgeted, a follow waits any outage out; budgeted, the sleep stops at the\n // deadline and the last failure reaches the caller as its exit code.\n const delay = nextPollDelay(\n followRetryDelay(error, retry.failures, dependencies.random),\n remainingOutageSeconds(retry.outageStartedAt, now, params.maxOutageMs),\n );\n if (delay === null) {\n throw error;\n }\n if (shouldReportFollowOutage(retry.lastWarnedAt, now)) {\n dependencies.warn(followOutageMessage(retry.warned));\n retry.warned = true;\n retry.lastWarnedAt = now;\n }\n await dependencies.retrySleep(delay);\n // Waking up on the deadline itself: fail with the real failure rather than\n // spend the caller's last millisecond on a request that cannot land.\n if (\n remainingOutageSeconds(\n retry.outageStartedAt,\n dependencies.now(),\n params.maxOutageMs,\n ) <= 0\n ) {\n throw error;\n }\n}\n","import type { FollowSessionDependencies } from \"../follow-session-dependencies\";\nimport type { FollowRetryState } from \"./follow-retry-state\";\nimport { waitForFollowRetry } from \"./wait-for-follow-retry\";\n\nexport async function requestWithFollowRetry<T>(params: {\n operation: () => Promise<T>;\n retry: FollowRetryState;\n maxOutageMs: number | null;\n dependencies: FollowSessionDependencies;\n}): Promise<T> {\n for (;;) {\n try {\n const result = await params.operation();\n if (params.retry.warned) {\n params.dependencies.warn(\"Hepha API recovered; continuing follow.\");\n }\n params.retry.failures = 0;\n params.retry.warned = false;\n params.retry.lastWarnedAt = null;\n params.retry.outageStartedAt = null;\n return result;\n } catch (error) {\n await waitForFollowRetry({\n error,\n retry: params.retry,\n maxOutageMs: params.maxOutageMs,\n dependencies: params.dependencies,\n });\n }\n }\n}\n","export const BLOCKED = new Set([\"waiting_human\", \"awaiting_approval\"]);\n","export const TERMINAL = new Set([\"completed\", \"failed\", \"killed\", \"abstained\"]);\n","import { BLOCKED } from \"@/lib/blocked/blocked-constants\";\nimport { TERMINAL } from \"@/lib/terminal/terminal-constants\";\n\n// Undefined is a deployment too old to report the status on an events page.\nexport function isFollowStopStatus(status: string | undefined): boolean {\n return status !== undefined && (TERMINAL.has(status) || BLOCKED.has(status));\n}\n","import { CliError } from \"@/lib/cli/cli-error\";\n\n/** Unset means forever: only a caller with no Ctrl-C needs an exit code. */\nexport function resolveFollowOutageBudget(): number | null {\n const raw = process.env.HEPHA_FOLLOW_MAX_OUTAGE_SECONDS?.trim();\n if (!raw) {\n return null;\n }\n // Checked in milliseconds: a finite 1e306 seconds overflows to an Infinity\n // budget, which would silently never expire.\n const budgetMs = Number(raw) * 1_000;\n if (!Number.isFinite(budgetMs) || budgetMs <= 0) {\n throw new CliError(\n `HEPHA_FOLLOW_MAX_OUTAGE_SECONDS expects a positive number of seconds, got \"${raw}\".`,\n 2,\n );\n }\n return budgetMs;\n}\n","import { resolveTimeout } from \"@/lib/timeout/resolve-timeout\";\nimport type { FollowRetryState } from \"./follow-retry-state\";\nimport { remainingOutageSeconds } from \"./remaining-outage-seconds\";\n\n/** A request may not outlive the outage budget it is being retried under. */\nexport function followRequestTimeoutMs(\n retry: FollowRetryState,\n maxOutageMs: number | null,\n now: number,\n): number {\n if (retry.outageStartedAt === null) {\n return resolveTimeout();\n }\n const remainingMs =\n remainingOutageSeconds(retry.outageStartedAt, now, maxOutageMs) * 1_000;\n return Math.max(1, Math.min(resolveTimeout(), remainingMs));\n}\n","import { path } from \"../path/path\";\nimport { expectShape } from \"../expect/expect-shape\";\nimport { is } from \"../is/is\";\nimport { POLL_SECONDS, PAGE_SIZE } from \"@/lib/follow/follow-constants\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\nimport { consumeSessionEvents } from \"@/lib/session/consume-session-events\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { FollowRetryState } from \"@/lib/session/retry/follow-retry-state\";\nimport type { FollowSessionDependencies } from \"@/lib/session/follow-session-dependencies\";\nimport { defaultFollowSessionDependencies } from \"@/lib/session/default-follow-session-dependencies\";\nimport { requestWithFollowRetry } from \"@/lib/session/retry/request-with-follow-retry\";\nimport { isFollowStopStatus } from \"@/lib/session/is-follow-stop-status\";\nimport { resolveFollowOutageBudget } from \"@/lib/session/retry/resolve-follow-outage-budget\";\nimport { followRequestTimeoutMs } from \"@/lib/session/retry/follow-request-timeout-ms\";\n\n/**\n * Follow a session until it finishes or needs a person.\n *\n * Stopping on `waiting_human` / `awaiting_approval` is the important part: the\n * agent parks there and burns nothing, so a follower that kept waiting would\n * hang forever. The caller turns that into a distinct exit code, which is what\n * lets an orchestrating agent branch on \"it asked me something\".\n */\nexport async function followSession(\n sessionId: string,\n options: { quiet?: boolean; after?: number } = {},\n dependencies: FollowSessionDependencies = defaultFollowSessionDependencies,\n): Promise<SessionDetail> {\n // Resuming a follow starts where the caller left off, so `--after` does not\n // replay (and reprint) the whole transcript.\n let cursor = options.after ?? 0;\n let emptyPolls = 0;\n const retry: FollowRetryState = {\n failures: 0,\n warned: false,\n lastWarnedAt: null,\n outageStartedAt: null,\n };\n const maxOutageMs = resolveFollowOutageBudget();\n\n for (;;) {\n const page = await requestWithFollowRetry({\n retry,\n maxOutageMs,\n dependencies,\n operation: async () =>\n expectShape<\n Omit<ApiOutputs[\"sessions\"][\"events\"], \"status\"> & { status?: string }\n >(\n await dependencies.request(path`/sessions/${sessionId}/events`, {\n query: { after: cursor || undefined, limit: PAGE_SIZE },\n timeoutMs: followRequestTimeoutMs(\n retry,\n maxOutageMs,\n dependencies.now(),\n ),\n }),\n \"GET /sessions/{id}/events\",\n {\n items: is.array,\n hasMore: (value) => typeof value === \"boolean\",\n nextCursor: (value) => value === null || is.number(value),\n // Optional: a deployment older than this binary omits it, and a\n // missing field here would be a non-retryable schema mismatch.\n status: is.optionalString,\n },\n ),\n });\n\n cursor = consumeSessionEvents(page.items, cursor, options.quiet);\n\n // Advance on the SERVER's cursor, not on what we could render. The API\n // paginates raw rows and drops the ones with no transcript representation,\n // so a page can come back empty with hasMore true — following the items\n // alone would re-request the same page forever, without even sleeping.\n if (page.nextCursor !== null) {\n cursor = Math.max(cursor, page.nextCursor);\n }\n\n if (page.hasMore) {\n continue;\n }\n\n emptyPolls = page.items.length === 0 ? emptyPolls + 1 : 0;\n if (\n isFollowStopStatus(page.status) ||\n page.items.length > 0 ||\n emptyPolls >= 3\n ) {\n const session = await requestWithFollowRetry({\n retry,\n maxOutageMs,\n dependencies,\n operation: async () =>\n expectShape<SessionDetail>(\n await dependencies.request(path`/sessions/${sessionId}`, {\n timeoutMs: followRequestTimeoutMs(\n retry,\n maxOutageMs,\n dependencies.now(),\n ),\n }),\n \"GET /sessions/{id}\",\n { status: is.string },\n ),\n });\n emptyPolls = 0;\n if (isFollowStopStatus(session.status)) {\n return session;\n }\n }\n\n await dependencies.pollSleep(POLL_SECONDS);\n }\n}\n","import { out } from \"@/lib/output/out\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\n\nexport function buildSessionDetailRows(session: SessionDetail): string[][] {\n const rows: string[][] = [[\"id\", out.cell(session.id)]];\n if (session.statusReason) {\n rows.push([\"reason\", out.cell(session.statusReason)]);\n }\n if (session.repoFullName) {\n const branch = session.repos.find(\n (repo) => repo.repoFullName === session.repoFullName,\n )?.branch;\n rows.push([\n \"repo\",\n out.cell(session.repoFullName + (branch ? ` @ ${branch}` : \"\")),\n ]);\n }\n rows.push([\"task\", session.taskType]);\n if (session.model) {\n rows.push([\"model\", out.cell(session.model)]);\n }\n if (session.prUrl) {\n rows.push([\n \"pr\",\n out.cell(\n `${session.prUrl}${session.prState ? ` (${session.prState})` : \"\"}`,\n ),\n ]);\n }\n for (const deliverable of session.deliverables) {\n if (deliverable.url && deliverable.url !== session.prUrl) {\n rows.push([out.cell(deliverable.type), out.cell(deliverable.url)]);\n }\n }\n return rows;\n}\n","import { out } from \"@/lib/output/out\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\n\nexport function printPlaybookSteps(\n steps: NonNullable<SessionDetail[\"playbook\"]>[\"steps\"],\n): void {\n if (steps.length === 0) {\n return;\n }\n out.line();\n for (const step of steps) {\n const done = step.todos.filter(\n (todo) => todo.status === \"completed\",\n ).length;\n const marker =\n done === step.todos.length && step.todos.length > 0 ? \"✓\" : \"·\";\n out.line(\n ` ${marker} ${out.cell(step.title)} ${out.paint(`${done}/${step.todos.length}`, \"dim\")}`,\n );\n }\n}\n","import { out } from \"../output/out\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\nimport { buildSessionDetailRows } from \"@/lib/session/build-session-detail-rows\";\nimport { printPlaybookSteps } from \"@/lib/session/print-playbook-steps\";\n\n/** The single-session view shared by `get`, `run` and every control command. */\nexport function printSession(session: SessionDetail): void {\n // Titles, reasons, URLs and step names are agent-authored: sanitise before\n // they reach a terminal (see out.safe).\n out.line(\n `${out.paint(out.cell(session.title), \"bold\")} ${out.status(session.status)}`,\n );\n\n const rows = buildSessionDetailRows(session);\n\n out.table(\n rows.map(([label, value]) => [out.paint(label ?? \"\", \"dim\"), value ?? \"\"]),\n );\n\n printPlaybookSteps(session.playbook?.steps ?? []);\n}\n","import { CliError } from \"../cli/cli-error\";\nimport type { SessionDetail } from \"@/lib/session/session-detail\";\n\n/**\n * What a followed session means for the caller's exit code.\n *\n * `followSession` returns on two very different conditions — the work is over,\n * or it needs a person — and both `run --follow` and `sessions logs --follow`\n * have to tell them apart the same way. Returns null when the session\n * completed (exit 0), a CliError carrying 3 when a human is needed, and 1 for\n * a real failure. The session rides on the error so `--json` can emit one\n * document holding both the outcome and what it applies to.\n */\nexport function sessionOutcome(session: SessionDetail): CliError | null {\n switch (session.status) {\n case \"completed\":\n return null;\n case \"waiting_human\":\n return new CliError(\n `Waiting on an answer — \\`hepha questions list --session ${session.id}\\``,\n 3,\n {},\n session,\n );\n case \"awaiting_approval\":\n return new CliError(\n \"Waiting on a guardrail approval — `hepha approvals list`\",\n 3,\n {},\n session,\n );\n default:\n return new CliError(\n `Session ended ${session.status}${session.statusReason ? `: ${session.statusReason}` : \".\"}`,\n 1,\n {},\n session,\n );\n }\n}\n","import { out } from \"../output/out\";\nimport { printSession } from \"./print-session\";\nimport { sessionOutcome } from \"./session-outcome\";\nimport type { SessionDetail } from \"./session-detail\";\n\nexport function writeFollowedSessionOutcome(\n session: SessionDetail,\n asJson: boolean,\n): void {\n const outcome = sessionOutcome(session);\n\n if (asJson) {\n if (!outcome) out.json(session);\n } else {\n out.line();\n printSession(session);\n }\n\n if (outcome) throw outcome;\n}\n","import type { CreateInput } from \"@/commands/create/create-input\";\nexport const HARNESSES = [\n \"claude-code\",\n \"codex\",\n \"cursor\",\n] as const satisfies readonly NonNullable<CreateInput[\"harnessPin\"]>[];\n","import type { CreateInput } from \"@/commands/create/create-input\";\n/**\n * Validated locally so a typo names itself, instead of travelling to the API\n * and coming back as a bare \"Input validation failed\" that says nothing about\n * which flag was wrong.\n *\n * `satisfies` against the router's own input type is what keeps these lists\n * honest: adding a task type server-side without updating this one is a\n * `types:check` failure, not a CLI that quietly refuses a valid value.\n */\nexport const TASK_TYPES = [\n \"implement\",\n \"new-project\",\n \"question\",\n \"draft\",\n \"orchestrator\",\n] as const satisfies readonly NonNullable<CreateInput[\"taskType\"]>[];\n","import { args } from \"@/lib/args/args\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nimport type { CreateInput } from \"@/commands/create/create-input\";\nimport { HARNESSES } from \"@/commands/harnesses/harnesses-constants\";\nimport { TASK_TYPES } from \"@/commands/task/task-types-constants\";\n\nexport function createRunInput(\n parsed: ParsedArgs,\n prompt: string,\n): CreateInput {\n const taskType = args.choice(parsed, \"task-type\", TASK_TYPES);\n const harness = args.choice(parsed, \"harness\", HARNESSES);\n\n return {\n prompt,\n ...(parsed.flags.title ? { title: parsed.flags.title } : {}),\n ...(taskType ? { taskType } : {}),\n ...(parsed.flags.model ? { modelSelection: parsed.flags.model } : {}),\n ...(harness ? { harnessPin: harness } : {}),\n ...(parsed.flags.repo ? { repoFullName: parsed.flags.repo } : {}),\n ...(parsed.flags.branch ? { branch: parsed.flags.branch } : {}),\n ...(parsed.repeated.skill ? { pinnedSkillIds: parsed.repeated.skill } : {}),\n };\n}\n","import { api } from \"../../lib/api/api\";\nimport { args } from \"../../lib/args/args\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { followSession } from \"../../lib/session/follow-session\";\nimport { out } from \"../../lib/output/out\";\nimport { printSession } from \"../../lib/session/print-session\";\nimport { writeFollowedSessionOutcome } from \"../../lib/session/write-followed-session-outcome\";\nimport { createRunInput } from \"@/commands/command/create-run-input\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * Exit code carries the outcome — 0 done, 3 waiting on a human, 1 failed — so\n * a caller can drive the loop without parsing text.\n */\nexport async function runCommand(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {\n flags: [\n \"title\",\n \"task-type\",\n \"model\",\n \"harness\",\n \"repo\",\n \"branch\",\n \"skill\",\n ],\n booleans: [\"follow\"],\n positional: 1,\n });\n\n const prompt = args.required(parsed, 0, \"prompt\");\n const asJson = parsed.booleans.has(\"json\");\n const body = createRunInput(parsed, prompt);\n\n const session = expectShape<ApiOutputs[\"sessions\"][\"create\"]>(\n await api(\"/sessions\", { method: \"POST\", body }),\n \"POST /sessions\",\n { id: is.string, title: is.string, status: is.string },\n );\n\n if (!parsed.booleans.has(\"follow\")) {\n if (asJson) {\n out.json(session);\n return;\n }\n printSession(session);\n out.line();\n out.line(out.paint(` hepha sessions logs ${session.id} --follow`, \"dim\"));\n return;\n }\n\n const quiet = asJson || parsed.booleans.has(\"quiet\");\n\n if (!quiet) {\n out.line(out.paint(`session ${session.id}`, \"dim\"));\n out.line();\n }\n\n const final = await followSession(session.id, { quiet });\n writeFollowedSessionOutcome(final, asJson);\n}\n","import { is } from \"@/lib/is/is\";\n\nexport const ACTIONS = [\n \"list\",\n \"get\",\n \"logs\",\n \"send\",\n \"pause\",\n \"resume\",\n \"kill\",\n \"archive\",\n \"checks\",\n \"pr\",\n \"verify\",\n] as const;\n\nexport const CONTROL_PATHS: Record<string, string> = {\n pause: \"pause\",\n resume: \"resume\",\n kill: \"kill\",\n archive: \"archive\",\n};\n\nexport const STATUS_GROUPS = [\"active\", \"waiting\", \"done\"] as const;\n\nexport const SESSION_FIELDS = {\n id: is.string,\n title: is.string,\n status: is.string,\n taskType: is.string,\n repos: is.array,\n deliverables: is.array,\n};\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport { STATUS_GROUPS } from \"@/commands/sessions/sessions-constants\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nexport async function listSessions(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {\n flags: [\"status\", \"repo\", \"search\", \"page\", \"limit\"],\n booleans: [\"all\"],\n positional: 1,\n });\n\n const result = expectShape<ApiOutputs[\"sessions\"][\"list\"]>(\n await api(\"/sessions\", {\n query: {\n statusGroup: args.choice(parsed, \"status\", STATUS_GROUPS),\n repoFullName: parsed.flags.repo,\n search: parsed.flags.search,\n page: args.integer(parsed, \"page\", { min: 1 }),\n limit: args.integer(parsed, \"limit\", { min: 1, max: 100 }),\n scope: parsed.booleans.has(\"all\") ? \"all\" : undefined,\n },\n }),\n \"GET /sessions\",\n { data: is.array, \"pagination.page\": is.number },\n );\n\n if (parsed.booleans.has(\"json\")) {\n out.json(result);\n return;\n }\n\n if (result.data.length === 0) {\n out.line(\"No sessions.\");\n return;\n }\n\n if (result.pagination.hasNextPage) {\n out.line(\n out.paint(\n `page ${result.pagination.page}/${result.pagination.totalPages} — --page ${result.pagination.page + 1} for more`,\n \"dim\",\n ),\n );\n out.line();\n }\n\n out.table(\n result.data.map((session) => [\n out.cell(session.id),\n out.status(session.status),\n out.cell(session.repoFullName ?? \"—\"),\n out.cell(session.title),\n ]),\n );\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { out } from \"@/lib/output/out\";\nimport { path } from \"@/lib/path/path\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function sendSessionMessage(\n parsed: ParsedArgs,\n asJson: boolean,\n): Promise<void> {\n args.expect(parsed, { positional: 3 });\n const sessionId = args.required(parsed, 1, \"sessionId\");\n const message = args.required(parsed, 2, \"message\");\n const result = expectShape<ApiOutputs[\"sessions\"][\"sendMessage\"]>(\n await api(path`/sessions/${sessionId}/messages`, {\n method: \"POST\",\n body: { message },\n }),\n \"POST /sessions/{id}/messages\",\n { delivery: is.string },\n );\n if (asJson) {\n out.json(result);\n return;\n }\n out.line(\n result.delivery === \"interrupt\"\n ? \"Delivered to the running agent.\"\n : \"Queued — the agent picks it up at the end of its turn.\",\n );\n}\n","import type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nimport { followSession } from \"@/lib/session/follow-session\";\nimport { writeFollowedSessionOutcome } from \"@/lib/session/write-followed-session-outcome\";\n\nexport async function followSessionLogs(\n parsed: ParsedArgs,\n sessionId: string,\n after: number | undefined,\n asJson: boolean,\n): Promise<void> {\n // JSON mode suppresses the transcript so stdout remains one document.\n const session = await followSession(sessionId, {\n quiet: asJson || parsed.booleans.has(\"quiet\"),\n ...(after !== undefined ? { after } : {}),\n });\n writeFollowedSessionOutcome(session, asJson);\n}\n","import { api } from \"@/lib/api/api\";\nimport { path } from \"@/lib/path/path\";\nimport { args } from \"@/lib/args/args\";\nimport { expectShape } from \"@/lib/expect/expect-shape\";\nimport { is } from \"@/lib/is/is\";\nimport { formatEvent } from \"@/lib/event/format-event\";\nimport { out } from \"@/lib/output/out\";\nimport { followSessionLogs } from \"@/commands/show/follow-session-logs\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\nexport async function showLogs(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {\n flags: [\"after\", \"limit\"],\n booleans: [\"follow\"],\n positional: 2,\n });\n\n const sessionId = args.required(parsed, 1, \"sessionId\");\n const asJson = parsed.booleans.has(\"json\");\n const after = args.integer(parsed, \"after\", { min: 0 });\n\n if (parsed.booleans.has(\"follow\")) {\n await followSessionLogs(parsed, sessionId, after, asJson);\n return;\n }\n\n const page = expectShape<ApiOutputs[\"sessions\"][\"events\"]>(\n await api(path`/sessions/${sessionId}/events`, {\n query: {\n after,\n limit: args.integer(parsed, \"limit\", { min: 1, max: 200 }),\n },\n }),\n \"GET /sessions/{id}/events\",\n { items: is.array },\n );\n\n if (asJson) {\n out.json(page);\n return;\n }\n\n for (const event of page.items) {\n const line = formatEvent(event);\n if (line) {\n out.line(line);\n }\n }\n\n // Never let a truncated transcript look complete. Formatted events do not\n // carry their sequence, so the continuation cursor has to be spelled out.\n if (page.hasMore && page.nextCursor !== null) {\n out.line();\n out.line(\n out.paint(\n `more events — hepha sessions logs ${sessionId} --after ${page.nextCursor}`,\n \"dim\",\n ),\n );\n }\n}\n","import { listSessions } from \"@/commands/sessions/list-sessions\";\nimport { sendSessionMessage } from \"@/commands/session/send-session-message\";\nimport { showLogs } from \"@/commands/show/show-logs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\n/**\n * The session actions with their own command. Anything absent here is a\n * per-session operation and goes through `runSessionOperation`, which resolves\n * the session id first.\n */\nexport const sessionActions: Record<\n string,\n (parsed: ParsedArgs, asJson: boolean) => Promise<void>\n> = {\n list: (parsed) => listSessions(parsed),\n logs: (parsed) => showLogs(parsed),\n send: sendSessionMessage,\n};\n","import { expectShape } from \"@/lib/expect/expect-shape\";\nimport { SESSION_FIELDS } from \"@/commands/sessions/sessions-constants\";\nimport type { SessionDetail } from \"@/commands/session/session-detail\";\nexport function detail(payload: unknown, endpoint: string): SessionDetail {\n return expectShape<SessionDetail>(payload, endpoint, SESSION_FIELDS);\n}\n","import { api } from \"@/lib/api/api\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { path } from \"@/lib/path/path\";\nimport { out } from \"@/lib/output/out\";\nimport { printSession } from \"@/lib/session/print-session\";\nimport { detail } from \"@/commands/detail/detail\";\nimport { CONTROL_PATHS } from \"@/commands/sessions/sessions-constants\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function runSessionControlAction(\n parsed: ParsedArgs,\n action: string,\n sessionId: string,\n asJson: boolean,\n): Promise<void> {\n const controlPath = CONTROL_PATHS[action];\n if (controlPath === undefined) {\n throw new CliError(`Unknown session action: ${action}`, 2);\n }\n const session = detail(\n await api(path`/sessions/${sessionId}/${controlPath}`, {\n method: \"POST\",\n body:\n action === \"kill\" && parsed.flags.reason\n ? { reason: parsed.flags.reason }\n : {},\n }),\n `POST /sessions/{id}/${controlPath}`,\n );\n if (asJson) {\n out.json(session);\n return;\n }\n printSession(session);\n}\n","import { api } from \"@/lib/api/api\";\nimport { args } from \"@/lib/args/args\";\nimport { path } from \"@/lib/path/path\";\nimport { out } from \"@/lib/output/out\";\nimport { printSession } from \"@/lib/session/print-session\";\nimport { runSessionControlAction } from \"@/commands/command/run-session-control-action\";\nimport { detail } from \"@/commands/detail/detail\";\nimport { CONTROL_PATHS } from \"@/commands/sessions/sessions-constants\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function runSessionOperation(\n parsed: ParsedArgs,\n action: string,\n asJson: boolean,\n): Promise<void> {\n // Only kill consumes --reason; the other operations must reject it.\n args.expect(parsed, {\n positional: 2,\n ...(action === \"kill\" ? { flags: [\"reason\"] } : {}),\n });\n\n const sessionId = args.required(parsed, 1, \"sessionId\");\n\n if (action === \"get\") {\n const session = detail(\n await api(path`/sessions/${sessionId}`),\n \"GET /sessions/{id}\",\n );\n if (asJson) {\n out.json(session);\n return;\n }\n printSession(session);\n return;\n }\n\n // Avoid inherited keys such as `toString` becoming control paths.\n if (Object.hasOwn(CONTROL_PATHS, action)) {\n await runSessionControlAction(parsed, action, sessionId, asJson);\n return;\n }\n\n if (action === \"checks\") {\n out.json(\n await api<ApiOutputs[\"sessions\"][\"runChecks\"]>(\n path`/sessions/${sessionId}/checks`,\n { method: \"POST\", body: {} },\n ),\n );\n return;\n }\n\n if (action === \"pr\") {\n out.json(\n await api<ApiOutputs[\"sessions\"][\"prChecks\"]>(\n path`/sessions/${sessionId}/pr-checks`,\n ),\n );\n return;\n }\n\n out.json(\n await api<ApiOutputs[\"sessions\"][\"verification\"]>(\n path`/sessions/${sessionId}/verification`,\n ),\n );\n}\n","import { args } from \"../../lib/args/args\";\nimport { ACTIONS } from \"@/commands/sessions/sessions-constants\";\nimport { sessionActions } from \"@/commands/sessions/session-actions\";\nimport { runSessionOperation } from \"@/commands/command/run-session-operation\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function sessionsCommand(parsed: ParsedArgs): Promise<void> {\n // The action is validated FIRST, so `hepha sessions frobnicate <id>` names\n // the real problem instead of asking for an argument it would never use.\n const action = args.action(parsed, \"sessions\", ACTIONS, \"list\");\n const asJson = parsed.booleans.has(\"json\");\n\n const dedicated = sessionActions[action];\n if (dedicated) {\n return await dedicated(parsed, asJson);\n }\n await runSessionOperation(parsed, action, asJson);\n}\n","import { api } from \"../../lib/api/api\";\nimport { args } from \"../../lib/args/args\";\nimport { config } from \"../../lib/shared/config\";\nimport { expectShape } from \"../../lib/expect/expect-shape\";\nimport { is } from \"../../lib/is/is\";\nimport { out } from \"../../lib/output/out\";\nimport type { ApiOutputs } from \"@/lib/api/api-outputs\";\nimport type { ParsedArgs } from \"@/lib/parsed/parsed-args\";\n\nexport async function whoamiCommand(parsed: ParsedArgs): Promise<void> {\n args.expect(parsed, {});\n\n const identity = expectShape<ApiOutputs[\"me\"][\"get\"]>(\n await api(\"/me\"),\n \"GET /me\",\n {\n \"user.name\": is.string,\n \"user.email\": is.string,\n \"auth.method\": is.string,\n \"auth.scopes\": is.array,\n },\n );\n\n if (parsed.booleans.has(\"json\")) {\n out.json(identity);\n return;\n }\n\n out.table([\n [\n out.paint(\"user\", \"dim\"),\n out.cell(`${identity.user.name} <${identity.user.email}>`),\n ],\n [out.paint(\"role\", \"dim\"), out.cell(identity.user.role ?? \"member\")],\n [\n out.paint(\"auth\", \"dim\"),\n out.cell(\n identity.auth.method === \"api_key\"\n ? `api key${identity.auth.keyName ? ` \"${identity.auth.keyName}\"` : \"\"}`\n : \"session\",\n ),\n ],\n [out.paint(\"scopes\", \"dim\"), identity.auth.scopes.join(\" \")],\n [out.paint(\"url\", \"dim\"), config.load().baseUrl],\n ]);\n}\n","export const CATALOG_TOPICS = new Set([\n \"repos\",\n \"branches\",\n \"models\",\n \"skills\",\n]);\n","import { approvalsCommand } from \"@/commands/command/approvals-command\";\nimport { catalogCommand } from \"@/commands/command/catalog-command\";\nimport { helpCommand } from \"@/commands/command/help-command\";\nimport { keysCommand } from \"@/commands/command/keys-command\";\nimport { loginCommand } from \"@/commands/command/login-command\";\nimport { logoutCommand } from \"@/commands/command/logout-command\";\nimport { questionsCommand } from \"@/commands/command/questions-command\";\nimport { runCommand } from \"@/commands/command/run-command\";\nimport { sessionsCommand } from \"@/commands/command/sessions-command\";\nimport { whoamiCommand } from \"@/commands/command/whoami-command\";\nimport { args } from \"@/lib/args/args\";\nimport { CliError } from \"@/lib/cli/cli-error\";\nimport { CATALOG_TOPICS } from \"@/catalog-topics-constants\";\nexport async function dispatch(command: string, argv: string[]): Promise<void> {\n const parsed = args.parse(argv);\n\n if (parsed.booleans.has(\"help\")) {\n helpCommand();\n return;\n }\n\n if (CATALOG_TOPICS.has(command)) {\n return await catalogCommand(command, parsed);\n }\n\n switch (command) {\n case \"login\":\n return await loginCommand(parsed);\n case \"logout\":\n return logoutCommand(parsed);\n case \"whoami\":\n return await whoamiCommand(parsed);\n case \"keys\":\n return await keysCommand(parsed);\n case \"run\":\n return await runCommand(parsed);\n case \"sessions\":\n return await sessionsCommand(parsed);\n case \"questions\":\n return await questionsCommand(parsed);\n case \"approvals\":\n return await approvalsCommand(parsed);\n default:\n helpCommand();\n throw new CliError(`Unknown command \"${command}\".`, 2);\n }\n}\n","import { helpCommand } from \"@/commands/command/help-command\";\nimport { args } from \"@/lib/args/args\";\nimport { out } from \"@/lib/output/out\";\nimport { VERSION } from \"@/lib/version/version-constants\";\nimport { wantsJson } from \"@/lib/wants/wants-json\";\nimport { dispatch } from \"@/dispatch\";\nexport async function main(): Promise<void> {\n const argv = process.argv.slice(2);\n out.setJson(wantsJson(argv));\n\n const [command, ...rest] = argv;\n\n if (!command || command === \"help\" || command === \"--help\") {\n helpCommand();\n return;\n }\n\n // Answered early, but NOT before the arguments are checked: returning ahead\n // of the parser would exempt this command from the strictness every other one\n // applies.\n if (command === \"--version\" || command === \"-v\" || command === \"version\") {\n args.expect(args.parse(rest), {});\n if (out.isJson()) {\n out.json({ version: VERSION });\n } else {\n out.line(VERSION);\n }\n return;\n }\n\n await dispatch(command, rest);\n}\n","import { CliError } from \"./lib/cli/cli-error\";\nimport { out } from \"./lib/output/out\";\nimport { main } from \"@/main\";\n\nexport async function cliEntry() {\n try {\n await main();\n } catch (error: unknown) {\n const failure =\n error instanceof CliError\n ? error\n : new CliError(error instanceof Error ? error.message : String(error));\n\n out.failure(failure);\n process.exit(failure.exitCode);\n }\n}\n\nvoid cliEntry();\n"],"mappings":"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","names":["readFileSync","dirname","join","detail","result","path","ACTIONS","ACTIONS","result","ACTIONS","ACTIONS","result","sleep","sleep","ACTIONS","ACTIONS"]}
|