@north-light/crouter-api 0.3.173 → 0.3.175
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/__tests__/{client.test.js → serial/client.test.js} +2 -135
- package/dist/client.d.ts +12 -21
- package/dist/client.js +22 -31
- package/dist/dto/broker-ops.d.ts +158 -0
- package/dist/dto/broker-ops.js +6 -0
- package/dist/dto/crons.d.ts +6 -0
- package/dist/dto/human.d.ts +7 -1
- package/dist/dto/inbox.d.ts +1 -71
- package/dist/dto/inbox.js +1 -9
- package/dist/dto/nodes.d.ts +6 -7
- package/dist/dto/reviews.d.ts +1 -11
- package/dist/routes.d.ts +7 -4
- package/dist/routes.js +8 -5
- package/package.json +1 -1
- /package/dist/__tests__/{client.test.d.ts → serial/client.test.d.ts} +0 -0
|
@@ -14,8 +14,8 @@ import { createServer } from 'node:http';
|
|
|
14
14
|
import { mkdtempSync, rmSync } from 'node:fs';
|
|
15
15
|
import { tmpdir } from 'node:os';
|
|
16
16
|
import { join } from 'node:path';
|
|
17
|
-
import { coldStartTimeoutMessage, CrtrClient, safeColdStartDiagnostic } from '
|
|
18
|
-
import { ApiError } from '
|
|
17
|
+
import { coldStartTimeoutMessage, CrtrClient, safeColdStartDiagnostic } from '../../client.js';
|
|
18
|
+
import { ApiError } from '../../errors.js';
|
|
19
19
|
test('coldStartTimeoutMessage appends a present diagnostic to the base message', () => {
|
|
20
20
|
const msg = coldStartTimeoutMessage('crtrd.err (tail):\nError: bind EADDRINUSE');
|
|
21
21
|
assert.match(msg, /crtrd did not start/);
|
|
@@ -139,136 +139,3 @@ test('safeColdStartDiagnostic treats a THROWING hook as absent, not a propagated
|
|
|
139
139
|
throw new Error('custom hook blew up');
|
|
140
140
|
}), undefined);
|
|
141
141
|
});
|
|
142
|
-
/** Spin a loopback server on a temp unix socket that records every request and
|
|
143
|
-
* replies with `respond(req)`. `respond` returning `undefined` means "handler
|
|
144
|
-
* not reached for this call" and is never exercised by these tests. */
|
|
145
|
-
async function startCapturingServer(respond) {
|
|
146
|
-
const dir = mkdtempSync(join(tmpdir(), 'crtr-client-inbox-'));
|
|
147
|
-
const socketPath = join(dir, 'crtrd.sock');
|
|
148
|
-
const requests = [];
|
|
149
|
-
const server = createServer((req, res) => {
|
|
150
|
-
const chunks = [];
|
|
151
|
-
req.on('data', (chunk) => chunks.push(chunk));
|
|
152
|
-
req.on('end', () => {
|
|
153
|
-
const raw = Buffer.concat(chunks).toString('utf8');
|
|
154
|
-
const body = raw.trim() === '' ? undefined : JSON.parse(raw);
|
|
155
|
-
const captured = { method: req.method ?? '', path: req.url ?? '', body };
|
|
156
|
-
requests.push(captured);
|
|
157
|
-
const { status, body: resBody } = respond(captured);
|
|
158
|
-
res.writeHead(status, { 'content-type': 'application/json' });
|
|
159
|
-
res.end(JSON.stringify(resBody));
|
|
160
|
-
});
|
|
161
|
-
});
|
|
162
|
-
await new Promise((resolvePromise) => server.listen(socketPath, resolvePromise));
|
|
163
|
-
const client = new CrtrClient({ socketPath, autostart: false });
|
|
164
|
-
return {
|
|
165
|
-
client,
|
|
166
|
-
requests,
|
|
167
|
-
close: () => new Promise((resolvePromise, rejectPromise) => {
|
|
168
|
-
server.close((err) => (err ? rejectPromise(err) : resolvePromise()));
|
|
169
|
-
}).finally(() => rmSync(dir, { recursive: true, force: true })),
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
const SAMPLE_TICKET_ID = 'a'.repeat(64);
|
|
173
|
-
test('listHumanInbox sends GET /v1/human/inbox with no body and returns the parsed list', async () => {
|
|
174
|
-
const inboxList = { tickets: [{ ticket_id: SAMPLE_TICKET_ID, kind: 'deck', title: 'Approve deploy', blocked_since: '2026-01-01T00:00:00Z', source: {} }] };
|
|
175
|
-
const srv = await startCapturingServer(() => ({ status: 200, body: inboxList }));
|
|
176
|
-
try {
|
|
177
|
-
const result = await srv.client.listHumanInbox();
|
|
178
|
-
assert.deepEqual(result, inboxList);
|
|
179
|
-
assert.equal(srv.requests.length, 1);
|
|
180
|
-
assert.equal(srv.requests[0]?.method, 'GET');
|
|
181
|
-
assert.equal(srv.requests[0]?.path, '/v1/human/inbox');
|
|
182
|
-
assert.equal(srv.requests[0]?.body, undefined);
|
|
183
|
-
}
|
|
184
|
-
finally {
|
|
185
|
-
await srv.close();
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
test('getHumanInboxDeck sends GET /v1/human/inbox/:ticket_id with no body and returns the parsed deck', async () => {
|
|
189
|
-
const deck = { ticket_id: SAMPLE_TICKET_ID, kind: 'deck', deck: { title: 'Approve deploy', interactions: [] } };
|
|
190
|
-
const srv = await startCapturingServer(() => ({ status: 200, body: deck }));
|
|
191
|
-
try {
|
|
192
|
-
const result = await srv.client.getHumanInboxDeck(SAMPLE_TICKET_ID);
|
|
193
|
-
assert.deepEqual(result, deck);
|
|
194
|
-
assert.equal(srv.requests[0]?.method, 'GET');
|
|
195
|
-
assert.equal(srv.requests[0]?.path, `/v1/human/inbox/${SAMPLE_TICKET_ID}`);
|
|
196
|
-
assert.equal(srv.requests[0]?.body, undefined);
|
|
197
|
-
}
|
|
198
|
-
finally {
|
|
199
|
-
await srv.close();
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
test('respondHumanInboxDeck sends POST with the exact responses body and returns the canonical result unchanged', async () => {
|
|
203
|
-
const request = { responses: [{ id: 'notify', selectedOptionId: 'ok' }] };
|
|
204
|
-
const result = { schema: 'humanloop.response/v2', kind: 'deck', responses: request.responses, summary: 'Acknowledged', completedAt: '2026-01-01T00:00:00Z' };
|
|
205
|
-
const srv = await startCapturingServer(() => ({ status: 200, body: result }));
|
|
206
|
-
try {
|
|
207
|
-
const got = await srv.client.respondHumanInboxDeck(SAMPLE_TICKET_ID, request);
|
|
208
|
-
assert.deepEqual(got, result);
|
|
209
|
-
assert.equal(srv.requests[0]?.method, 'POST');
|
|
210
|
-
assert.equal(srv.requests[0]?.path, `/v1/human/inbox/${SAMPLE_TICKET_ID}/respond`);
|
|
211
|
-
assert.deepEqual(srv.requests[0]?.body, request);
|
|
212
|
-
}
|
|
213
|
-
finally {
|
|
214
|
-
await srv.close();
|
|
215
|
-
}
|
|
216
|
-
});
|
|
217
|
-
test('cancelHumanInboxTicket sends POST with the reason body when a request is passed', async () => {
|
|
218
|
-
const result = { schema: 'humanloop.cancel/v1', kind: 'canceled', canceledAt: '2026-01-01T00:00:00Z', reason: 'no longer needed', actor: 'human' };
|
|
219
|
-
const srv = await startCapturingServer(() => ({ status: 200, body: result }));
|
|
220
|
-
try {
|
|
221
|
-
const got = await srv.client.cancelHumanInboxTicket(SAMPLE_TICKET_ID, { reason: 'no longer needed' });
|
|
222
|
-
assert.deepEqual(got, result);
|
|
223
|
-
assert.equal(srv.requests[0]?.method, 'POST');
|
|
224
|
-
assert.equal(srv.requests[0]?.path, `/v1/human/inbox/${SAMPLE_TICKET_ID}/cancel`);
|
|
225
|
-
assert.deepEqual(srv.requests[0]?.body, { reason: 'no longer needed' });
|
|
226
|
-
}
|
|
227
|
-
finally {
|
|
228
|
-
await srv.close();
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
|
-
test('cancelHumanInboxTicket sends an empty object body when no request is passed', async () => {
|
|
232
|
-
const result = { schema: 'humanloop.cancel/v1', kind: 'canceled', canceledAt: '2026-01-01T00:00:00Z' };
|
|
233
|
-
const srv = await startCapturingServer(() => ({ status: 200, body: result }));
|
|
234
|
-
try {
|
|
235
|
-
const got = await srv.client.cancelHumanInboxTicket(SAMPLE_TICKET_ID);
|
|
236
|
-
assert.deepEqual(got, result);
|
|
237
|
-
assert.deepEqual(srv.requests[0]?.body, {});
|
|
238
|
-
}
|
|
239
|
-
finally {
|
|
240
|
-
await srv.close();
|
|
241
|
-
}
|
|
242
|
-
});
|
|
243
|
-
test('a non-2xx inbox error body decodes to a typed ApiError (status/code/message)', async () => {
|
|
244
|
-
const srv = await startCapturingServer(() => ({
|
|
245
|
-
status: 409,
|
|
246
|
-
body: { error: { code: 'ticket_kind_unsupported', message: 'review tickets have no v1 response operation' } },
|
|
247
|
-
}));
|
|
248
|
-
try {
|
|
249
|
-
await assert.rejects(() => srv.client.respondHumanInboxDeck(SAMPLE_TICKET_ID, { responses: [] }), (err) => {
|
|
250
|
-
assert.ok(err instanceof ApiError);
|
|
251
|
-
assert.equal(err.status, 409);
|
|
252
|
-
assert.equal(err.code, 'ticket_kind_unsupported');
|
|
253
|
-
assert.match(err.message, /review tickets have no v1 response operation/);
|
|
254
|
-
return true;
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
finally {
|
|
258
|
-
await srv.close();
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
test('a malformed local ticket id throws a synchronous TypeError and never reaches the transport', async () => {
|
|
262
|
-
const srv = await startCapturingServer(() => {
|
|
263
|
-
throw new Error('handler must never be invoked for a locally-rejected ticket id');
|
|
264
|
-
});
|
|
265
|
-
try {
|
|
266
|
-
assert.throws(() => srv.client.getHumanInboxDeck('not-a-valid-hash'), TypeError);
|
|
267
|
-
assert.throws(() => srv.client.respondHumanInboxDeck('short', { responses: [] }), TypeError);
|
|
268
|
-
assert.throws(() => srv.client.cancelHumanInboxTicket('UPPERCASE'.repeat(7)), TypeError);
|
|
269
|
-
assert.equal(srv.requests.length, 0);
|
|
270
|
-
}
|
|
271
|
-
finally {
|
|
272
|
-
await srv.close();
|
|
273
|
-
}
|
|
274
|
-
});
|
package/dist/client.d.ts
CHANGED
|
@@ -5,18 +5,19 @@ import type { PushReportRequest, PushReportResultDTO, ReportDTO, ReportsQuery }
|
|
|
5
5
|
import type { CloseRequest, CloseResultDTO, PromoteRequest, RelaunchRootResultDTO, ReviveRequest, ReviveResultDTO, WaitRequest, YieldRequest } from './dto/lifecycle.js';
|
|
6
6
|
import type { SubscribeRequest, SubscriptionDTO } from './dto/subscriptions.js';
|
|
7
7
|
import type { FocusDTO, RegisterFocusRequest, SetFocusPaneRequest } from './dto/focus.js';
|
|
8
|
-
import { type ArmCronRequest, type CronDTO, type CronRunDTO, type CronScopeQuery, type CronShowDTO, type ListCronsQuery } from './dto/crons.js';
|
|
8
|
+
import { type ArmCronRequest, type CancelCronQuery, type CronDTO, type CronRunDTO, type CronScopeQuery, type CronShowDTO, type ListCronsQuery } from './dto/crons.js';
|
|
9
9
|
import type { NodeConfigPatch } from './dto/config.js';
|
|
10
10
|
import type { AttachEnsureRequest, AttachEnsureResultDTO } from './dto/attach.js';
|
|
11
11
|
import type { EnsureProfileRequest, ProfileDTO } from './dto/profiles.js';
|
|
12
12
|
import type { FilePeekDTO } from './dto/files.js';
|
|
13
13
|
import type { CredentialRemovalResultDTO, CredentialResultDTO, InstallCredentialRequest, ModelAuthListDTO } from './dto/modelauth.js';
|
|
14
14
|
import type { CreateHumanBridgeRequest, HumanBridgeResultDTO, HumanCancelRequest, HumanCancelResultDTO, HumanResolveRequest, HumanResolveResultDTO } from './dto/human.js';
|
|
15
|
-
import type { CancelReviewRequest, CreateReviewRequest, ListReviewsQuery, ReviewCancelResultDTO, ReviewDocumentBaseDTO, ReviewDTO, ReviewListDTO,
|
|
15
|
+
import type { CancelReviewRequest, CreateReviewRequest, ListReviewsQuery, ReviewCancelResultDTO, ReviewDocumentBaseDTO, ReviewDTO, ReviewListDTO, ReviewSubmitResultDTO } from './dto/reviews.js';
|
|
16
16
|
import type { CreateReviewCommentRequest, EditReviewCommentRequest, ListReviewCommentsQuery, ReadReviewCommentEventsQuery, ReviewCommentActionRequest, ReviewCommentDetailDTO, ReviewCommentEventsDTO, ReviewCommentListDTO, ReviewCommentMutationDTO, ReviewCommentRangeBatchRequest, ReviewCommentRangeBatchResultDTO } from './dto/review-comments.js';
|
|
17
|
-
import type {
|
|
17
|
+
import type { InboxListDTO } from './dto/inbox.js';
|
|
18
18
|
import type { AttentionCountsDTO, AttentionDTO, DashboardDTO, DashboardQuery, HistoryGrepQuery, HistoryGrepResultDTO, HistoryReadQuery, HistoryReadResultDTO, HistorySearchQuery, HistorySearchResultDTO, PruneRequest, PruneResultDTO, RebuildIndexResultDTO, RosterDTO, SnapshotDTO } from './dto/canvas.js';
|
|
19
19
|
import type { CloseWorktreeResultDTO } from './dto/worktree.js';
|
|
20
|
+
import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerInboxCursorDirective, BrokerInboxCursorRequest, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerPersonaAckRequest, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest } from './dto/broker-ops.js';
|
|
20
21
|
export interface CrtrClientOptions {
|
|
21
22
|
/** Unix socket path (default local transport). Exactly one of socketPath|baseUrl. */
|
|
22
23
|
socketPath?: string;
|
|
@@ -86,6 +87,13 @@ export declare class CrtrClient {
|
|
|
86
87
|
forkNode(id: string): Promise<NodeDetailDTO>;
|
|
87
88
|
reviveNode(id: string, req?: ReviveRequest): Promise<ReviveResultDTO>;
|
|
88
89
|
relaunchRoot(id: string): Promise<RelaunchRootResultDTO>;
|
|
90
|
+
bindBrokerSession(id: string, req: BrokerSessionBoundRequest): Promise<BrokerSessionBoundResultDTO>;
|
|
91
|
+
settleBroker(id: string, req: BrokerSettleRequest): Promise<BrokerSettleDirective>;
|
|
92
|
+
advanceBrokerInboxCursor(id: string, req: BrokerInboxCursorRequest): Promise<BrokerInboxCursorDirective>;
|
|
93
|
+
commitBrokerModel(id: string, req: BrokerModelCommitRequest): Promise<BrokerModelCommitResultDTO>;
|
|
94
|
+
brokerExtensionState(id: string): Promise<BrokerExtensionStateDTO>;
|
|
95
|
+
commitBrokerGeneratedName(id: string, req: BrokerGeneratedNameRequest): Promise<BrokerGeneratedNameResultDTO>;
|
|
96
|
+
commitBrokerPersonaAck(id: string, req: BrokerPersonaAckRequest): Promise<void>;
|
|
89
97
|
closeNode(id: string, req?: CloseRequest): Promise<CloseResultDTO>;
|
|
90
98
|
recycleNode(id: string): Promise<NodeDetailDTO>;
|
|
91
99
|
demoteNode(id: string): Promise<NodeDetailDTO>;
|
|
@@ -122,7 +130,7 @@ export declare class CrtrClient {
|
|
|
122
130
|
* advance the schedule or consume a one-shot; never escalates. */
|
|
123
131
|
runCron(cronId: string, q?: CronScopeQuery): Promise<CronRunDTO>;
|
|
124
132
|
/** Cancel one cron (`DELETE /v1/crons/:cronId`, idempotent). */
|
|
125
|
-
cancelCron(cronId: string, q?:
|
|
133
|
+
cancelCron(cronId: string, q?: CancelCronQuery): Promise<void>;
|
|
126
134
|
ensureAttach(id: string, req?: AttachEnsureRequest): Promise<AttachEnsureResultDTO>;
|
|
127
135
|
getReports(id: string, q?: ReportsQuery): Promise<ReportDTO[]>;
|
|
128
136
|
getTranscript(id: string, q?: TranscriptQuery): Promise<TranscriptDTO>;
|
|
@@ -159,7 +167,6 @@ export declare class CrtrClient {
|
|
|
159
167
|
listReviews(query?: ListReviewsQuery): Promise<ReviewListDTO>;
|
|
160
168
|
getReview(reviewId: string): Promise<ReviewDTO>;
|
|
161
169
|
getReviewByBridge(bridgeNodeId: string): Promise<ReviewDTO>;
|
|
162
|
-
openReview(reviewId: string): Promise<ReviewOpenResultDTO>;
|
|
163
170
|
submitReview(reviewId: string): Promise<ReviewSubmitResultDTO>;
|
|
164
171
|
cancelReview(reviewId: string, req?: CancelReviewRequest): Promise<ReviewCancelResultDTO>;
|
|
165
172
|
getReviewDocumentBase(reviewId: string): Promise<ReviewDocumentBaseDTO>;
|
|
@@ -172,17 +179,7 @@ export declare class CrtrClient {
|
|
|
172
179
|
resolveReviewComment(commentId: string, req?: ReviewCommentActionRequest): Promise<ReviewCommentMutationDTO>;
|
|
173
180
|
reopenReviewComment(commentId: string, req?: ReviewCommentActionRequest): Promise<ReviewCommentMutationDTO>;
|
|
174
181
|
deleteReviewComment(commentId: string, req?: ReviewCommentActionRequest): Promise<ReviewCommentMutationDTO>;
|
|
175
|
-
/** Pending deck/review tickets across every available crouter-owned
|
|
176
|
-
* humanloop root. */
|
|
177
182
|
listHumanInbox(): Promise<InboxListDTO>;
|
|
178
|
-
/** Read one pending deck by its opaque ticket id, with Markdown bodies
|
|
179
|
-
* resolved inline. */
|
|
180
|
-
getHumanInboxDeck(ticketId: InboxTicketIdDTO): Promise<InboxDeckDTO>;
|
|
181
|
-
/** Submit ordered interaction responses for a pending deck. Single-assignment
|
|
182
|
-
* server-side: a competing resolution races to `ticket_already_resolved`. */
|
|
183
|
-
respondHumanInboxDeck(ticketId: InboxTicketIdDTO, request: RespondInboxDeckRequest): Promise<DeckTicketResultDTO>;
|
|
184
|
-
/** Cancel a pending deck (terminal response, never deletion). */
|
|
185
|
-
cancelHumanInboxTicket(ticketId: InboxTicketIdDTO, request?: CancelInboxTicketRequest): Promise<CanceledTicketResultDTO>;
|
|
186
183
|
/** Composed client-side from `GET /v1/nodes` + `GET /v1/status` (spec §6.3 —
|
|
187
184
|
* the dashboard is absorbed into those two reads; there is no single route).
|
|
188
185
|
* `generated_at` is the client-side capture instant of the composition. */
|
|
@@ -220,12 +217,6 @@ export declare class CrtrClient {
|
|
|
220
217
|
* it raw, so a value carrying `/`, whitespace or `?` would corrupt the
|
|
221
218
|
* request line rather than 404 cleanly. Mirrors `nodePath`. */
|
|
222
219
|
private cronPath;
|
|
223
|
-
/** Validate an opaque inbox ticket id before route construction. A local
|
|
224
|
-
* shape violation is a caller bug, not a server-rejectable request — throws
|
|
225
|
-
* `TypeError` (matching the existing safe-segment discipline of a local
|
|
226
|
-
* precondition, distinct from `nodePath`'s `ApiError` because that one IS a
|
|
227
|
-
* request the server could plausibly receive and reject itself). */
|
|
228
|
-
private ticketId;
|
|
229
220
|
/** Validate a review id before route construction (D-A6). Reviews are minted
|
|
230
221
|
* and addressed like node ids, but arrive from agent argv, so a malformed
|
|
231
222
|
* one is a plausible request the server would also reject — `ApiError`,
|
package/dist/client.js
CHANGED
|
@@ -118,6 +118,27 @@ export class CrtrClient {
|
|
|
118
118
|
relaunchRoot(id) {
|
|
119
119
|
return this.request('POST', routes.nodeRelaunchRoot(this.nodePath(id)), {});
|
|
120
120
|
}
|
|
121
|
+
bindBrokerSession(id, req) {
|
|
122
|
+
return this.request('POST', routes.nodeBrokerSessionBound(this.nodePath(id)), req);
|
|
123
|
+
}
|
|
124
|
+
settleBroker(id, req) {
|
|
125
|
+
return this.request('POST', routes.nodeBrokerSettle(this.nodePath(id)), req);
|
|
126
|
+
}
|
|
127
|
+
advanceBrokerInboxCursor(id, req) {
|
|
128
|
+
return this.request('POST', routes.nodeBrokerInboxCursor(this.nodePath(id)), req);
|
|
129
|
+
}
|
|
130
|
+
commitBrokerModel(id, req) {
|
|
131
|
+
return this.request('POST', routes.nodeBrokerModel(this.nodePath(id)), req);
|
|
132
|
+
}
|
|
133
|
+
brokerExtensionState(id) {
|
|
134
|
+
return this.request('GET', routes.nodeBrokerExtensionState(this.nodePath(id)));
|
|
135
|
+
}
|
|
136
|
+
commitBrokerGeneratedName(id, req) {
|
|
137
|
+
return this.request('POST', routes.nodeBrokerGeneratedName(this.nodePath(id)), req);
|
|
138
|
+
}
|
|
139
|
+
commitBrokerPersonaAck(id, req) {
|
|
140
|
+
return this.request('POST', routes.nodeBrokerPersonaAck(this.nodePath(id)), req);
|
|
141
|
+
}
|
|
121
142
|
closeNode(id, req) {
|
|
122
143
|
return this.request('POST', routes.nodeClose(this.nodePath(id)), req ?? {});
|
|
123
144
|
}
|
|
@@ -292,9 +313,6 @@ export class CrtrClient {
|
|
|
292
313
|
getReviewByBridge(bridgeNodeId) {
|
|
293
314
|
return this.request('GET', routes.humanReviewByBridge(this.nodePath(bridgeNodeId)));
|
|
294
315
|
}
|
|
295
|
-
openReview(reviewId) {
|
|
296
|
-
return this.request('POST', routes.humanReviewOpen(this.reviewPath(reviewId)), {});
|
|
297
|
-
}
|
|
298
316
|
submitReview(reviewId) {
|
|
299
317
|
return this.request('POST', routes.humanReviewSubmit(this.reviewPath(reviewId)), {});
|
|
300
318
|
}
|
|
@@ -333,26 +351,10 @@ export class CrtrClient {
|
|
|
333
351
|
deleteReviewComment(commentId, req = {}) {
|
|
334
352
|
return this.request('POST', routes.humanCommentDelete(this.commentPath(commentId)), req);
|
|
335
353
|
}
|
|
336
|
-
// ----
|
|
337
|
-
/** Pending deck/review tickets across every available crouter-owned
|
|
338
|
-
* humanloop root. */
|
|
354
|
+
// ---- Attached terminal viewer inbox -------------------------------------
|
|
339
355
|
listHumanInbox() {
|
|
340
356
|
return this.request('GET', routes.humanInbox());
|
|
341
357
|
}
|
|
342
|
-
/** Read one pending deck by its opaque ticket id, with Markdown bodies
|
|
343
|
-
* resolved inline. */
|
|
344
|
-
getHumanInboxDeck(ticketId) {
|
|
345
|
-
return this.request('GET', routes.humanInboxTicket(this.ticketId(ticketId)));
|
|
346
|
-
}
|
|
347
|
-
/** Submit ordered interaction responses for a pending deck. Single-assignment
|
|
348
|
-
* server-side: a competing resolution races to `ticket_already_resolved`. */
|
|
349
|
-
respondHumanInboxDeck(ticketId, request) {
|
|
350
|
-
return this.request('POST', routes.humanInboxRespond(this.ticketId(ticketId)), request);
|
|
351
|
-
}
|
|
352
|
-
/** Cancel a pending deck (terminal response, never deletion). */
|
|
353
|
-
cancelHumanInboxTicket(ticketId, request) {
|
|
354
|
-
return this.request('POST', routes.humanInboxCancel(this.ticketId(ticketId)), request ?? {});
|
|
355
|
-
}
|
|
356
358
|
// ---- Canvas reads / maintenance ---------------------------------------
|
|
357
359
|
/** Composed client-side from `GET /v1/nodes` + `GET /v1/status` (spec §6.3 —
|
|
358
360
|
* the dashboard is absorbed into those two reads; there is no single route).
|
|
@@ -444,17 +446,6 @@ export class CrtrClient {
|
|
|
444
446
|
}
|
|
445
447
|
return id;
|
|
446
448
|
}
|
|
447
|
-
/** Validate an opaque inbox ticket id before route construction. A local
|
|
448
|
-
* shape violation is a caller bug, not a server-rejectable request — throws
|
|
449
|
-
* `TypeError` (matching the existing safe-segment discipline of a local
|
|
450
|
-
* precondition, distinct from `nodePath`'s `ApiError` because that one IS a
|
|
451
|
-
* request the server could plausibly receive and reject itself). */
|
|
452
|
-
ticketId(id) {
|
|
453
|
-
if (!/^[a-f0-9]{64}$/.test(id)) {
|
|
454
|
-
throw new TypeError(`invalid inbox ticket id: ${JSON.stringify(id)}`);
|
|
455
|
-
}
|
|
456
|
-
return id;
|
|
457
|
-
}
|
|
458
449
|
/** Validate a review id before route construction (D-A6). Reviews are minted
|
|
459
450
|
* and addressed like node ids, but arrive from agent argv, so a malformed
|
|
460
451
|
* one is a plausible request the server would also reject — `ApiError`,
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { ExitIntentDTO, NodeStatusDTO } from './common.js';
|
|
2
|
+
/** `POST /v1/nodes/{id}/broker/session-bound` body. Pi's session-start reason
|
|
3
|
+
* distinguishes an ordinary boot/resume from `/new`, whose child-side session
|
|
4
|
+
* reset is a different durable operation. `reviewBoundaryIds` reports only the
|
|
5
|
+
* review markers visible in Pi's current branch; crtrd owns the node binding
|
|
6
|
+
* used to decide whether that branch is valid. */
|
|
7
|
+
export interface BrokerSessionBoundRequest {
|
|
8
|
+
piSessionId: string;
|
|
9
|
+
sessionFile: string | null;
|
|
10
|
+
pid: number;
|
|
11
|
+
reason: string | null;
|
|
12
|
+
reviewBoundaryIds: string[];
|
|
13
|
+
}
|
|
14
|
+
/** Pi-side consequence selected by crtrd after binding the session. The
|
|
15
|
+
* handler itself never calls back into the broker while servicing the request. */
|
|
16
|
+
export interface BrokerSessionBoundResultDTO {
|
|
17
|
+
action: 'none' | 'relaunch_root' | 'shutdown';
|
|
18
|
+
}
|
|
19
|
+
/** `POST /v1/nodes/{id}/broker/settle` body. These are the facts only Pi can
|
|
20
|
+
* know at its settlement boundary; crtrd reads all current canvas state and
|
|
21
|
+
* selects the durable consequence. */
|
|
22
|
+
export interface BrokerSettleRequest {
|
|
23
|
+
stopReason: string;
|
|
24
|
+
backgroundJobsRunning: boolean;
|
|
25
|
+
pushedFinal: boolean;
|
|
26
|
+
askedHuman: boolean;
|
|
27
|
+
}
|
|
28
|
+
/** The only consequence a settle caller may enact. crtrd has already committed
|
|
29
|
+
* every canvas and placement effect before returning this directive. */
|
|
30
|
+
export type BrokerSettleDirective = {
|
|
31
|
+
action: 'reprompt';
|
|
32
|
+
prompt: string;
|
|
33
|
+
} | {
|
|
34
|
+
action: 'stay_dormant';
|
|
35
|
+
} | {
|
|
36
|
+
action: 'shutdown';
|
|
37
|
+
};
|
|
38
|
+
/** `POST /v1/nodes/{id}/broker/inbox-cursor` body. The watcher advances this
|
|
39
|
+
* only after Pi has settled every handoff through the supplied physical entry.
|
|
40
|
+
* `brokerPid` binds the commit to the broker generation crtrd currently owns. */
|
|
41
|
+
export interface BrokerInboxCursorRequest {
|
|
42
|
+
throughEntryId: string;
|
|
43
|
+
brokerPid: number;
|
|
44
|
+
}
|
|
45
|
+
/** crtrd either commits the durable cursor or preserves it while a refresh
|
|
46
|
+
* discards the current Pi conversation, so the next broker replays the entry. */
|
|
47
|
+
export type BrokerInboxCursorDirective = {
|
|
48
|
+
action: 'advanced';
|
|
49
|
+
} | {
|
|
50
|
+
action: 'hold_refresh';
|
|
51
|
+
};
|
|
52
|
+
/** Durable model recipe selected by the live broker after Pi accepts a model or thinking change. */
|
|
53
|
+
export interface BrokerModelCommitRequest {
|
|
54
|
+
spec: string;
|
|
55
|
+
pinnedOverride?: boolean;
|
|
56
|
+
userSelected: boolean;
|
|
57
|
+
}
|
|
58
|
+
export interface BrokerModelCommitResultDTO {
|
|
59
|
+
modelOverride: string;
|
|
60
|
+
}
|
|
61
|
+
/** The dependency-light identity/runtime projection broker extensions need to
|
|
62
|
+
* render their local Pi hooks without reading canvas.db themselves. */
|
|
63
|
+
export interface BrokerExtensionNodeDTO {
|
|
64
|
+
node_id: string;
|
|
65
|
+
name: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
icon?: string;
|
|
68
|
+
kind: string;
|
|
69
|
+
mode: 'base' | 'orchestrator';
|
|
70
|
+
lifecycle: 'terminal' | 'resident';
|
|
71
|
+
status: NodeStatusDTO;
|
|
72
|
+
cwd: string;
|
|
73
|
+
parent: string | null;
|
|
74
|
+
fork_from: string | null;
|
|
75
|
+
profile_id: string | null;
|
|
76
|
+
managed_worktree?: {
|
|
77
|
+
state: 'open' | 'closed';
|
|
78
|
+
path: string;
|
|
79
|
+
branch: string;
|
|
80
|
+
base_ref: string;
|
|
81
|
+
base_sha: string;
|
|
82
|
+
} | null;
|
|
83
|
+
review_binding?: {
|
|
84
|
+
review_id: string;
|
|
85
|
+
origin_node_id: string;
|
|
86
|
+
branch_file: string;
|
|
87
|
+
target_file: string;
|
|
88
|
+
} | null;
|
|
89
|
+
intent: ExitIntentDTO;
|
|
90
|
+
persona_ack?: {
|
|
91
|
+
mode: 'base' | 'orchestrator';
|
|
92
|
+
lifecycle: 'terminal' | 'resident';
|
|
93
|
+
};
|
|
94
|
+
created: string;
|
|
95
|
+
}
|
|
96
|
+
export interface BrokerExtensionSubjectDTO {
|
|
97
|
+
kind: string;
|
|
98
|
+
mode: 'base' | 'orchestrator';
|
|
99
|
+
lifecycle: 'terminal' | 'resident';
|
|
100
|
+
hasManager: boolean;
|
|
101
|
+
cwd: string;
|
|
102
|
+
scope: 'user' | 'project';
|
|
103
|
+
orchestration: {
|
|
104
|
+
depth: number;
|
|
105
|
+
};
|
|
106
|
+
profile: string | null;
|
|
107
|
+
}
|
|
108
|
+
/** One resolved report sender. Report contents stay broker-local filesystem
|
|
109
|
+
* data; this daemon projection supplies only existence and display metadata. */
|
|
110
|
+
export interface BrokerReportNodeDTO {
|
|
111
|
+
node_id: string;
|
|
112
|
+
name: string;
|
|
113
|
+
created: string;
|
|
114
|
+
}
|
|
115
|
+
/** `GET /v1/nodes/{id}/broker/extension-state`. This is deliberately a fixed
|
|
116
|
+
* extension rendering projection, not a generic node/state read API. */
|
|
117
|
+
export interface BrokerExtensionStateDTO {
|
|
118
|
+
node: BrokerExtensionNodeDTO;
|
|
119
|
+
warm_spare: boolean;
|
|
120
|
+
ancestors: BrokerExtensionNodeDTO[];
|
|
121
|
+
children: BrokerExtensionNodeDTO[];
|
|
122
|
+
fork_source: BrokerExtensionNodeDTO | null;
|
|
123
|
+
subject: BrokerExtensionSubjectDTO;
|
|
124
|
+
report_nodes: BrokerReportNodeDTO[];
|
|
125
|
+
}
|
|
126
|
+
/** Guarded generated-label update. `initial` can only fill a blank generated
|
|
127
|
+
* description; `recap` additionally compares the exact automatic-name snapshot
|
|
128
|
+
* captured before the headless naming call. */
|
|
129
|
+
export type BrokerGeneratedNameRequest = {
|
|
130
|
+
kind: 'initial';
|
|
131
|
+
description: string;
|
|
132
|
+
icon: string;
|
|
133
|
+
} | {
|
|
134
|
+
kind: 'recap';
|
|
135
|
+
description: string;
|
|
136
|
+
icon: string;
|
|
137
|
+
expected: {
|
|
138
|
+
name: string;
|
|
139
|
+
description: string;
|
|
140
|
+
icon: string;
|
|
141
|
+
kind: string;
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
/** A daemon-selected Pi editor-label directive. No handler calls a broker. */
|
|
145
|
+
export interface BrokerGeneratedNameResultDTO {
|
|
146
|
+
applied: boolean;
|
|
147
|
+
editorLabel?: string;
|
|
148
|
+
}
|
|
149
|
+
export interface BrokerPersonaAckRequest {
|
|
150
|
+
from: {
|
|
151
|
+
mode: 'base' | 'orchestrator';
|
|
152
|
+
lifecycle: 'terminal' | 'resident';
|
|
153
|
+
};
|
|
154
|
+
to: {
|
|
155
|
+
mode: 'base' | 'orchestrator';
|
|
156
|
+
lifecycle: 'terminal' | 'resident';
|
|
157
|
+
};
|
|
158
|
+
}
|
package/dist/dto/crons.d.ts
CHANGED
|
@@ -74,6 +74,12 @@ export interface ListCronsQuery {
|
|
|
74
74
|
export interface CronScopeQuery {
|
|
75
75
|
profile?: string | null;
|
|
76
76
|
}
|
|
77
|
+
/** Cancellation-only query. `run_id` is set automatically inside a cron run,
|
|
78
|
+
* letting crtrd distinguish a run ending itself from an external cancellation
|
|
79
|
+
* that must terminate an in-flight process. */
|
|
80
|
+
export interface CancelCronQuery extends CronScopeQuery {
|
|
81
|
+
run_id?: string;
|
|
82
|
+
}
|
|
77
83
|
/** One settled run-log entry (`GET /v1/crons/:cronId`, `POST /v1/crons/:cronId/run`). */
|
|
78
84
|
export interface CronRunDTO {
|
|
79
85
|
run_id: string;
|
package/dist/dto/human.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { NodeIdDTO } from './common.js';
|
|
2
|
-
import type { InteractionResponseDTO } from './inbox.js';
|
|
3
2
|
/** One anchored review comment, mirroring crouter's ticket-store shape as a
|
|
4
3
|
* plain structural wire type (no store import). */
|
|
5
4
|
export interface FeedbackCommentDTO {
|
|
@@ -37,6 +36,13 @@ export interface FeedbackResultDTO {
|
|
|
37
36
|
commentsTotal: number;
|
|
38
37
|
commentsUnresolved: number;
|
|
39
38
|
}
|
|
39
|
+
export interface InteractionResponseDTO {
|
|
40
|
+
id: string;
|
|
41
|
+
selectedOptionId?: string;
|
|
42
|
+
selectedOptionIds?: string[];
|
|
43
|
+
freetext?: string;
|
|
44
|
+
optionComments?: Record<string, string>;
|
|
45
|
+
}
|
|
40
46
|
/** `POST /v1/human/tickets/{node_id}/resolve` body — a deck answer. */
|
|
41
47
|
export interface HumanResolveRequest {
|
|
42
48
|
responses: InteractionResponseDTO[];
|
package/dist/dto/inbox.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { IsoTime } from './common.js';
|
|
2
2
|
/** Opaque, stable, URL-safe ticket id: lowercase SHA-256 hex of
|
|
3
|
-
* `canonicalRoot + "\0" + ticketBasename`.
|
|
4
|
-
* it discloses no home filesystem path. */
|
|
3
|
+
* `canonicalRoot + "\0" + ticketBasename`. */
|
|
5
4
|
export type InboxTicketIdDTO = string;
|
|
6
5
|
export type InteractionKindDTO = 'notify' | 'decision' | 'context' | 'error' | 'review';
|
|
7
6
|
export interface DeckSourceDTO {
|
|
@@ -33,72 +32,3 @@ export type InboxTicketSummaryDTO = DeckTicketSummaryDTO | ReviewTicketSummaryDT
|
|
|
33
32
|
export interface InboxListDTO {
|
|
34
33
|
tickets: InboxTicketSummaryDTO[];
|
|
35
34
|
}
|
|
36
|
-
export interface InteractionOptionDTO {
|
|
37
|
-
id: string;
|
|
38
|
-
label: string;
|
|
39
|
-
description?: string;
|
|
40
|
-
}
|
|
41
|
-
export interface InteractionPreAnswerDTO {
|
|
42
|
-
selectedOptionId?: string;
|
|
43
|
-
selectedOptionIds?: string[];
|
|
44
|
-
freetext?: string;
|
|
45
|
-
label?: string;
|
|
46
|
-
}
|
|
47
|
-
export interface InteractionDTO {
|
|
48
|
-
id: string;
|
|
49
|
-
title: string;
|
|
50
|
-
subtitle: string;
|
|
51
|
-
/** Resolved source Markdown — `bodyPath` is deliberately impossible here. */
|
|
52
|
-
body?: string;
|
|
53
|
-
options: InteractionOptionDTO[];
|
|
54
|
-
multiSelect?: boolean;
|
|
55
|
-
allowFreetext?: boolean;
|
|
56
|
-
freetextLabel?: string;
|
|
57
|
-
kind?: InteractionKindDTO;
|
|
58
|
-
preAnswered?: InteractionPreAnswerDTO;
|
|
59
|
-
}
|
|
60
|
-
export interface DeckDTO {
|
|
61
|
-
title: string;
|
|
62
|
-
source?: DeckSourceDTO;
|
|
63
|
-
interactions: InteractionDTO[];
|
|
64
|
-
}
|
|
65
|
-
/** `GET /v1/human/inbox/:ticket_id` result for a pending deck. */
|
|
66
|
-
export interface InboxDeckDTO {
|
|
67
|
-
ticket_id: InboxTicketIdDTO;
|
|
68
|
-
kind: 'deck';
|
|
69
|
-
deck: DeckDTO;
|
|
70
|
-
}
|
|
71
|
-
export interface InteractionResponseDTO {
|
|
72
|
-
id: string;
|
|
73
|
-
selectedOptionId?: string;
|
|
74
|
-
selectedOptionIds?: string[];
|
|
75
|
-
freetext?: string;
|
|
76
|
-
optionComments?: Record<string, string>;
|
|
77
|
-
}
|
|
78
|
-
/** `POST /v1/human/inbox/:ticket_id/respond` body. */
|
|
79
|
-
export interface RespondInboxDeckRequest {
|
|
80
|
-
responses: InteractionResponseDTO[];
|
|
81
|
-
}
|
|
82
|
-
/** `POST /v1/human/inbox/:ticket_id/respond` result — the canonical humanloop
|
|
83
|
-
* `humanloop.response/v2` result, unchanged. */
|
|
84
|
-
export interface DeckTicketResultDTO {
|
|
85
|
-
schema: 'humanloop.response/v2';
|
|
86
|
-
kind: 'deck';
|
|
87
|
-
responses: InteractionResponseDTO[];
|
|
88
|
-
summary: string;
|
|
89
|
-
completedAt: IsoTime;
|
|
90
|
-
}
|
|
91
|
-
/** `POST /v1/human/inbox/:ticket_id/cancel` body. `reason`, when present, must
|
|
92
|
-
* be nonempty after trim and at most 1000 characters. */
|
|
93
|
-
export interface CancelInboxTicketRequest {
|
|
94
|
-
reason?: string;
|
|
95
|
-
}
|
|
96
|
-
/** `POST /v1/human/inbox/:ticket_id/cancel` result — the canonical humanloop
|
|
97
|
-
* `humanloop.cancel/v1` result, unchanged. `actor` is always `"human"`. */
|
|
98
|
-
export interface CanceledTicketResultDTO {
|
|
99
|
-
schema: 'humanloop.cancel/v1';
|
|
100
|
-
kind: 'canceled';
|
|
101
|
-
canceledAt: IsoTime;
|
|
102
|
-
reason?: string;
|
|
103
|
-
actor?: string;
|
|
104
|
-
}
|
package/dist/dto/inbox.js
CHANGED
|
@@ -1,10 +1,2 @@
|
|
|
1
|
-
//
|
|
2
|
-
// inbox-contract.md §A). Crouter API envelope fields use the existing
|
|
3
|
-
// snake_case convention; nested humanloop protocol objects retain their
|
|
4
|
-
// canonical camelCase field names so they cross the wire without translation
|
|
5
|
-
// or loss. Optional fields are omitted when absent, never serialized as
|
|
6
|
-
// `null`. `bodyPath` is deliberately impossible on this wire — crtrd resolves
|
|
7
|
-
// it server-side via humanloop's `parseDeck` and returns inline `body`.
|
|
8
|
-
//
|
|
9
|
-
// PURITY (spec §3.1): Node built-ins + `src/api/*` only.
|
|
1
|
+
// Ticket summaries rendered by the attached terminal viewer.
|
|
10
2
|
export {};
|
package/dist/dto/nodes.d.ts
CHANGED
|
@@ -45,6 +45,12 @@ export interface NodeSummaryDTO {
|
|
|
45
45
|
intent: ExitIntentDTO;
|
|
46
46
|
waiting_for: NodeIdDTO | null;
|
|
47
47
|
pi_pid: number | null;
|
|
48
|
+
/** Launch-time process identity paired with `pi_pid`, or null when absent. */
|
|
49
|
+
pi_pid_identity: string | null;
|
|
50
|
+
/** Current tmux placement cache. Local tmux callers re-check the pane itself before acting. */
|
|
51
|
+
window: string | null;
|
|
52
|
+
tmux_session: string | null;
|
|
53
|
+
pane: string | null;
|
|
48
54
|
final_report: string | null;
|
|
49
55
|
finalized_at: IsoTime | null;
|
|
50
56
|
}
|
|
@@ -103,13 +109,6 @@ export interface NodeDetailDTO extends NodeSummaryDTO {
|
|
|
103
109
|
* (never launched, or no token accounting yet). */
|
|
104
110
|
context_tokens?: number | null;
|
|
105
111
|
pi_session_id?: string | null;
|
|
106
|
-
/** Launch-time process-identity fingerprint captured alongside `pi_pid`
|
|
107
|
-
* (`NodeMeta.pi_pid_identity`), or null. Surfaced so `revive --now`'s
|
|
108
|
-
* client-side SIGTERM can pass the identity baseline to `recordedPidLiveness`
|
|
109
|
-
* and refuse to signal a stranger process that reused a dead broker's pid.
|
|
110
|
-
* Null when the node predates the field or its launch-time capture failed
|
|
111
|
-
* (fail-open — no baseline means no guard, not a false mismatch). */
|
|
112
|
-
pi_pid_identity?: string | null;
|
|
113
112
|
/** The node's durable model override (`NodeMeta.model_override`), or null when
|
|
114
113
|
* it runs on the kind/profile default. Surfaced so `node config --model`
|
|
115
114
|
* can report the resolved model after a patch. */
|
package/dist/dto/reviews.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { IsoTime, NodeIdDTO
|
|
1
|
+
import type { IsoTime, NodeIdDTO } from './common.js';
|
|
2
2
|
import type { FeedbackResultDTO } from './human.js';
|
|
3
3
|
export type ReviewOriginKindDTO = 'ticket' | 'inline';
|
|
4
4
|
/** `binding` is intentionally never exposed over the API. */
|
|
@@ -73,16 +73,6 @@ export interface ListReviewsQuery {
|
|
|
73
73
|
export interface ReviewListDTO {
|
|
74
74
|
reviews: ReviewDTO[];
|
|
75
75
|
}
|
|
76
|
-
/** Daemon-derived result of opening an active review or acknowledging a terminal one. */
|
|
77
|
-
export type ReviewOpenResultDTO = {
|
|
78
|
-
review: ReviewDTO;
|
|
79
|
-
companion_node_id: NodeIdDTO;
|
|
80
|
-
companion_status: NodeStatusDTO;
|
|
81
|
-
disposition: 'open';
|
|
82
|
-
} | {
|
|
83
|
-
review: ReviewDTO;
|
|
84
|
-
disposition: 'terminal';
|
|
85
|
-
};
|
|
86
76
|
/** Daemon-derived result of terminal review approval. */
|
|
87
77
|
export interface ReviewSubmitResultDTO {
|
|
88
78
|
review: ReviewDTO;
|
package/dist/routes.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export declare const routes: {
|
|
|
19
19
|
readonly nodeFork: (id: string) => string;
|
|
20
20
|
readonly nodeRevive: (id: string) => string;
|
|
21
21
|
readonly nodeRelaunchRoot: (id: string) => string;
|
|
22
|
+
readonly nodeBrokerSessionBound: (id: string) => string;
|
|
23
|
+
readonly nodeBrokerSettle: (id: string) => string;
|
|
24
|
+
readonly nodeBrokerInboxCursor: (id: string) => string;
|
|
25
|
+
readonly nodeBrokerModel: (id: string) => string;
|
|
26
|
+
readonly nodeBrokerExtensionState: (id: string) => string;
|
|
27
|
+
readonly nodeBrokerGeneratedName: (id: string) => string;
|
|
28
|
+
readonly nodeBrokerPersonaAck: (id: string) => string;
|
|
22
29
|
readonly nodeClose: (id: string) => string;
|
|
23
30
|
readonly nodeRecycle: (id: string) => string;
|
|
24
31
|
readonly nodeDemote: (id: string) => string;
|
|
@@ -54,7 +61,6 @@ export declare const routes: {
|
|
|
54
61
|
readonly humanReviews: () => string;
|
|
55
62
|
readonly humanReview: (reviewId: string) => string;
|
|
56
63
|
readonly humanReviewByBridge: (bridgeNodeId: string) => string;
|
|
57
|
-
readonly humanReviewOpen: (reviewId: string) => string;
|
|
58
64
|
readonly humanReviewSubmit: (reviewId: string) => string;
|
|
59
65
|
readonly humanReviewCancel: (reviewId: string) => string;
|
|
60
66
|
readonly humanReviewDocument: (reviewId: string) => string;
|
|
@@ -67,9 +73,6 @@ export declare const routes: {
|
|
|
67
73
|
readonly humanCommentReopen: (commentId: string) => string;
|
|
68
74
|
readonly humanCommentDelete: (commentId: string) => string;
|
|
69
75
|
readonly humanInbox: () => string;
|
|
70
|
-
readonly humanInboxTicket: (ticketId: string) => string;
|
|
71
|
-
readonly humanInboxRespond: (ticketId: string) => string;
|
|
72
|
-
readonly humanInboxCancel: (ticketId: string) => string;
|
|
73
76
|
readonly profiles: () => string;
|
|
74
77
|
readonly profile: (name: string) => string;
|
|
75
78
|
readonly modelAuths: () => string;
|
package/dist/routes.js
CHANGED
|
@@ -37,6 +37,13 @@ export const routes = {
|
|
|
37
37
|
nodeFork: (id) => `${V}/nodes/${id}/fork`,
|
|
38
38
|
nodeRevive: (id) => `${V}/nodes/${id}/revive`,
|
|
39
39
|
nodeRelaunchRoot: (id) => `${V}/nodes/${id}/relaunch-root`,
|
|
40
|
+
nodeBrokerSessionBound: (id) => `${V}/nodes/${id}/broker/session-bound`,
|
|
41
|
+
nodeBrokerSettle: (id) => `${V}/nodes/${id}/broker/settle`,
|
|
42
|
+
nodeBrokerInboxCursor: (id) => `${V}/nodes/${id}/broker/inbox-cursor`,
|
|
43
|
+
nodeBrokerModel: (id) => `${V}/nodes/${id}/broker/model`,
|
|
44
|
+
nodeBrokerExtensionState: (id) => `${V}/nodes/${id}/broker/extension-state`,
|
|
45
|
+
nodeBrokerGeneratedName: (id) => `${V}/nodes/${id}/broker/generated-name`,
|
|
46
|
+
nodeBrokerPersonaAck: (id) => `${V}/nodes/${id}/broker/persona-ack`,
|
|
40
47
|
nodeClose: (id) => `${V}/nodes/${id}/close`,
|
|
41
48
|
nodeRecycle: (id) => `${V}/nodes/${id}/recycle`,
|
|
42
49
|
nodeDemote: (id) => `${V}/nodes/${id}/demote`,
|
|
@@ -80,7 +87,6 @@ export const routes = {
|
|
|
80
87
|
humanReviews: () => `${V}/human/reviews`,
|
|
81
88
|
humanReview: (reviewId) => `${V}/human/reviews/${reviewId}`,
|
|
82
89
|
humanReviewByBridge: (bridgeNodeId) => `${V}/human/reviews/by-bridge/${bridgeNodeId}`,
|
|
83
|
-
humanReviewOpen: (reviewId) => `${V}/human/reviews/${reviewId}/open`,
|
|
84
90
|
humanReviewSubmit: (reviewId) => `${V}/human/reviews/${reviewId}/submit`,
|
|
85
91
|
humanReviewCancel: (reviewId) => `${V}/human/reviews/${reviewId}/cancel`,
|
|
86
92
|
humanReviewDocument: (reviewId) => `${V}/human/reviews/${reviewId}/document`,
|
|
@@ -92,11 +98,8 @@ export const routes = {
|
|
|
92
98
|
humanCommentResolve: (commentId) => `${V}/human/comments/${commentId}/resolve`,
|
|
93
99
|
humanCommentReopen: (commentId) => `${V}/human/comments/${commentId}/reopen`,
|
|
94
100
|
humanCommentDelete: (commentId) => `${V}/human/comments/${commentId}/delete`,
|
|
95
|
-
//
|
|
101
|
+
// Attached terminal viewer inbox
|
|
96
102
|
humanInbox: () => `${V}/human/inbox`,
|
|
97
|
-
humanInboxTicket: (ticketId) => `${V}/human/inbox/${ticketId}`,
|
|
98
|
-
humanInboxRespond: (ticketId) => `${V}/human/inbox/${ticketId}/respond`,
|
|
99
|
-
humanInboxCancel: (ticketId) => `${V}/human/inbox/${ticketId}/cancel`,
|
|
100
103
|
// Profiles (server-side for P2 Core; CLI profile verbs stay fs-local)
|
|
101
104
|
profiles: () => `${V}/profiles`,
|
|
102
105
|
profile: (name) => `${V}/profiles/${name}`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter-api",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.175",
|
|
4
4
|
"description": "Typed crtrd /v1 API contract — DTOs, route builders, the error contract, and the CrtrClient. Zero runtime dependencies.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
File without changes
|