@crouter/api 0.3.377
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/README.md +67 -0
- package/dist/api/__tests__/error-codes.test.d.ts +1 -0
- package/dist/api/__tests__/error-codes.test.js +78 -0
- package/dist/api/__tests__/integration/client.test.d.ts +1 -0
- package/dist/api/__tests__/integration/client.test.js +179 -0
- package/dist/api/client.d.ts +467 -0
- package/dist/api/client.js +1179 -0
- package/dist/api/command-manifest/index.d.ts +3 -0
- package/dist/api/command-manifest/index.js +3 -0
- package/dist/api/command-manifest/manifest.d.ts +51 -0
- package/dist/api/command-manifest/manifest.js +332 -0
- package/dist/api/command-manifest/result.d.ts +25 -0
- package/dist/api/command-manifest/result.js +97 -0
- package/dist/api/command-manifest/schema.d.ts +28 -0
- package/dist/api/command-manifest/schema.js +856 -0
- package/dist/api/dto/analytics.d.ts +184 -0
- package/dist/api/dto/analytics.js +3 -0
- package/dist/api/dto/attach.d.ts +22 -0
- package/dist/api/dto/attach.js +13 -0
- package/dist/api/dto/bash-jobs.d.ts +24 -0
- package/dist/api/dto/bash-jobs.js +9 -0
- package/dist/api/dto/bash.d.ts +17 -0
- package/dist/api/dto/bash.js +1 -0
- package/dist/api/dto/broker-ops.d.ts +187 -0
- package/dist/api/dto/broker-ops.js +6 -0
- package/dist/api/dto/broker-signals.d.ts +25 -0
- package/dist/api/dto/broker-signals.js +1 -0
- package/dist/api/dto/broker.d.ts +86 -0
- package/dist/api/dto/broker.js +20 -0
- package/dist/api/dto/canvas.d.ts +359 -0
- package/dist/api/dto/canvas.js +2 -0
- package/dist/api/dto/chat-inventory.d.ts +56 -0
- package/dist/api/dto/chat-inventory.js +11 -0
- package/dist/api/dto/common.d.ts +29 -0
- package/dist/api/dto/common.js +15 -0
- package/dist/api/dto/config.d.ts +36 -0
- package/dist/api/dto/config.js +3 -0
- package/dist/api/dto/crons.d.ts +150 -0
- package/dist/api/dto/crons.js +10 -0
- package/dist/api/dto/custom-objects.d.ts +66 -0
- package/dist/api/dto/custom-objects.js +1 -0
- package/dist/api/dto/delivery.d.ts +71 -0
- package/dist/api/dto/delivery.js +7 -0
- package/dist/api/dto/docs.d.ts +135 -0
- package/dist/api/dto/docs.js +8 -0
- package/dist/api/dto/files.d.ts +21 -0
- package/dist/api/dto/files.js +1 -0
- package/dist/api/dto/focus.d.ts +24 -0
- package/dist/api/dto/focus.js +10 -0
- package/dist/api/dto/grants.d.ts +14 -0
- package/dist/api/dto/grants.js +1 -0
- package/dist/api/dto/health.d.ts +106 -0
- package/dist/api/dto/health.js +2 -0
- package/dist/api/dto/human-requests.d.ts +113 -0
- package/dist/api/dto/human-requests.js +4 -0
- package/dist/api/dto/human.d.ts +28 -0
- package/dist/api/dto/human.js +4 -0
- package/dist/api/dto/inbox.d.ts +273 -0
- package/dist/api/dto/inbox.js +4 -0
- package/dist/api/dto/lifecycle.d.ts +88 -0
- package/dist/api/dto/lifecycle.js +3 -0
- package/dist/api/dto/mail.d.ts +44 -0
- package/dist/api/dto/mail.js +1 -0
- package/dist/api/dto/messages.d.ts +88 -0
- package/dist/api/dto/messages.js +2 -0
- package/dist/api/dto/model-config.d.ts +25 -0
- package/dist/api/dto/model-config.js +1 -0
- package/dist/api/dto/modelauth.d.ts +132 -0
- package/dist/api/dto/modelauth.js +4 -0
- package/dist/api/dto/node-events.d.ts +65 -0
- package/dist/api/dto/node-events.js +4 -0
- package/dist/api/dto/node-outcomes.d.ts +88 -0
- package/dist/api/dto/node-outcomes.js +2 -0
- package/dist/api/dto/node-records.d.ts +35 -0
- package/dist/api/dto/node-records.js +5 -0
- package/dist/api/dto/nodes.d.ts +368 -0
- package/dist/api/dto/nodes.js +3 -0
- package/dist/api/dto/objects.d.ts +172 -0
- package/dist/api/dto/objects.js +5 -0
- package/dist/api/dto/profiles.d.ts +117 -0
- package/dist/api/dto/profiles.js +4 -0
- package/dist/api/dto/recovery.d.ts +104 -0
- package/dist/api/dto/recovery.js +1 -0
- package/dist/api/dto/reports.d.ts +93 -0
- package/dist/api/dto/reports.js +2 -0
- package/dist/api/dto/review-comments.d.ts +146 -0
- package/dist/api/dto/review-comments.js +5 -0
- package/dist/api/dto/reviews.d.ts +113 -0
- package/dist/api/dto/reviews.js +5 -0
- package/dist/api/dto/run-events.d.ts +293 -0
- package/dist/api/dto/run-events.js +6 -0
- package/dist/api/dto/subscriptions.d.ts +14 -0
- package/dist/api/dto/subscriptions.js +2 -0
- package/dist/api/dto/worktree.d.ts +55 -0
- package/dist/api/dto/worktree.js +6 -0
- package/dist/api/error-codes.d.ts +254 -0
- package/dist/api/error-codes.js +54 -0
- package/dist/api/errors.d.ts +47 -0
- package/dist/api/errors.js +66 -0
- package/dist/api/index.d.ts +42 -0
- package/dist/api/index.js +41 -0
- package/dist/api/node-transport.d.ts +18 -0
- package/dist/api/node-transport.js +105 -0
- package/dist/api/plugin-manifest-schema.d.ts +233 -0
- package/dist/api/plugin-manifest-schema.js +23 -0
- package/dist/api/routes.d.ts +160 -0
- package/dist/api/routes.js +193 -0
- package/dist/shared/generated-context.d.ts +79 -0
- package/dist/shared/generated-context.js +232 -0
- package/dist/shared/predicates.d.ts +2 -0
- package/dist/shared/predicates.js +4 -0
- package/package.json +49 -0
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
import type { Cursor, IsoTime, NodeIdDTO, NodeStatusDTO } from './common.js';
|
|
2
|
+
import type { NodeFaultDTO, NodeSummaryDTO } from './nodes.js';
|
|
3
|
+
/** `GET /v1/nodes` + `GET /v1/status` composed for the dashboard view. */
|
|
4
|
+
export interface DashboardQuery {
|
|
5
|
+
/** Restrict to the subtree under this node. */
|
|
6
|
+
under?: NodeIdDTO;
|
|
7
|
+
}
|
|
8
|
+
export interface DashboardDTO {
|
|
9
|
+
nodes: NodeSummaryDTO[];
|
|
10
|
+
/** Node counts keyed by status. */
|
|
11
|
+
counts: Partial<Record<NodeStatusDTO, number>>;
|
|
12
|
+
generated_at: IsoTime;
|
|
13
|
+
}
|
|
14
|
+
/** A node needing attention (tickets across the canvas). Projected from the
|
|
15
|
+
* `TicketEntry` reader — one entry per node with open human tickets. */
|
|
16
|
+
export interface AttentionItemDTO {
|
|
17
|
+
node_id: NodeIdDTO;
|
|
18
|
+
name: string;
|
|
19
|
+
cwd: string;
|
|
20
|
+
/** Number of open tickets on this node. */
|
|
21
|
+
count: number;
|
|
22
|
+
/** Open ticket titles for this node, newest first — one per counted ticket. */
|
|
23
|
+
subjects: string[];
|
|
24
|
+
}
|
|
25
|
+
/** `GET /v1/canvas/attention` result. */
|
|
26
|
+
export interface AttentionDTO {
|
|
27
|
+
items: AttentionItemDTO[];
|
|
28
|
+
}
|
|
29
|
+
/** `POST /v1/canvas/attention/counts` request. Restrict the synchronous inbox
|
|
30
|
+
* scan to the nodes a viewer is actually rendering instead of enriching the
|
|
31
|
+
* entire canvas roster. */
|
|
32
|
+
export interface AttentionCountsRequest {
|
|
33
|
+
node_ids: NodeIdDTO[];
|
|
34
|
+
}
|
|
35
|
+
/** `POST /v1/canvas/attention/counts` result, keyed by requested node id. */
|
|
36
|
+
export interface AttentionCountsDTO {
|
|
37
|
+
counts: Record<NodeIdDTO, number>;
|
|
38
|
+
}
|
|
39
|
+
/** `POST /v1/canvas/history/search` body — the ranked/filtered search over the
|
|
40
|
+
* per-cwd conversation corpus (inboxes and transcripts), backing `crtr canvas history search` (optional
|
|
41
|
+
* query: ranked when present, recency browse when omitted). The CLI parses +
|
|
42
|
+
* validates flags (`--type` set, `--since`/`--until` → epoch ms) and sends
|
|
43
|
+
* this normalized query; the server runs `buildCorpus` + ranking + pagination
|
|
44
|
+
* (closures like `loadBody` cannot cross the boundary, so the whole search
|
|
45
|
+
* executes server-side). Sent as POST — the query carries arrays and
|
|
46
|
+
* free-text that do not serialize cleanly as GET params. */
|
|
47
|
+
export interface HistorySearchQuery {
|
|
48
|
+
/** Whitespace-separated terms, ranked; omit to browse by recency. */
|
|
49
|
+
query?: string;
|
|
50
|
+
cwd?: string;
|
|
51
|
+
all_cwds?: boolean;
|
|
52
|
+
under?: string;
|
|
53
|
+
/** Restrict to specific node ids. */
|
|
54
|
+
nodes?: string[];
|
|
55
|
+
/** Corpus types: inbox | transcript. */
|
|
56
|
+
types?: string[];
|
|
57
|
+
kinds?: string[];
|
|
58
|
+
statuses?: string[];
|
|
59
|
+
/** Lower bound on artifact timestamp (epoch ms), parsed CLI-side. */
|
|
60
|
+
since_ms?: number;
|
|
61
|
+
/** Upper bound on artifact timestamp (epoch ms), parsed CLI-side. */
|
|
62
|
+
until_ms?: number;
|
|
63
|
+
/** Inbound-message narrowing (transcript + inbox): what drove arrival. */
|
|
64
|
+
origins?: string[];
|
|
65
|
+
/** Transcript-message roles: user | assistant | toolResult. */
|
|
66
|
+
roles?: string[];
|
|
67
|
+
/** Case-insensitive substring against sender attribution. */
|
|
68
|
+
from?: string;
|
|
69
|
+
/** Weigh full body text in ranking (`--body`). */
|
|
70
|
+
weigh_body?: boolean;
|
|
71
|
+
/** relevance | recency | oldest — already resolved to the effective sort. */
|
|
72
|
+
sort?: string;
|
|
73
|
+
snippet_lines?: number;
|
|
74
|
+
full?: boolean;
|
|
75
|
+
limit?: number;
|
|
76
|
+
cursor?: Cursor;
|
|
77
|
+
}
|
|
78
|
+
/** `POST /v1/canvas/history/search` result. `hits` is heterogeneous by mode
|
|
79
|
+
* (with/without a relevance score, snippet vs full body), so it stays a
|
|
80
|
+
* loose object list — the CLI's renderer already treats hits as
|
|
81
|
+
* `Record<string, unknown>[]`. The static `follow_up` line is appended
|
|
82
|
+
* CLI-side. */
|
|
83
|
+
export interface HistorySearchResultDTO {
|
|
84
|
+
hits: Record<string, unknown>[];
|
|
85
|
+
next_cursor: Cursor | null;
|
|
86
|
+
total: number;
|
|
87
|
+
}
|
|
88
|
+
/** `POST /v1/canvas/history/grep` body — the required-pattern line-hit search
|
|
89
|
+
* over the per-cwd conversation corpus (inboxes and transcripts), backing `crtr canvas history grep`.
|
|
90
|
+
* Shares scope/corpus filters with `HistorySearchQuery` but is a distinct
|
|
91
|
+
* wire contract: `pattern` is mandatory (an ECMAScript regex) and there is no
|
|
92
|
+
* ranking/snippet/full-body shape. */
|
|
93
|
+
export interface HistoryGrepQuery {
|
|
94
|
+
/** Required ECMAScript regex, matched per body line (case-insensitive). */
|
|
95
|
+
pattern: string;
|
|
96
|
+
cwd?: string;
|
|
97
|
+
all_cwds?: boolean;
|
|
98
|
+
under?: string;
|
|
99
|
+
/** Restrict to specific node ids. */
|
|
100
|
+
nodes?: string[];
|
|
101
|
+
/** Corpus types: inbox | transcript. */
|
|
102
|
+
types?: string[];
|
|
103
|
+
kinds?: string[];
|
|
104
|
+
statuses?: string[];
|
|
105
|
+
/** Lower bound on artifact timestamp (epoch ms), parsed CLI-side. */
|
|
106
|
+
since_ms?: number;
|
|
107
|
+
/** Upper bound on artifact timestamp (epoch ms), parsed CLI-side. */
|
|
108
|
+
until_ms?: number;
|
|
109
|
+
/** Inbound-message narrowing (transcript + inbox): what drove arrival. */
|
|
110
|
+
origins?: string[];
|
|
111
|
+
/** Transcript-message roles: user | assistant | toolResult. */
|
|
112
|
+
roles?: string[];
|
|
113
|
+
/** Case-insensitive substring against sender attribution. */
|
|
114
|
+
from?: string;
|
|
115
|
+
limit?: number;
|
|
116
|
+
cursor?: Cursor;
|
|
117
|
+
}
|
|
118
|
+
/** `POST /v1/canvas/history/stats` body — the grouped-count projection over
|
|
119
|
+
* the same corpus search and grep scan, backing `crtr canvas history stats`.
|
|
120
|
+
* Shares every scope/corpus/message filter; carries no query, pattern, or
|
|
121
|
+
* pagination because the result is an aggregate, not a hit list. */
|
|
122
|
+
export interface HistoryStatsQuery {
|
|
123
|
+
/** origin | node | kind | day | type | role. Defaults to type. */
|
|
124
|
+
group_by?: string;
|
|
125
|
+
cwd?: string;
|
|
126
|
+
all_cwds?: boolean;
|
|
127
|
+
under?: string;
|
|
128
|
+
nodes?: string[];
|
|
129
|
+
types?: string[];
|
|
130
|
+
kinds?: string[];
|
|
131
|
+
statuses?: string[];
|
|
132
|
+
since_ms?: number;
|
|
133
|
+
until_ms?: number;
|
|
134
|
+
origins?: string[];
|
|
135
|
+
roles?: string[];
|
|
136
|
+
from?: string;
|
|
137
|
+
}
|
|
138
|
+
/** `POST /v1/canvas/history/stats` result — counts by the grouped dimension,
|
|
139
|
+
* descending. `total` counts the artifacts that carried the dimension, so it
|
|
140
|
+
* can be lower than the corpus size when grouping by one not every artifact
|
|
141
|
+
* has (origin, role). */
|
|
142
|
+
export interface HistoryStatsResultDTO {
|
|
143
|
+
group_by: string;
|
|
144
|
+
groups: Array<{
|
|
145
|
+
key: string;
|
|
146
|
+
count: number;
|
|
147
|
+
}>;
|
|
148
|
+
total: number;
|
|
149
|
+
/** Artifacts scanned before the grouping dimension was applied. */
|
|
150
|
+
scanned: number;
|
|
151
|
+
}
|
|
152
|
+
/** One matching body line from `crtr canvas history grep`. */
|
|
153
|
+
export interface HistoryGrepHitDTO {
|
|
154
|
+
ref: string;
|
|
155
|
+
/** "name (id)". */
|
|
156
|
+
node: string;
|
|
157
|
+
ts: IsoTime;
|
|
158
|
+
line: number;
|
|
159
|
+
text: string;
|
|
160
|
+
}
|
|
161
|
+
/** `POST /v1/canvas/history/grep` result — a stable line-hit schema, distinct
|
|
162
|
+
* from `HistorySearchResultDTO`'s heterogeneous ranked/browse shape. */
|
|
163
|
+
export interface HistoryGrepResultDTO {
|
|
164
|
+
hits: HistoryGrepHitDTO[];
|
|
165
|
+
next_cursor: Cursor | null;
|
|
166
|
+
total: number;
|
|
167
|
+
}
|
|
168
|
+
/** `GET /v1/canvas/history/read` query — resolve one `<node-id>:inbox/<n>`,
|
|
169
|
+
* `<node-id>:session` or `<node-id>:session/<n>` ref. */
|
|
170
|
+
export interface HistoryReadQuery {
|
|
171
|
+
ref: string;
|
|
172
|
+
/** `rendered` (default) or `raw` — the verbatim bytes behind the ref: the
|
|
173
|
+
* session file for a bare `session` ref, the one jsonl line for a message. */
|
|
174
|
+
format?: string;
|
|
175
|
+
}
|
|
176
|
+
/** `GET /v1/canvas/history/read` result — one hit's full body. */
|
|
177
|
+
export interface HistoryReadResultDTO {
|
|
178
|
+
ref: string;
|
|
179
|
+
/** "name (id)". */
|
|
180
|
+
node: string;
|
|
181
|
+
/** inbox | transcript. */
|
|
182
|
+
source: string;
|
|
183
|
+
ts: IsoTime;
|
|
184
|
+
content: string;
|
|
185
|
+
}
|
|
186
|
+
/** One node row in the browser canvas roster (`GET /v1/canvas/snapshot`). A
|
|
187
|
+
* richer projection than `NodeSummaryDTO`: it carries the enriched viewer
|
|
188
|
+
* fields (`dashboardRowsAll` + `enrichRows`) the browser canvas renders —
|
|
189
|
+
* attention counts, ctx tokens, streaming/hanging/viewed state, last activity. */
|
|
190
|
+
export interface SnapshotNodeDTO {
|
|
191
|
+
node_id: NodeIdDTO;
|
|
192
|
+
name: string;
|
|
193
|
+
/** Caller-supplied node title, kept separate from the enriched full label. */
|
|
194
|
+
title: string;
|
|
195
|
+
/** Caller-supplied node brief, or null when absent. */
|
|
196
|
+
description: string | null;
|
|
197
|
+
kind: string;
|
|
198
|
+
mode: string;
|
|
199
|
+
lifecycle?: string;
|
|
200
|
+
status: NodeStatusDTO;
|
|
201
|
+
cwd: string;
|
|
202
|
+
/** The profile this node runs under; null for a historical no-profile row.
|
|
203
|
+
* Carried here because it is the only field that says WHOSE work a node is —
|
|
204
|
+
* a snapshot consumer grouping nodes by agent has nothing else to key on. */
|
|
205
|
+
profile_id: string | null;
|
|
206
|
+
parent: NodeIdDTO | null;
|
|
207
|
+
created: IsoTime;
|
|
208
|
+
host_kind: string;
|
|
209
|
+
/** True when the node hosts an enterable broker (`host_kind === 'broker'`). */
|
|
210
|
+
enterable: boolean;
|
|
211
|
+
attention_count: number;
|
|
212
|
+
cycles?: number;
|
|
213
|
+
last_activity?: IsoTime;
|
|
214
|
+
ctx_tokens?: number;
|
|
215
|
+
streaming: boolean;
|
|
216
|
+
/** Number of active background bash jobs, reported only for a live broker. */
|
|
217
|
+
jobs_active: number;
|
|
218
|
+
/** Controller node this node is durably waiting for, or null. */
|
|
219
|
+
waiting_for: string | null;
|
|
220
|
+
/** The node's active fault projection (structurally a `Fault`), or null. Kept
|
|
221
|
+
* as a loose object to keep this DTO free of a `core` type import. */
|
|
222
|
+
hanging: Record<string, unknown> | null;
|
|
223
|
+
viewed: boolean;
|
|
224
|
+
/** Basename of the node's final report, or null when it never pushed one.
|
|
225
|
+
* Presence — not `status === 'done'` — is what distinguishes finished work
|
|
226
|
+
* from clean parking. */
|
|
227
|
+
final_report: string | null;
|
|
228
|
+
finalized_at: IsoTime | null;
|
|
229
|
+
}
|
|
230
|
+
/** `GET /v1/canvas/snapshot` result — the machine-readable browser canvas
|
|
231
|
+
* roster (`crtr canvas snapshot`). Distinct from the per-node `NodeSnapshotDTO`
|
|
232
|
+
* (nodes.ts). `subscriptions` is the authoritative `subscribes_to` adjacency
|
|
233
|
+
* map: each node id → its publisher/child node ids in edge order. */
|
|
234
|
+
export interface SnapshotDTO {
|
|
235
|
+
generated_at: IsoTime;
|
|
236
|
+
nodes: SnapshotNodeDTO[];
|
|
237
|
+
subscriptions: Record<string, NodeIdDTO[]>;
|
|
238
|
+
}
|
|
239
|
+
/** One node row in the lean roster (`GET /v1/canvas/roster`). Carries only
|
|
240
|
+
* stored node fields, without a process-liveness probe. `attention_count`/`last_activity`/`ctx_tokens`/
|
|
241
|
+
* `streaming`/`hanging`/`viewed` stay on `SnapshotNodeDTO`; a roster consumer
|
|
242
|
+
* that needs attention counts fetches them separately via the existing
|
|
243
|
+
* `POST /v1/canvas/attention/counts` (already scoped to exactly the ids it
|
|
244
|
+
* renders, never the whole canvas). */
|
|
245
|
+
export interface RosterNodeDTO {
|
|
246
|
+
node_id: NodeIdDTO;
|
|
247
|
+
name: string;
|
|
248
|
+
kind: string;
|
|
249
|
+
mode: string;
|
|
250
|
+
lifecycle?: string;
|
|
251
|
+
status: NodeStatusDTO;
|
|
252
|
+
cwd: string;
|
|
253
|
+
host_kind: string;
|
|
254
|
+
/** True when the node hosts an enterable broker (`host_kind === 'broker'`). */
|
|
255
|
+
enterable: boolean;
|
|
256
|
+
parent: NodeIdDTO | null;
|
|
257
|
+
created: IsoTime;
|
|
258
|
+
}
|
|
259
|
+
/** One `subscribes_to` edge in the roster's topology half. Every edge is kept
|
|
260
|
+
* (passive + multiple per node) — never collapsed to one edge per node. */
|
|
261
|
+
export interface RosterEdgeDTO {
|
|
262
|
+
from_id: NodeIdDTO;
|
|
263
|
+
to_id: NodeIdDTO;
|
|
264
|
+
active: boolean;
|
|
265
|
+
created: IsoTime;
|
|
266
|
+
}
|
|
267
|
+
/** `GET /v1/canvas/roster` result — the lean, set-based topology read shared by
|
|
268
|
+
* the attach viewer and the browser canvas: exactly two indexed queries
|
|
269
|
+
* (`rosterNodes()` + `rosterEdges()`), no `enrichRows`, no per-row
|
|
270
|
+
* `getNode`/`subscriptionsOf` loop, no synchronous liveness probe. The
|
|
271
|
+
* recurring poll target that replaces the enriched `/v1/canvas/snapshot`
|
|
272
|
+
* storm; that endpoint remains for genuinely on-demand rich views. */
|
|
273
|
+
export interface RosterDTO {
|
|
274
|
+
generated_at: IsoTime;
|
|
275
|
+
nodes: RosterNodeDTO[];
|
|
276
|
+
edges: RosterEdgeDTO[];
|
|
277
|
+
}
|
|
278
|
+
/** Browse's initial frame needs the dashboard fields and topology, not the full
|
|
279
|
+
* node detail/list projection. Transported as gzip JSON (application/gzip) over
|
|
280
|
+
* the local socket; other /v1/nodes consumers keep their original response. */
|
|
281
|
+
export interface BrowseNodeDTO {
|
|
282
|
+
node_id: string;
|
|
283
|
+
name: string;
|
|
284
|
+
description?: string;
|
|
285
|
+
kind: string;
|
|
286
|
+
mode: string;
|
|
287
|
+
lifecycle: string;
|
|
288
|
+
status: NodeStatusDTO;
|
|
289
|
+
cwd: string;
|
|
290
|
+
profile_id: string | null;
|
|
291
|
+
grantee: string;
|
|
292
|
+
parent: string | null;
|
|
293
|
+
created: IsoTime;
|
|
294
|
+
frozen_at: IsoTime | null;
|
|
295
|
+
terminal_reason: string | null;
|
|
296
|
+
final_report: string | null;
|
|
297
|
+
telemetry_tokens_in: number | null;
|
|
298
|
+
telemetry_updated_at: IsoTime | null;
|
|
299
|
+
fault: import('./nodes.js').NodeFaultDTO | null;
|
|
300
|
+
streaming: boolean;
|
|
301
|
+
}
|
|
302
|
+
export interface BrowseCanvasDTO {
|
|
303
|
+
nodes: BrowseNodeDTO[];
|
|
304
|
+
edges: RosterEdgeDTO[];
|
|
305
|
+
}
|
|
306
|
+
/** One row in `GET /v1/canvas/graph`: exactly the node fields the attach graph displays. */
|
|
307
|
+
export interface GraphNodeDTO {
|
|
308
|
+
node_id: NodeIdDTO;
|
|
309
|
+
name: string;
|
|
310
|
+
description: string | null;
|
|
311
|
+
cycles: number | null;
|
|
312
|
+
kind: string;
|
|
313
|
+
status: NodeStatusDTO;
|
|
314
|
+
frozen_at: IsoTime | null;
|
|
315
|
+
pi_pid: number | null;
|
|
316
|
+
telemetry_context_tokens: number | null;
|
|
317
|
+
telemetry_last_activity: string | null;
|
|
318
|
+
fault: NodeFaultDTO | null;
|
|
319
|
+
streaming: boolean;
|
|
320
|
+
}
|
|
321
|
+
/** `GET /v1/canvas/graph` — the attach graph's one-read projection: display rows, subscription topology, and the current local viewer-focus set. */
|
|
322
|
+
export interface GraphDTO {
|
|
323
|
+
generated_at: IsoTime;
|
|
324
|
+
nodes: GraphNodeDTO[];
|
|
325
|
+
edges: RosterEdgeDTO[];
|
|
326
|
+
focused_node_ids: NodeIdDTO[];
|
|
327
|
+
}
|
|
328
|
+
/** `POST /v1/canvas/prune` body — the three exclusive prune modes of
|
|
329
|
+
* `crtr canvas prune`, precedence COUNT (`limit`) > EMPTY (`empty`) > TTL sweep. */
|
|
330
|
+
export interface PruneRequest {
|
|
331
|
+
/** COUNT mode: keep the N most-recently-active nodes, prune the oldest
|
|
332
|
+
* remaining terminal nodes (protected nodes always survive). */
|
|
333
|
+
limit?: number;
|
|
334
|
+
/** TTL sweep retention window in days (default 14). */
|
|
335
|
+
ttl_days?: number;
|
|
336
|
+
/** TTL sweep: also prune stale active/idle nodes past the TTL whose process
|
|
337
|
+
* is provably gone. */
|
|
338
|
+
include_stale?: boolean;
|
|
339
|
+
/** EMPTY mode: reap nodes whose engine never produced an assistant message. */
|
|
340
|
+
empty?: boolean;
|
|
341
|
+
/** Report what would be pruned without mutating. */
|
|
342
|
+
dry_run?: boolean;
|
|
343
|
+
}
|
|
344
|
+
/** One node in a prune result (pruned, or candidate under `dry_run`). */
|
|
345
|
+
export interface PrunedNodeDTO {
|
|
346
|
+
node_id: NodeIdDTO;
|
|
347
|
+
/** Lifecycle status, or `empty` for EMPTY-mode reaps. */
|
|
348
|
+
status: string;
|
|
349
|
+
/** ISO created timestamp (empty string for EMPTY-mode reaps). */
|
|
350
|
+
created: string;
|
|
351
|
+
}
|
|
352
|
+
/** `POST /v1/canvas/prune` result. `pruned` is the pruned set (or, under
|
|
353
|
+
* `dry_run`, the candidate set — nothing deleted). `ttl_days` echoes the
|
|
354
|
+
* retention window used. */
|
|
355
|
+
export interface PruneResultDTO {
|
|
356
|
+
pruned: PrunedNodeDTO[];
|
|
357
|
+
dry_run: boolean;
|
|
358
|
+
ttl_days: number;
|
|
359
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** One command a chat surface may advertise. Builtin and non-opted-in rows are
|
|
2
|
+
* dropped before this DTO exists, so `source` never carries `'builtin'`. */
|
|
3
|
+
export interface ChatInventoryCommandDTO {
|
|
4
|
+
/** No leading slash, exactly as the engine dispatches it. */
|
|
5
|
+
name: string;
|
|
6
|
+
description: string;
|
|
7
|
+
source: 'command' | 'template';
|
|
8
|
+
/** Argument shape to display beside the name, when the command supplies one. */
|
|
9
|
+
argument_hint?: string;
|
|
10
|
+
/** Deterministic expansion metadata for a memory-slash command — the same
|
|
11
|
+
* material the terminal preview uses, so a chat preview cannot drift from
|
|
12
|
+
* what submission sends. */
|
|
13
|
+
expansion?: {
|
|
14
|
+
kind: 'memory-slash';
|
|
15
|
+
commandName: string;
|
|
16
|
+
body: string;
|
|
17
|
+
};
|
|
18
|
+
/** Raw prompt-template content (frontmatter stripped), for `source: 'template'`. */
|
|
19
|
+
template?: string;
|
|
20
|
+
}
|
|
21
|
+
/** One resolvable inline memory reference. Metadata only — never the document
|
|
22
|
+
* body or its source path. `shortForm` stays camelCase to mirror the broker's
|
|
23
|
+
* own `RefMeta`, which is where these rows come from. */
|
|
24
|
+
export interface ChatInventoryMemoryRefDTO {
|
|
25
|
+
/** Canonical `/`-joined name, e.g. `taste/writing`. */
|
|
26
|
+
name: string;
|
|
27
|
+
kind: 'knowledge' | 'preference';
|
|
28
|
+
scope: 'node' | 'project' | 'profile' | 'user' | 'builtin';
|
|
29
|
+
shortForm: string;
|
|
30
|
+
}
|
|
31
|
+
/** `GET /v1/nodes/{id}/chat-inventory` result.
|
|
32
|
+
*
|
|
33
|
+
* `broker_live` reports whether the node's engine was reachable at all. There
|
|
34
|
+
* is no per-part error flag: a part that failed and a part that is genuinely
|
|
35
|
+
* empty both arrive as an empty array, and a client's behavior is identical
|
|
36
|
+
* for both. A dormant node answers 200 with `broker_live: false` — this read
|
|
37
|
+
* never revives an engine. */
|
|
38
|
+
export interface ChatInventoryDTO {
|
|
39
|
+
node_id: string;
|
|
40
|
+
broker_live: boolean;
|
|
41
|
+
commands: ChatInventoryCommandDTO[];
|
|
42
|
+
memory_refs: ChatInventoryMemoryRefDTO[];
|
|
43
|
+
}
|
|
44
|
+
/** Session-less inventory for the launch target a create would resolve. */
|
|
45
|
+
export interface ProspectiveChatInventoryDTO {
|
|
46
|
+
profile_id: string | null;
|
|
47
|
+
cwd: string;
|
|
48
|
+
commands: ChatInventoryCommandDTO[];
|
|
49
|
+
memory_refs: ChatInventoryMemoryRefDTO[];
|
|
50
|
+
}
|
|
51
|
+
export interface ProspectiveChatInventoryQuery {
|
|
52
|
+
profile?: string;
|
|
53
|
+
cwd?: string;
|
|
54
|
+
/** Same optional kind operand as POST /v1/nodes. */
|
|
55
|
+
kind?: string;
|
|
56
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Chat-inventory DTO. Backs `GET /v1/nodes/{id}/chat-inventory` — the one read
|
|
2
|
+
// a non-terminal chat surface makes to learn what the node's live engine will
|
|
3
|
+
// accept: the slash commands that can complete their outcome from a chat
|
|
4
|
+
// conversation, and the memory documents an inline `/name` token resolves to.
|
|
5
|
+
//
|
|
6
|
+
// Eligibility is decided in crouter and disclosed here. A client never filters
|
|
7
|
+
// by name, infers capability, or invents a row: what is absent from these
|
|
8
|
+
// arrays is not offered.
|
|
9
|
+
//
|
|
10
|
+
// PURITY (spec §3.1): Node built-ins + `src/api/*` only.
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** ISO-8601 timestamp string (matches the runtime's `nowIso()` output). */
|
|
2
|
+
export type IsoTime = string;
|
|
3
|
+
/** A node id — the existing `<slug>-<hash>` string. Typed as a nominal alias so
|
|
4
|
+
* DTOs read as thin projections; validated at the boundary by `isSafeNodeId`. */
|
|
5
|
+
export type NodeIdDTO = string;
|
|
6
|
+
/** Opaque pagination cursor (server-defined; clients pass it back verbatim). */
|
|
7
|
+
export type Cursor = string;
|
|
8
|
+
/** Standard list-pagination inputs shared by paged queries. */
|
|
9
|
+
export interface Pagination {
|
|
10
|
+
limit?: number;
|
|
11
|
+
cursor?: Cursor;
|
|
12
|
+
}
|
|
13
|
+
/** Runtime status of a node (mirrors the runtime `NodeStatus` union; declared
|
|
14
|
+
* locally to keep `/api` free of any `core/*` import). */
|
|
15
|
+
export type NodeStatusDTO = 'active' | 'idle' | 'done' | 'dead' | 'canceled';
|
|
16
|
+
/** Lifecycle class of a node (mirrors the runtime `Lifecycle` union). */
|
|
17
|
+
export type LifecycleDTO = 'terminal' | 'resident';
|
|
18
|
+
/** Execution mode of a node (mirrors the runtime `Mode` union). */
|
|
19
|
+
export type ModeDTO = 'base' | 'orchestrator';
|
|
20
|
+
/** Why a node last stopped (mirrors the runtime `ExitIntent` union). */
|
|
21
|
+
export type ExitIntentDTO = 'done' | 'refresh' | 'idle-release' | 'parked' | null;
|
|
22
|
+
/** Why a terminal node ended (mirrors the runtime `TerminalReason` union). */
|
|
23
|
+
export type TerminalReasonDTO = 'finalized' | 'finished' | 'parked' | 'closed' | 'retired' | 'crashed' | 'stranded' | 'boot_failed' | 'crash_looped' | 'launch_failed' | 'context_overflow' | 'deadline_exceeded' | 'provider_fatal' | 'declined';
|
|
24
|
+
/** Inbox urgency tier for a delivered message (mirrors feed/inbox `InboxTier`). */
|
|
25
|
+
export type InboxTierDTO = 'critical' | 'urgent' | 'normal' | 'deferred';
|
|
26
|
+
/** Whether a node id is a safe single filesystem path segment. Re-declared here
|
|
27
|
+
* (not imported from `core/canvas/paths.ts`) to keep the exported `/api`
|
|
28
|
+
* contract dependency-light; kept byte-for-byte equivalent to the runtime's. */
|
|
29
|
+
export declare function isSafeNodeId(id: string): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Shared scalars and cross-cutting DTO primitives.
|
|
2
|
+
//
|
|
3
|
+
// PURITY (spec §3.1): this file — like every file under `src/api/` — imports
|
|
4
|
+
// ONLY other `src/api/*` modules and Node built-ins. Never `core/*`,
|
|
5
|
+
// `node:sqlite`, TUI, or any heavy runtime module.
|
|
6
|
+
const MAX_NODE_ID_BYTES = 128;
|
|
7
|
+
/** Whether a node id is a safe single filesystem path segment. Re-declared here
|
|
8
|
+
* (not imported from `core/canvas/paths.ts`) to keep the exported `/api`
|
|
9
|
+
* contract dependency-light; kept byte-for-byte equivalent to the runtime's. */
|
|
10
|
+
export function isSafeNodeId(id) {
|
|
11
|
+
return typeof id === 'string'
|
|
12
|
+
&& id !== '' && id !== '.' && id !== '..'
|
|
13
|
+
&& !/[\\/\0]/u.test(id)
|
|
14
|
+
&& Buffer.byteLength(id, 'utf8') <= MAX_NODE_ID_BYTES;
|
|
15
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { LifecycleDTO, ModeDTO } from './common.js';
|
|
2
|
+
/** `PATCH /v1/nodes/{id}/config` body. All fields optional; a set field is
|
|
3
|
+
* applied, an absent field is untouched. */
|
|
4
|
+
export interface NodeConfigPatch {
|
|
5
|
+
/** Model tier or exact selection override. */
|
|
6
|
+
model?: string;
|
|
7
|
+
/** Ambient situational-context text override. */
|
|
8
|
+
situational_context?: string;
|
|
9
|
+
/** Persona kind respecialization — rebuilds the launch spec server-side. */
|
|
10
|
+
kind?: string;
|
|
11
|
+
/** Persona mode; setting `orchestrator` seeds a roadmap scaffold if absent. */
|
|
12
|
+
mode?: ModeDTO;
|
|
13
|
+
/** Lifecycle flip (terminal↔resident), rebuilding the launch spec. */
|
|
14
|
+
lifecycle?: LifecycleDTO;
|
|
15
|
+
/** Rename the node (and, when it has a live viewer window, that window). */
|
|
16
|
+
name?: string;
|
|
17
|
+
/** Repair-only replacement launch directory; exclusive of every other field. */
|
|
18
|
+
cwd?: string;
|
|
19
|
+
/** Per-run allow-list. A patch may only remove scopes; it applies to a live broker on its next revive. */
|
|
20
|
+
scopes?: string[];
|
|
21
|
+
/** The node's default listening configuration: event level ("1".."10") → delivery
|
|
22
|
+
* (`interrupt`|`steer`|`after-turn`|`next-turn`) for watches with no config of their own.
|
|
23
|
+
* `null` resets it to the global default. */
|
|
24
|
+
listen?: Record<string, 'interrupt' | 'steer' | 'after-turn' | 'next-turn'> | null;
|
|
25
|
+
}
|
|
26
|
+
/** One installed persona kind, as the daemon resolves kinds for node creation. */
|
|
27
|
+
export interface KindDTO {
|
|
28
|
+
kind: string;
|
|
29
|
+
when_to_use: string | null;
|
|
30
|
+
/** Top-level kinds a sub-kind is offered to; null takes the default (its own ancestor). */
|
|
31
|
+
available_to: string[] | null;
|
|
32
|
+
}
|
|
33
|
+
/** `GET /v1/kinds` — every kind the daemon accepts on create, sorted by name. */
|
|
34
|
+
export interface KindListDTO {
|
|
35
|
+
kinds: KindDTO[];
|
|
36
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { IsoTime, NodeIdDTO } from './common.js';
|
|
2
|
+
export type CronScopeDTO = 'profile' | 'global';
|
|
3
|
+
export type CronOverlapDTO = 'skip' | 'queue' | 'replace';
|
|
4
|
+
export type CronOnOutputDTO = 'silent' | 'on-failure' | 'always' | 'on-change';
|
|
5
|
+
export type CronStateDTO = 'active' | 'paused';
|
|
6
|
+
export type CronRunStateDTO = 'idle' | 'running';
|
|
7
|
+
/** Is this a safe single path segment for `routes.cron*()` interpolation?
|
|
8
|
+
* Cron ids are server-minted UUIDs, but the route builders carry no logic, so
|
|
9
|
+
* every interpolated id is gated here first (the `isSafeNodeId` discipline). */
|
|
10
|
+
export declare function isSafeCronId(id: string): boolean;
|
|
11
|
+
/** The last settled run, carried on every cron projection so `cron list` shows
|
|
12
|
+
* recent health without a `cron show` per row. Null until the first run. */
|
|
13
|
+
export interface CronLastRunDTO {
|
|
14
|
+
/** When the run settled (UTC). */
|
|
15
|
+
finished: IsoTime | null;
|
|
16
|
+
/** -1 = timeout kill; null = no exit observed (process error / skip marker). */
|
|
17
|
+
exit_code: number | null;
|
|
18
|
+
/** What the sink did with the output, or why it didn't. */
|
|
19
|
+
delivered: string | null;
|
|
20
|
+
}
|
|
21
|
+
/** A cron row projection (`GET /v1/crons`). */
|
|
22
|
+
export interface CronDTO {
|
|
23
|
+
cron_id: string;
|
|
24
|
+
/** Agent-legible label; how the cron shows in list. */
|
|
25
|
+
name: string;
|
|
26
|
+
/** Provenance only — the node that armed it, if any; never a cascade anchor. */
|
|
27
|
+
created_by: NodeIdDTO | null;
|
|
28
|
+
/** The bash command each fire runs. */
|
|
29
|
+
command: string;
|
|
30
|
+
/** The shell and any spawned node stay isolated when armed from an isolated node. */
|
|
31
|
+
isolated: boolean;
|
|
32
|
+
/** Next occurrence (UTC). */
|
|
33
|
+
fire_at: IsoTime;
|
|
34
|
+
/** Recur JSON (interval or cron); null for a one-shot. */
|
|
35
|
+
recur: string | null;
|
|
36
|
+
/** IANA zone for a calendar cadence; null otherwise. */
|
|
37
|
+
tz: string | null;
|
|
38
|
+
/** Clock bound; the row is deleted when passed. Null = no bound. */
|
|
39
|
+
expires_at: IsoTime | null;
|
|
40
|
+
/** Opt-in node coupling (cascades on that node's deletion); null = detached. */
|
|
41
|
+
anchor_node: NodeIdDTO | null;
|
|
42
|
+
cancel_on_wake: boolean;
|
|
43
|
+
/** Execution context, snapshotted at arm time. */
|
|
44
|
+
cwd: string;
|
|
45
|
+
profile: string | null;
|
|
46
|
+
scope: CronScopeDTO;
|
|
47
|
+
/** Names of the extra env vars snapshotted onto the row — KEYS ONLY: the
|
|
48
|
+
* values are the caller's to know and may be secrets. */
|
|
49
|
+
env_keys: string[];
|
|
50
|
+
run_timeout_s: number;
|
|
51
|
+
overlap: CronOverlapDTO;
|
|
52
|
+
on_output: CronOnOutputDTO;
|
|
53
|
+
/** Where deliveries go — the raw sink spec (`node:<id>` | `spawn:<kind>` |
|
|
54
|
+
* `human`), or null when the disposition never delivers. */
|
|
55
|
+
sink: string | null;
|
|
56
|
+
tier: string;
|
|
57
|
+
state: CronStateDTO;
|
|
58
|
+
/** True while the row is parked by the exit-75 owed-gate disposition: the
|
|
59
|
+
* last scheduled run declared "owed but not currently eligible", so the
|
|
60
|
+
* occurrence was not spent. A daemon poke re-dues it now; otherwise a
|
|
61
|
+
* recurring row re-checks at its natural `fire_at` slot (the backstop) and
|
|
62
|
+
* a held one-shot waits for a poke until `expires_at` deletes it. `state`
|
|
63
|
+
* stays honest (active|paused) — renderers derive; an active held row must
|
|
64
|
+
* never present as paused. */
|
|
65
|
+
held: boolean;
|
|
66
|
+
run_state: CronRunStateDTO;
|
|
67
|
+
/** Recent health: the most recent settled run, or null if it never ran. */
|
|
68
|
+
last_run: CronLastRunDTO | null;
|
|
69
|
+
created: IsoTime;
|
|
70
|
+
updated: IsoTime;
|
|
71
|
+
}
|
|
72
|
+
/** `GET /v1/crons` query. `profile` is the CALLER's profile, which is what
|
|
73
|
+
* scoping means here: a profile-scoped cron belongs to its profile, a global
|
|
74
|
+
* one is canvas-home-wide. Omitting `profile` means the caller stands outside
|
|
75
|
+
* every profile (a plain shell, or a provenance read such as "which crons did
|
|
76
|
+
* node X arm") and sees the whole canvas home. This is a namespacing
|
|
77
|
+
* boundary between profiles, not a security boundary. */
|
|
78
|
+
export interface ListCronsQuery {
|
|
79
|
+
profile?: string;
|
|
80
|
+
}
|
|
81
|
+
/** Caller identity for the per-cron routes (show/pause/resume/run/cancel).
|
|
82
|
+
* Same rule as `ListCronsQuery`: a cron outside the caller's scope is 404,
|
|
83
|
+
* and an absent profile sees everything. */
|
|
84
|
+
export interface CronScopeQuery {
|
|
85
|
+
profile?: string | null;
|
|
86
|
+
}
|
|
87
|
+
/** Cancellation-only query. `run_id` is set automatically inside a cron run,
|
|
88
|
+
* letting crtrd distinguish a run ending itself from an external cancellation
|
|
89
|
+
* that must terminate an in-flight process. */
|
|
90
|
+
export interface CancelCronQuery extends CronScopeQuery {
|
|
91
|
+
run_id?: string;
|
|
92
|
+
}
|
|
93
|
+
/** One settled run-log entry (`GET /v1/crons/:cronId`, `POST /v1/crons/:cronId/run`). */
|
|
94
|
+
export interface CronRunDTO {
|
|
95
|
+
run_id: string;
|
|
96
|
+
started: IsoTime;
|
|
97
|
+
finished: IsoTime | null;
|
|
98
|
+
duration_ms: number | null;
|
|
99
|
+
/** null = no exit observed (spawn/process error, or a skip marker); -1 = timeout kill. */
|
|
100
|
+
exit_code: number | null;
|
|
101
|
+
stdout_head: string | null;
|
|
102
|
+
stderr_head: string | null;
|
|
103
|
+
/** What the sink did with this run's output, or why it didn't. */
|
|
104
|
+
delivered: string | null;
|
|
105
|
+
}
|
|
106
|
+
/** `POST /v1/crons/poke` — the bare daemon-level eligibility poke. Re-dues
|
|
107
|
+
* every held active cron now; paused rows keep their held state. Idempotent
|
|
108
|
+
* and free when nothing is held. */
|
|
109
|
+
export interface PokeCronsResult {
|
|
110
|
+
/** How many held rows were re-dued — for the caller's log line. */
|
|
111
|
+
unparked: number;
|
|
112
|
+
/** The poke receipt instant (UTC). */
|
|
113
|
+
at: IsoTime;
|
|
114
|
+
}
|
|
115
|
+
/** `GET /v1/crons/:cronId` — one cron with its run-log ring (most recent first). */
|
|
116
|
+
export interface CronShowDTO {
|
|
117
|
+
cron: CronDTO;
|
|
118
|
+
runs: CronRunDTO[];
|
|
119
|
+
}
|
|
120
|
+
/** `POST /v1/crons` — arm one cron. The CLI resolves timing client-side
|
|
121
|
+
* (parseWhen/parseCadence) and sends the settled `fire_at`/`recur`/`tz`;
|
|
122
|
+
* the server mints the cron_id and applies spec defaults for everything
|
|
123
|
+
* omitted. */
|
|
124
|
+
export interface ArmCronRequest {
|
|
125
|
+
name: string;
|
|
126
|
+
command: string;
|
|
127
|
+
fire_at: IsoTime;
|
|
128
|
+
recur?: string | null;
|
|
129
|
+
tz?: string | null;
|
|
130
|
+
created_by?: NodeIdDTO | null;
|
|
131
|
+
isolated?: boolean;
|
|
132
|
+
/** Execution context, snapshotted at arm time — chosen by the client, else
|
|
133
|
+
* inherited from the creating node; never re-resolved at run time. */
|
|
134
|
+
cwd: string;
|
|
135
|
+
/** Extra env for every run, as a JSON object of string values. */
|
|
136
|
+
env_json?: string | null;
|
|
137
|
+
profile?: string | null;
|
|
138
|
+
/** `profile` (default when a profile is resolved) requires a profile. */
|
|
139
|
+
scope?: CronScopeDTO;
|
|
140
|
+
on_output?: CronOnOutputDTO;
|
|
141
|
+
/** Raw sink spec: `node:<id>` | `spawn:<kind>` | `human`. Required by the
|
|
142
|
+
* always/on-change dispositions; meaningless otherwise. */
|
|
143
|
+
sink?: string | null;
|
|
144
|
+
tier?: string;
|
|
145
|
+
expires_at?: IsoTime | null;
|
|
146
|
+
anchor_node?: NodeIdDTO | null;
|
|
147
|
+
cancel_on_wake?: boolean;
|
|
148
|
+
run_timeout_s?: number;
|
|
149
|
+
overlap?: CronOverlapDTO;
|
|
150
|
+
}
|