@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.
Files changed (112) hide show
  1. package/README.md +67 -0
  2. package/dist/api/__tests__/error-codes.test.d.ts +1 -0
  3. package/dist/api/__tests__/error-codes.test.js +78 -0
  4. package/dist/api/__tests__/integration/client.test.d.ts +1 -0
  5. package/dist/api/__tests__/integration/client.test.js +179 -0
  6. package/dist/api/client.d.ts +467 -0
  7. package/dist/api/client.js +1179 -0
  8. package/dist/api/command-manifest/index.d.ts +3 -0
  9. package/dist/api/command-manifest/index.js +3 -0
  10. package/dist/api/command-manifest/manifest.d.ts +51 -0
  11. package/dist/api/command-manifest/manifest.js +332 -0
  12. package/dist/api/command-manifest/result.d.ts +25 -0
  13. package/dist/api/command-manifest/result.js +97 -0
  14. package/dist/api/command-manifest/schema.d.ts +28 -0
  15. package/dist/api/command-manifest/schema.js +856 -0
  16. package/dist/api/dto/analytics.d.ts +184 -0
  17. package/dist/api/dto/analytics.js +3 -0
  18. package/dist/api/dto/attach.d.ts +22 -0
  19. package/dist/api/dto/attach.js +13 -0
  20. package/dist/api/dto/bash-jobs.d.ts +24 -0
  21. package/dist/api/dto/bash-jobs.js +9 -0
  22. package/dist/api/dto/bash.d.ts +17 -0
  23. package/dist/api/dto/bash.js +1 -0
  24. package/dist/api/dto/broker-ops.d.ts +187 -0
  25. package/dist/api/dto/broker-ops.js +6 -0
  26. package/dist/api/dto/broker-signals.d.ts +25 -0
  27. package/dist/api/dto/broker-signals.js +1 -0
  28. package/dist/api/dto/broker.d.ts +86 -0
  29. package/dist/api/dto/broker.js +20 -0
  30. package/dist/api/dto/canvas.d.ts +359 -0
  31. package/dist/api/dto/canvas.js +2 -0
  32. package/dist/api/dto/chat-inventory.d.ts +56 -0
  33. package/dist/api/dto/chat-inventory.js +11 -0
  34. package/dist/api/dto/common.d.ts +29 -0
  35. package/dist/api/dto/common.js +15 -0
  36. package/dist/api/dto/config.d.ts +36 -0
  37. package/dist/api/dto/config.js +3 -0
  38. package/dist/api/dto/crons.d.ts +150 -0
  39. package/dist/api/dto/crons.js +10 -0
  40. package/dist/api/dto/custom-objects.d.ts +66 -0
  41. package/dist/api/dto/custom-objects.js +1 -0
  42. package/dist/api/dto/delivery.d.ts +71 -0
  43. package/dist/api/dto/delivery.js +7 -0
  44. package/dist/api/dto/docs.d.ts +135 -0
  45. package/dist/api/dto/docs.js +8 -0
  46. package/dist/api/dto/files.d.ts +21 -0
  47. package/dist/api/dto/files.js +1 -0
  48. package/dist/api/dto/focus.d.ts +24 -0
  49. package/dist/api/dto/focus.js +10 -0
  50. package/dist/api/dto/grants.d.ts +14 -0
  51. package/dist/api/dto/grants.js +1 -0
  52. package/dist/api/dto/health.d.ts +106 -0
  53. package/dist/api/dto/health.js +2 -0
  54. package/dist/api/dto/human-requests.d.ts +113 -0
  55. package/dist/api/dto/human-requests.js +4 -0
  56. package/dist/api/dto/human.d.ts +28 -0
  57. package/dist/api/dto/human.js +4 -0
  58. package/dist/api/dto/inbox.d.ts +273 -0
  59. package/dist/api/dto/inbox.js +4 -0
  60. package/dist/api/dto/lifecycle.d.ts +88 -0
  61. package/dist/api/dto/lifecycle.js +3 -0
  62. package/dist/api/dto/mail.d.ts +44 -0
  63. package/dist/api/dto/mail.js +1 -0
  64. package/dist/api/dto/messages.d.ts +88 -0
  65. package/dist/api/dto/messages.js +2 -0
  66. package/dist/api/dto/model-config.d.ts +25 -0
  67. package/dist/api/dto/model-config.js +1 -0
  68. package/dist/api/dto/modelauth.d.ts +132 -0
  69. package/dist/api/dto/modelauth.js +4 -0
  70. package/dist/api/dto/node-events.d.ts +65 -0
  71. package/dist/api/dto/node-events.js +4 -0
  72. package/dist/api/dto/node-outcomes.d.ts +88 -0
  73. package/dist/api/dto/node-outcomes.js +2 -0
  74. package/dist/api/dto/node-records.d.ts +35 -0
  75. package/dist/api/dto/node-records.js +5 -0
  76. package/dist/api/dto/nodes.d.ts +368 -0
  77. package/dist/api/dto/nodes.js +3 -0
  78. package/dist/api/dto/objects.d.ts +172 -0
  79. package/dist/api/dto/objects.js +5 -0
  80. package/dist/api/dto/profiles.d.ts +117 -0
  81. package/dist/api/dto/profiles.js +4 -0
  82. package/dist/api/dto/recovery.d.ts +104 -0
  83. package/dist/api/dto/recovery.js +1 -0
  84. package/dist/api/dto/reports.d.ts +93 -0
  85. package/dist/api/dto/reports.js +2 -0
  86. package/dist/api/dto/review-comments.d.ts +146 -0
  87. package/dist/api/dto/review-comments.js +5 -0
  88. package/dist/api/dto/reviews.d.ts +113 -0
  89. package/dist/api/dto/reviews.js +5 -0
  90. package/dist/api/dto/run-events.d.ts +293 -0
  91. package/dist/api/dto/run-events.js +6 -0
  92. package/dist/api/dto/subscriptions.d.ts +14 -0
  93. package/dist/api/dto/subscriptions.js +2 -0
  94. package/dist/api/dto/worktree.d.ts +55 -0
  95. package/dist/api/dto/worktree.js +6 -0
  96. package/dist/api/error-codes.d.ts +254 -0
  97. package/dist/api/error-codes.js +54 -0
  98. package/dist/api/errors.d.ts +47 -0
  99. package/dist/api/errors.js +66 -0
  100. package/dist/api/index.d.ts +42 -0
  101. package/dist/api/index.js +41 -0
  102. package/dist/api/node-transport.d.ts +18 -0
  103. package/dist/api/node-transport.js +105 -0
  104. package/dist/api/plugin-manifest-schema.d.ts +233 -0
  105. package/dist/api/plugin-manifest-schema.js +23 -0
  106. package/dist/api/routes.d.ts +160 -0
  107. package/dist/api/routes.js +193 -0
  108. package/dist/shared/generated-context.d.ts +79 -0
  109. package/dist/shared/generated-context.js +232 -0
  110. package/dist/shared/predicates.d.ts +2 -0
  111. package/dist/shared/predicates.js +4 -0
  112. package/package.json +49 -0
