import type { ManagedWorktree, NodeMeta, NodeRow, SubscriptionRef } from '../../core/canvas/types.js'; import type { HumanWorkRow } from '../../core/canvas/human-work-outbox.js'; import type { Cron, CronRunRecord } from '../../core/canvas/crons.js'; import type { ProfileEntry } from '../../core/profiles/manifest.js'; import type { ReviveResult } from '../../core/runtime/revive.js'; import type { CloseNodeResult } from '../../core/runtime/close.js'; import { type PushResult } from '../../core/feed/feed.js'; import type { CloseResultDTO, ConsultOutboxEntryDTO, CronDTO, CronRunDTO, ErrorBody, NodeEdgesDTO, NodePathsDTO, NodeStatusDTO, NodeSummaryDTO, NodeDetailDTO, NodeWorktreeDTO, ProfileDTO, PushReportResultDTO, ReviveResultDTO, SubscriptionDTO } from '../../api/index.js'; /** Project the queryable row (what `listNodes` yields) into a summary DTO. */ export declare function toNodeSummaryDTO(row: NodeRow): NodeSummaryDTO; /** The subscription/child edges a detail projection needs. The handler gathers * these from `subscriptionsOf`/`subscribersOf` + a children query and passes * them in, so this module stays a pure projection with no db reach. */ export interface NodeEdgesInput { /** Publishers this node subscribes to (`subscriptionsOf(id)`). */ subscribesTo: readonly SubscriptionRef[]; /** Subscribers to this node's output — its managers (`subscribersOf(id)`). */ subscribers: readonly SubscriptionRef[]; /** Node ids this node spawned (children). */ children: readonly string[]; } /** Project a node's spine + subscription edges (absorbs `managers`/`paths`). */ export declare function toNodeEdgesDTO(meta: NodeMeta, edges: NodeEdgesInput): NodeEdgesDTO; /** Absolute filesystem paths for a node (absorbs the `paths` read). Pure — the * `core/canvas/paths.ts` helpers are string constructors, not db reach. */ export declare function toNodePathsDTO(nodeId: string): NodePathsDTO; /** Project a node's managed git worktree, if any. */ export declare function toNodeWorktreeDTO(w: ManagedWorktree): NodeWorktreeDTO; /** Project the hydrated node view (`getNode` → `NodeMeta`) into a detail DTO. * The summary fields come from the meta's runtime half (hydrated from the * authoritative row); the identity extras (description/cycles/session) come * from the meta's identity half. Edges are gathered by the handler. */ export declare function toNodeDetailDTO(meta: NodeMeta, edges: NodeEdgesInput): NodeDetailDTO; /** Project a `reviveNode` result. `revived` is true only when a fresh launch * actually happened — the double-revive no-op (already-alive) returns without a * `launch` handle, so its absence is the "nothing relaunched" signal. `status` * is the caller's post-revive row read. */ export declare function toReviveResultDTO(nodeId: string, result: ReviveResult, status: NodeStatusDTO): ReviveResultDTO; /** Project a `closeNode` cascade result. Field names align 1:1. */ export declare function toCloseResultDTO(result: CloseNodeResult): CloseResultDTO; /** Project a feed `push` result into a push-report result. `transitioned` is * supplied by the handler only for a `final` push (the server-side lifecycle * flip); an update/urgent push omits it. */ export declare function toReportResultDTO(result: PushResult, transitioned?: { from: string; to: string; }, autoDroppedWorktreePath?: string): PushReportResultDTO; /** Project a subscription ref as seen from one endpoint. */ export declare function toSubscriptionDTO(ref: SubscriptionRef): SubscriptionDTO; /** Project a cron row into its DTO — a straight column projection minus the * internal lease plumbing (run_pid/run_lease_owner/env_json/last_output_hash/ * queued stay server-side); the sink JSON is rendered back to its display * spec. `lastRun` is the most recent settled run — the recent health every * cron projection carries so `cron list` needs no `cron show` per row. */ export declare function toCronDTO(c: Cron, lastRun?: CronRunRecord | null): CronDTO; /** Project one settled run-log record into its DTO — a straight projection * minus the redundant cron_id (the route already names the cron). */ export declare function toCronRunDTO(r: CronRunRecord): CronRunDTO; /** Project a profile-manifest entry into its DTO. `default_dir` (the directory * this profile is pinned as default for) is a reverse lookup not carried on the * entry, so it is left null here — a caller that needs it resolves it * separately. */ export declare function toProfileDTO(entry: ProfileEntry): ProfileDTO; /** Project a `consult_outbox` (human-work) row into a consult-outbox entry DTO * (the canvas half of a human consult/visual request). `work_kind` is the same * `'follow_up' | 'visual'` union as `ConsultKindDTO`; `created` carries the * row's last-touch timestamp (the table has no separate creation column). */ export declare function toConsultOutboxEntryDTO(row: HumanWorkRow): ConsultOutboxEntryDTO; /** The single error-mapping function (spec §8). Projects any thrown value into * `{ status, code }`: * - a CrtrError → status by its `exitCode` class, `code` its machine code; * - a feed `FinalizationError` → 409 `already_finalized` / * `finalization_forbidden`, or 404 `node_not_found`; * - a `NodeIdConflictError` (a `--node-id`/`node_id` spawn at an id that * already exists) → 409 `node_id_exists`; * - `reviveNode`'s finalization-latch throw → 409 `already_finalized`; * - an "unknown node" throw (reviveNode / transition / getNode-null handler) → * 404 `node_not_found`; * - a `transition` illegal-move throw → 409 `illegal_transition`; * - anything already carrying a numeric `status` + string `code` (an * `ApiError`-shaped throw) → used verbatim; * - anything else → 500 `internal`. * The recognized plain-`Error` cases match on the throw sites' messages (the * only signal those sites carry); the source sites are named above so a message * change there is caught by the A-11 tests. */ export declare function errorToStatus(err: unknown): { status: number; code: string; }; /** Build the uniform JSON error body (spec §8) for a thrown value, using * `errorToStatus` for the status/code. Structured `details` are surfaced for a * CrtrError (they let the client reconstruct the error verbatim). A 500 still * omits `details` for hygiene, but NO LONGER strips the message to a bare * `internal error`: it surfaces the bounded cause (`boundedCause`) so a caller * is never left with a causeless internal, while the router logs the full * error (with stack) server-side. */ export declare function toErrorBody(err: unknown): { status: number; body: ErrorBody; };