@@ -0,0 +1,184 @@
1
+ export type AnalyticsWindow = '24h' | '7d';
2
+ export interface AnalyticsQuery {
3
+ as_of: string;
4
+ window: AnalyticsWindow;
5
+ project?: string;
6
+ }
7
+ export type MeasureDTO<T> = {
8
+ ok: true;
9
+ value: T;
10
+ } | {
11
+ ok: false;
12
+ reason: string;
13
+ };
14
+ export interface AnalyticsDTO {
15
+ as_of: string;
16
+ window_start: string;
17
+ window: AnalyticsWindow;
18
+ project: string | null;
19
+ projects: Array<{
20
+ cwd: string;
21
+ api_price_estimate: number;
22
+ }>;
23
+ transcripts: {
24
+ total: number;
25
+ read: number;
26
+ unreadable: Array<{
27
+ node_id: string;
28
+ reason: 'file missing' | 'unreadable' | 'parse error';
29
+ }>;
30
+ } | null;
31
+ unknown_responses: number | null;
32
+ oldest_agent_created: string | null;
33
+ memory_log_started_at: string | null;
34
+ agents: AgentRowDTO[];
35
+ graphs: MeasureDTO<GraphsDTO>;
36
+ time: MeasureDTO<TimeDTO>;
37
+ usage: MeasureDTO<UsageDTO>;
38
+ memory: MeasureDTO<{
39
+ read: MemoryViewDTO;
40
+ loaded: MemoryViewDTO;
41
+ }>;
42
+ }
43
+ export interface AgentRowDTO {
44
+ node_id: string;
45
+ name: string;
46
+ kind: string;
47
+ graph_id: string;
48
+ in_graph_detail: boolean;
49
+ parent: string | null;
50
+ depth: number;
51
+ created: string;
52
+ finalized_at: string | null;
53
+ lifecycle: 'resident' | 'terminal';
54
+ active: boolean;
55
+ spawned_in_window: boolean;
56
+ finished_in_window: boolean;
57
+ agent_time_ms: number | null;
58
+ api_price_estimate: number;
59
+ tokens: number;
60
+ responses: number;
61
+ response_times_ms: number[];
62
+ final_report_ref: string | null;
63
+ }
64
+ export interface GraphRowDTO {
65
+ graph_id: string;
66
+ name: string;
67
+ root_deleted: boolean;
68
+ cwd: string;
69
+ root_kind: string;
70
+ root_lifecycle: 'resident' | 'terminal';
71
+ root_created: string;
72
+ active_agents: number;
73
+ depth: number;
74
+ api_price_estimate: number;
75
+ tokens: number;
76
+ spawned_kinds: string[];
77
+ }
78
+ export interface GraphsDTO {
79
+ count: number;
80
+ spawned: number;
81
+ deepest: number;
82
+ graphs: GraphRowDTO[];
83
+ size_buckets: Array<{
84
+ label: '1' | '2–5' | '6–10' | '11–20' | '21+';
85
+ graphs: number;
86
+ }>;
87
+ spawned_by_kind: Array<{
88
+ kind: string;
89
+ agents: number;
90
+ }>;
91
+ }
92
+ export interface DurationStatsDTO {
93
+ count: number;
94
+ p10_ms: number;
95
+ median_ms: number;
96
+ p90_ms: number;
97
+ max_ms: number;
98
+ }
99
+ export interface TimeDTO {
100
+ all: DurationStatsDTO | null;
101
+ by_kind: Array<{
102
+ kind: string;
103
+ } & DurationStatsDTO>;
104
+ activity: {
105
+ bucket_ms: number;
106
+ buckets: Array<{
107
+ start: string;
108
+ agents: number;
109
+ }>;
110
+ max: number;
111
+ };
112
+ }
113
+ export interface ModelKeyDTO {
114
+ provider: string;
115
+ model: string;
116
+ }
117
+ export interface ModelRowDTO extends ModelKeyDTO {
118
+ responses: number;
119
+ api_price_estimate: number;
120
+ tokens: number;
121
+ tokens_by_type: {
122
+ cache_read: number;
123
+ cache_write: number;
124
+ input: number;
125
+ output: number;
126
+ };
127
+ cache_read_share: number;
128
+ context: {
129
+ median: number;
130
+ p90: number;
131
+ max: number;
132
+ buckets: [number, number, number, number, number];
133
+ };
134
+ }
135
+ export interface UsageDTO {
136
+ api_price_estimate: number;
137
+ tokens: number;
138
+ median_context: number | null;
139
+ models: ModelRowDTO[];
140
+ legend: ModelKeyDTO[];
141
+ kinds: Array<{
142
+ kind: string;
143
+ api_price_estimate: number;
144
+ tokens: number;
145
+ responses_by_model: Array<ModelKeyDTO & {
146
+ responses: number;
147
+ }>;
148
+ }>;
149
+ }
150
+ export interface MemoryDocRowDTO {
151
+ name: string;
152
+ scope: string;
153
+ reads: number;
154
+ agents: number;
155
+ graphs: number;
156
+ readers_by_kind: Array<{
157
+ kind: string;
158
+ agents: number;
159
+ }>;
160
+ readers: Array<{
161
+ node_id: string;
162
+ kind: string;
163
+ name: string;
164
+ graph_id: string;
165
+ reads: number;
166
+ first_at: string;
167
+ }>;
168
+ }
169
+ export interface MemoryViewDTO {
170
+ entries: number;
171
+ documents: number;
172
+ agents_with_entry: number;
173
+ active_agents: number;
174
+ rows: MemoryDocRowDTO[];
175
+ }
176
+ export interface MemoryReadEventDTO {
177
+ name: string;
178
+ scope: string;
179
+ at: string;
180
+ type: 'read' | 'loaded';
181
+ }
182
+ export interface MemoryReadsRequestDTO {
183
+ events: MemoryReadEventDTO[];
184
+ }
@@ -0,0 +1,3 @@
1
+ // Analytics page contract: `GET /v1/canvas/analytics` and
2
+ // `POST /v1/nodes/:id/memory-reads`. crtrd computes every number; the page only sorts, folds, bins, and formats.
3
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { NodeIdDTO } from './common.js';
2
+ /** `POST /v1/nodes/{id}/attach` body (local ensure). */
3
+ export interface AttachEnsureRequest {
4
+ /** Resume saved history on revive (default true). */
5
+ resume?: boolean;
6
+ /** Revive if dormant (default true); false returns a possibly-dead socket. */
7
+ revive?: boolean;
8
+ /** Wake an exact unfinalized parked resident (default true). Focus/navigation
9
+ * sets false so it can open the saved conversation without launching. */
10
+ wakeParked?: boolean;
11
+ }
12
+ /** Result of a local attach-ensure. */
13
+ export interface AttachEnsureResultDTO {
14
+ node_id: NodeIdDTO;
15
+ /** Host-local path to the node's broker `view.sock`. */
16
+ socket_path: string;
17
+ revived: boolean;
18
+ resumed: boolean;
19
+ /** True when a non-waking focus ensure found an exact parked resident with no
20
+ * live broker. `socket_path` is then the target the viewer will later redial. */
21
+ parked: boolean;
22
+ }
@@ -0,0 +1,13 @@
1
+ // Attach DTOs (spec §5). Two shapes, one concept:
2
+ //
3
+ // - `POST /v1/nodes/{id}/attach` (LOCAL) — crtrd revives (unless opted out) and
4
+ // returns `socket_path`; the local viewer then connects to `view.sock`
5
+ // directly with the existing `ViewSocketClient`. Meaningful only over the
6
+ // unix socket (the path is host-local). This is `ensureAttach()` on the client.
7
+ //
8
+ // - `GET /v1/nodes/{id}/attach` with `Upgrade: websocket` (REMOTE) — crtrd
9
+ // bridges the WS ⇄ the node's `view.sock` byte-for-byte, one WS per node.
10
+ // Opened DIRECTLY against the URL, NOT via a `CrtrClient` method. Opt out of
11
+ // the implicit revive with `?revive=0` or header `X-Crtr-Attach-Revive: 0`;
12
+ // a dormant node with revive opted out refuses the upgrade with 409.
13
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { IsoTime, NodeIdDTO } from './common.js';
2
+ /** A still-live background bash job owned by one node. */
3
+ export interface BashJobStatusDTO {
4
+ job_id: string;
5
+ command: string;
6
+ /** Human-readable label supplied with the bash call, or null when absent. */
7
+ purpose: string | null;
8
+ started_at: IsoTime;
9
+ elapsed_ms: number;
10
+ /** Persisted supervisor process group, or null for legacy jobs. */
11
+ pgid: number | null;
12
+ /** Whether the persisted process group currently exists. */
13
+ pgid_alive: boolean;
14
+ }
15
+ /** Result of stopping one background bash job. `signaled` is false when the
16
+ * process group had already exited, but the job is still retired via its exit
17
+ * sentinel. */
18
+ export interface BashJobStopResultDTO {
19
+ node_id: NodeIdDTO;
20
+ job_id: string;
21
+ signaled: boolean;
22
+ }
23
+ /** Whether a job id is safe to interpolate as one API/filesystem segment. */
24
+ export declare function isSafeBashJobId(jobId: string): boolean;
@@ -0,0 +1,9 @@
1
+ // Background bash job API shapes. The daemon projects the file-backed job
2
+ // control plane into these dependency-light DTOs for remote presenters.
3
+ /** Whether a job id is safe to interpolate as one API/filesystem segment. */
4
+ export function isSafeBashJobId(jobId) {
5
+ return typeof jobId === 'string'
6
+ && jobId !== '' && jobId !== '.' && jobId !== '..'
7
+ && /^[A-Za-z0-9._~-]+$/u.test(jobId)
8
+ && Buffer.byteLength(jobId, 'utf8') <= 128;
9
+ }
@@ -0,0 +1,17 @@
1
+ export interface BashRunParams {
2
+ command: string;
3
+ cwd: string;
4
+ timeout_s?: number;
5
+ env?: Record<string, string>;
6
+ profile?: string;
7
+ }
8
+ export interface BashRunDTO {
9
+ exit_code: number | null;
10
+ signal: string | null;
11
+ stdout: string;
12
+ stdout_truncated: boolean;
13
+ stderr: string;
14
+ stderr_truncated: boolean;
15
+ timed_out: boolean;
16
+ duration_ms: number;
17
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,187 @@
1
+ import type { ExitIntentDTO, NodeStatusDTO } from './common.js';
2
+ import type { NodeSubjectDTO } from './nodes.js';
3
+ /** `POST /v1/nodes/{id}/broker/session-bound` body. Pi's session-start reason
4
+ * distinguishes an ordinary boot/resume from `/new`, whose child-side session
5
+ * reset is a different durable operation. `reviewBoundaryIds` reports only the
6
+ * review markers visible in Pi's current branch; crtrd owns the node binding
7
+ * used to decide whether that branch is valid. */
8
+ export interface BrokerSessionBoundRequest {
9
+ executionId: string;
10
+ piSessionId: string;
11
+ sessionFile: string | null;
12
+ pid: number;
13
+ reason: string | null;
14
+ reviewBoundaryIds: string[];
15
+ }
16
+ /** Pi-side consequence selected by crtrd after binding the session. The
17
+ * handler itself never calls back into the broker while servicing the request. */
18
+ export interface BrokerSessionBoundResultDTO {
19
+ action: 'none' | 'relaunch_root' | 'shutdown';
20
+ }
21
+ /** `POST /v1/nodes/{id}/broker/settle` body. These are the facts only Pi can
22
+ * know at its settlement boundary; crtrd reads all current canvas state and
23
+ * selects the durable consequence. */
24
+ export interface BrokerExecutionRequest {
25
+ expected_execution_id: string;
26
+ }
27
+ export interface BrokerSettleRequest extends BrokerExecutionRequest {
28
+ stopReason: string;
29
+ backgroundJobsRunning: boolean;
30
+ pushedFinal: boolean;
31
+ }
32
+ /** `POST /v1/nodes/{id}/broker/telemetry` body. Tokens are cumulative within
33
+ * the broker's current Pi session; null context/activity values preserve the
34
+ * last usable value in the daemon projection, matching telemetry.json. */
35
+ export interface BrokerTelemetryRequest extends BrokerExecutionRequest {
36
+ tokens_in: number;
37
+ tokens_out: number;
38
+ model: string;
39
+ context_tokens: number | null;
40
+ last_activity: string | null;
41
+ updated_at: string;
42
+ }
43
+ /** The only consequence a settle caller may enact. crtrd has already committed
44
+ * every canvas and placement effect before returning this directive. */
45
+ export type BrokerSettleDirective = {
46
+ action: 'reprompt';
47
+ prompt: string;
48
+ } | {
49
+ action: 'stay_dormant';
50
+ } | {
51
+ action: 'shutdown';
52
+ };
53
+ /** A main-engine input has won broker admission while a parking summary may be
54
+ * in flight. crtrd records it against the process-local pending marker before
55
+ * Pi begins the input, making parking completion and input admission atomic. */
56
+ export interface BrokerParkActivityResultDTO {
57
+ activity: 'recorded' | 'none';
58
+ }
59
+ /** `POST /v1/nodes/{id}/broker/park-complete` body. The isolated parking turn
60
+ * has ended; crtrd alone decides whether its pending park still applies. */
61
+ export interface BrokerParkCompleteRequest extends BrokerExecutionRequest {
62
+ outcome: 'completed' | 'failed';
63
+ }
64
+ /** Durable model recipe selected by the live broker after Pi accepts a model or thinking change. */
65
+ export interface BrokerModelCommitRequest extends BrokerExecutionRequest {
66
+ spec: string;
67
+ /** Portable routing contract for a user-selected change; absent means exact. */
68
+ intent?: {
69
+ family: string;
70
+ strength: 'ultra' | 'strong' | 'medium' | 'light';
71
+ };
72
+ userSelected: boolean;
73
+ }
74
+ export interface BrokerModelCommitResultDTO {
75
+ modelOverride: string;
76
+ }
77
+ /** The dependency-light identity/runtime projection broker extensions need to
78
+ * render their local Pi hooks without reading canvas.db themselves. */
79
+ export interface BrokerExtensionNodeDTO {
80
+ node_id: string;
81
+ grantee: string;
82
+ name: string;
83
+ description?: string;
84
+ title?: string;
85
+ icon?: string;
86
+ kind: string;
87
+ mode: 'base' | 'orchestrator';
88
+ lifecycle: 'terminal' | 'resident';
89
+ status: NodeStatusDTO;
90
+ cwd: string;
91
+ parent: string | null;
92
+ fork_from: string | null;
93
+ profile_id: string | null;
94
+ managed_worktree?: {
95
+ state: 'open' | 'closed' | 'abandoned';
96
+ cleanup?: 'pending' | 'complete';
97
+ path: string;
98
+ branch: string;
99
+ base_ref: string;
100
+ base_sha: string;
101
+ } | null;
102
+ review_binding?: {
103
+ kind?: 'review' | 'page_feedback';
104
+ review_id: string;
105
+ origin_node_id: string;
106
+ branch_file: string;
107
+ target_file: string;
108
+ } | null;
109
+ intent: ExitIntentDTO;
110
+ /** `kind` is absent on rows written before kind joined the drift key; a read
111
+ * resolves it to the node's current kind. */
112
+ persona_ack?: {
113
+ kind?: string;
114
+ mode: 'base' | 'orchestrator';
115
+ lifecycle: 'terminal' | 'resident';
116
+ };
117
+ created: string;
118
+ }
119
+ export type BrokerExtensionSubjectDTO = NodeSubjectDTO;
120
+ /** One resolved report sender. Report contents stay broker-local filesystem
121
+ * data; this daemon projection supplies only existence and display metadata. */
122
+ export interface BrokerReportNodeDTO {
123
+ node_id: string;
124
+ grantee: string;
125
+ name: string;
126
+ created: string;
127
+ }
128
+ /** `GET /v1/nodes/{id}/broker/extension-state`. This is deliberately a fixed
129
+ * extension rendering projection, not a generic node/state read API. */
130
+ export interface BrokerExtensionStateDTO {
131
+ node: BrokerExtensionNodeDTO;
132
+ warm_spare: boolean;
133
+ ancestors: BrokerExtensionNodeDTO[];
134
+ children: BrokerExtensionNodeDTO[];
135
+ fork_source: BrokerExtensionNodeDTO | null;
136
+ subject: BrokerExtensionSubjectDTO;
137
+ report_nodes: BrokerReportNodeDTO[];
138
+ /** The head body of the node's `roadmap` document, or null when it has none. */
139
+ roadmap: string | null;
140
+ }
141
+ /** Guarded generated-label update. `initial` can only fill a blank generated
142
+ * description; `recap` additionally compares the exact automatic-name snapshot
143
+ * captured before the headless naming call. */
144
+ export type BrokerGeneratedNameRequest = BrokerExecutionRequest & ({
145
+ kind: 'initial';
146
+ description: string;
147
+ title: string;
148
+ icon: string;
149
+ } | {
150
+ kind: 'recap';
151
+ description: string;
152
+ title: string;
153
+ icon: string;
154
+ expected: {
155
+ name: string;
156
+ description: string;
157
+ title: string;
158
+ icon: string;
159
+ kind: string;
160
+ };
161
+ });
162
+ /** A daemon-selected Pi editor-label directive. No handler calls a broker.
163
+ * `description`/`title`/`icon` are the values as STORED (an empty title or icon
164
+ * is left unset), so the broker announces what the node now carries rather than
165
+ * what it asked for. All four are present exactly when `applied`. */
166
+ export interface BrokerGeneratedNameResultDTO {
167
+ applied: boolean;
168
+ editorLabel?: string;
169
+ description?: string;
170
+ title?: string;
171
+ icon?: string;
172
+ }
173
+ export interface BrokerPersonaAckRequest extends BrokerExecutionRequest {
174
+ from: {
175
+ kind: string;
176
+ mode: 'base' | 'orchestrator';
177
+ lifecycle: 'terminal' | 'resident';
178
+ };
179
+ to: {
180
+ kind: string;
181
+ mode: 'base' | 'orchestrator';
182
+ lifecycle: 'terminal' | 'resident';
183
+ };
184
+ }
185
+ export interface BrokerPersonaAckResultDTO {
186
+ applied: boolean;
187
+ }
@@ -0,0 +1,6 @@
1
+ // Broker-to-daemon operation DTOs. These requests are emitted by a broker Pi
2
+ // extension, but are handled exclusively by crtrd so canvas state keeps one
3
+ // owner.
4
+ //
5
+ // PURITY (spec §3.1): Node built-ins + `src/api/*` only.
6
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { BrokerExtensionNodeDTO } from './broker-ops.js';
2
+ /** Ephemeral hints only; consumers resync from durable rows on every hello. */
3
+ export type BrokerSignalLineDTO = {
4
+ type: 'hello';
5
+ epoch: string;
6
+ execution_id: string;
7
+ node: BrokerExtensionNodeDTO;
8
+ at: number;
9
+ } | {
10
+ type: 'mail';
11
+ channel: 'wake';
12
+ at: number;
13
+ } | {
14
+ type: 'node';
15
+ node: BrokerExtensionNodeDTO;
16
+ at: number;
17
+ }
18
+ /** The daemon found a pending provider retry with no live timer: re-run the broker's own retry scheduling. */
19
+ | {
20
+ type: 'fault-retry';
21
+ at: number;
22
+ } | {
23
+ type: 'ping';
24
+ at: number;
25
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,86 @@
1
+ /**
2
+ * The crtrd broker `error` control frame — `{ code, message, id? }`. `id` is a
3
+ * correlation token echoed only from the request that failed (a read-op /
4
+ * `dequeue`); absent on uncorrelated errors. There is NO `retryable` field.
5
+ */
6
+ export interface BrokerErrorFrame {
7
+ type: 'error';
8
+ code: string;
9
+ message: string;
10
+ /** Correlation token, echoed from the failed request; absent on uncorrelated errors. */
11
+ id?: string;
12
+ }
13
+ /**
14
+ * The `welcome` frame's history/state snapshot, narrowed to what a relay consumer
15
+ * replays: the message history, the streaming flag, and the unrun queue. `M` is
16
+ * the message shape (pi's `AgentMessage` in a pi consumer; `unknown` by default).
17
+ *
18
+ * `queued` carries the same two arrays a live `queue_update` frame carries — the
19
+ * steer/follow-up texts accepted by the engine but not started yet. A relay that
20
+ * renders queued rows needs it to survive (re)attach: a message enqueued mid-turn
21
+ * is in NEITHER `messages` (it never ran) nor any later frame the consumer has
22
+ * already seen. Optional: a broker on an older runtime generation omits it, which
23
+ * a consumer reads as an empty queue.
24
+ */
25
+ export interface BrokerWelcomeSnapshot<M = unknown> {
26
+ messages: M[];
27
+ /** Stable session-entry ids aligned 1:1 with `messages`. */
28
+ messageIds?: string[];
29
+ /** Presentation visibility aligned 1:1 with `messages`. */
30
+ messageVisibility: Array<'visible' | 'internal'>;
31
+ /** Presentation visibility of the run currently owned by the engine. */
32
+ turnVisibility: 'visible' | 'internal';
33
+ state?: {
34
+ isStreaming?: boolean;
35
+ };
36
+ queued?: {
37
+ steering?: string[];
38
+ followUp?: string[];
39
+ };
40
+ }
41
+ /**
42
+ * The crtrd broker `welcome` control frame — the history/resume catch-up snapshot
43
+ * delivered on (re)attach.
44
+ */
45
+ export interface BrokerWelcomeFrame<M = unknown> {
46
+ type: 'welcome';
47
+ snapshot?: BrokerWelcomeSnapshot<M>;
48
+ }
49
+ /**
50
+ * The crtrd broker `node_named` control frame — the node's generated name at the
51
+ * instant crtrd committed it.
52
+ *
53
+ * A node names itself off its first real message: the naming extension asks a
54
+ * headless model for a handle, commits it through crtrd's guarded compare-and-set,
55
+ * and pushes this frame down the attach stream in the same callback. It is sent
56
+ * ONLY when that guarded commit APPLIED, so a name a human already set is never
57
+ * announced as generated.
58
+ *
59
+ * It exists because the name lands SECONDS AFTER the turn that triggered it — a
60
+ * consumer that settles its own display state on turn-end reads an unnamed node and
61
+ * has nothing left to re-read on. This frame is the push: `description` is the
62
+ * 3-8 word kebab-case handle, `title` the prose sentence a conversation list
63
+ * shows, `icon` the Nerd Font glyph the namer chose (empty when it chose none),
64
+ * and `editorLabel` crtrd's own rendered label for the node.
65
+ */
66
+ export interface BrokerNodeNamedFrame {
67
+ type: 'node_named';
68
+ description: string;
69
+ title: string;
70
+ icon: string;
71
+ editorLabel: string;
72
+ }
73
+ /**
74
+ * The broker-control frames a relay consumer reads: `welcome`, `error`, and
75
+ * `node_named`. The broker interleaves others (display_*, ack, …)
76
+ * under non-colliding `type` discriminants; a relay mapper drops those through its
77
+ * `default` arm untyped, so they are not enumerated here.
78
+ */
79
+ export type BrokerControlFrame<M = unknown> = BrokerWelcomeFrame<M> | BrokerErrorFrame | BrokerNodeNamedFrame;
80
+ /**
81
+ * What the crtrd broker attach delivers to a relay consumer: the live engine
82
+ * event stream (`E` — pi's `AgentSessionEvent`, relayed verbatim) unioned with the
83
+ * broker's own control frames. Discriminants never collide: an `AgentSessionEvent`
84
+ * owns no `welcome` / `error` `type`.
85
+ */
86
+ export type BrokerAttachFrame<E, M = unknown> = E | BrokerControlFrame<M>;
@@ -0,0 +1,20 @@
1
+ // Broker attach-protocol envelope DTOs — the crtrd-specific control frames the
2
+ // broker interleaves around pi's native agent-session event stream over a node's
3
+ // `view.sock` (and its WS bridge, spec §5). This module owns ONLY that envelope
4
+ // vocabulary: the broker-control frames a relay consumer reads, the welcome
5
+ // snapshot they carry, and the relay union that folds them
6
+ // together with the live engine event stream.
7
+ //
8
+ // PURITY (spec §3.1): like every file under `src/api/`, this imports NOTHING —
9
+ // not `core/*`, not pi. The live engine event type (pi's `AgentSessionEvent`)
10
+ // and the snapshot message type (pi's `AgentMessage`) are left as TYPE PARAMETERS
11
+ // so a consumer instantiates them with the exact pi shapes it pins, while this
12
+ // package stays zero-dependency. A pi-free consumer can leave them at their
13
+ // `unknown` defaults.
14
+ //
15
+ // NARROWING NOTE: `BrokerWelcomeSnapshot` is deliberately the fields a live/history
16
+ // relay mapper reads — `messages`, `state.isStreaming`, and the unrun `queued`
17
+ // texts — not the broker's full authoritative `BrokerSnapshot` (stats + the
18
+ // complete `get_state` mirror). The broker sends the richer object on the wire;
19
+ // consumers that only replay history read this narrowing of it.
20
+ export {};