@north-light/crouter-api 0.3.221 → 0.3.222

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.
@@ -12,12 +12,13 @@ import type { AttachEnsureRequest, AttachEnsureResultDTO } from './dto/attach.js
12
12
  import type { DeleteProfileRequest, DeleteProfileResultDTO, EnsureProfileRequest, ProfileDTO } from './dto/profiles.js';
13
13
  import type { FilePeekDTO } from './dto/files.js';
14
14
  import type { MemoryDocRefDTO } from './dto/memory.js';
15
- import type { ChatInventoryDTO } from './dto/chat-inventory.js';
15
+ import type { ChatInventoryDTO, ProspectiveChatInventoryDTO, ProspectiveChatInventoryQuery } from './dto/chat-inventory.js';
16
16
  import type { CredentialRemovalResultDTO, CredentialResultDTO, InstallCredentialRequest, ModelAuthListDTO } from './dto/modelauth.js';
17
17
  import type { CreateHumanBridgeRequest, HumanBridgeResultDTO, HumanCancelRequest, HumanCancelResultDTO, HumanResolveRequest, HumanResolveResultDTO } from './dto/human.js';
18
18
  import type { CancelReviewRequest, CreateReviewRequest, ListReviewsQuery, ReviewCancelResultDTO, ReviewDocumentBaseDTO, ReviewDTO, ReviewListDTO, ReviewSubmitResultDTO } from './dto/reviews.js';
19
19
  import type { CreateReviewCommentRequest, EditReviewCommentRequest, ListReviewCommentsQuery, ReadReviewCommentEventsQuery, ReviewCommentActionRequest, ReviewCommentDetailDTO, ReviewCommentEventsDTO, ReviewCommentListDTO, ReviewCommentMutationDTO, ReviewCommentRangeBatchRequest, ReviewCommentRangeBatchResultDTO } from './dto/review-comments.js';
20
20
  import type { CancelInboxTicketRequest, CanceledTicketResultDTO, InboxListDTO, InboxPageDTO, InboxPageHistoryDTO, InboxPageResponseDTO, InboxTicketIdDTO, PageFeedbackResolutionDTO, PageResponsesDTO, PageTicketResultDTO, RespondInboxPageRequest } from './dto/inbox.js';
21
+ import type { CreateHumanRequestDTO, CreateHumanRequestRequest, HumanRequestDTO, HumanRequestIdDTO, ReplaceHumanRequestRequest, RespondHumanRequestRequest, SettleHumanRequestRequest } from './dto/human-requests.js';
21
22
  import type { AttentionCountsDTO, AttentionDTO, DashboardDTO, DashboardQuery, HistoryGrepQuery, HistoryGrepResultDTO, HistoryReadQuery, HistoryReadResultDTO, HistorySearchQuery, HistorySearchResultDTO, PruneRequest, PruneResultDTO, RebuildIndexResultDTO, RosterDTO, SnapshotDTO } from './dto/canvas.js';
22
23
  import type { CloseWorktreeResultDTO } from './dto/worktree.js';
23
24
  import type { BrokerExtensionStateDTO, BrokerGeneratedNameRequest, BrokerGeneratedNameResultDTO, BrokerInboxCursorDirective, BrokerInboxCursorRequest, BrokerModelCommitRequest, BrokerModelCommitResultDTO, BrokerPersonaAckRequest, BrokerSessionBoundRequest, BrokerSessionBoundResultDTO, BrokerSettleDirective, BrokerSettleRequest } from './dto/broker-ops.js';
@@ -157,6 +158,7 @@ export declare class CrtrClient {
157
158
  * inline `/name` token resolves to. Never revives — a node whose broker is
158
159
  * not live answers `broker_live: false` with empty arrays. */
159
160
  getChatInventory(id: string): Promise<ChatInventoryDTO>;
161
+ getProspectiveChatInventory(q?: ProspectiveChatInventoryQuery): Promise<ProspectiveChatInventoryDTO>;
160
162
  getArtifacts(id: string, q?: ArtifactsQuery): Promise<ArtifactListDTO>;
161
163
  getContext(id: string): Promise<ContextListDTO>;
162
164
  /** Read an absolute host path as UTF-8 (capped, `truncated` when clipped) for
@@ -220,6 +222,24 @@ export declare class CrtrClient {
220
222
  getInboxResponse(ticketId: InboxTicketIdDTO): Promise<InboxPageResponseDTO>;
221
223
  /** Cancel a ticket (terminal response, never deletion). */
222
224
  cancelHumanInboxTicket(ticketId: InboxTicketIdDTO, request?: CancelInboxTicketRequest): Promise<CanceledTicketResultDTO>;
225
+ /** Create one durable human request. Its `request_id` is the same opaque id
226
+ * the inbox routes address, so the request and the inbox ticket are one
227
+ * record. An unresolvable `action.name` is rejected before the page is
228
+ * published, leaving no inbox row behind. */
229
+ createHumanRequest(request: CreateHumanRequestRequest): Promise<CreateHumanRequestDTO>;
230
+ /** Read one request: its current state, its answer when answered, and the
231
+ * delivery state of its completion action when it bound one. */
232
+ getHumanRequest(requestId: HumanRequestIdDTO): Promise<HumanRequestDTO>;
233
+ /** Revise a pending request's page in place. Identity, provenance, and the
234
+ * frozen action binding are preserved; a settled request refuses. */
235
+ replaceHumanRequest(requestId: HumanRequestIdDTO, request: ReplaceHumanRequestRequest): Promise<HumanRequestDTO>;
236
+ /** Settle a request `answered` programmatically. Races a human answer to the
237
+ * same first-writer-wins result. */
238
+ respondHumanRequest(requestId: HumanRequestIdDTO, request: RespondHumanRequestRequest): Promise<HumanRequestDTO>;
239
+ /** The recipient surface closing a request without answering. */
240
+ dismissHumanRequest(requestId: HumanRequestIdDTO, request?: SettleHumanRequestRequest): Promise<HumanRequestDTO>;
241
+ /** The requester withdrawing its own request. */
242
+ cancelHumanRequest(requestId: HumanRequestIdDTO, request?: SettleHumanRequestRequest): Promise<HumanRequestDTO>;
223
243
  /** Resolve one page feedback comment — the bound companion's report that it
224
244
  * has been dealt with. `nodeId` names the caller; the daemon refuses any
225
245
  * node but the ticket's companion. Terminal for the comment; appends no
@@ -274,6 +274,9 @@ export class CrtrClient {
274
274
  getChatInventory(id) {
275
275
  return this.request('GET', routes.nodeChatInventory(this.nodePath(id)));
276
276
  }
277
+ getProspectiveChatInventory(q) {
278
+ return this.request('GET', withQuery(routes.prospectiveChatInventory(), q));
279
+ }
277
280
  getArtifacts(id, q) {
278
281
  return this.request('GET', withQuery(routes.nodeArtifacts(this.nodePath(id)), q));
279
282
  }
@@ -426,6 +429,37 @@ export class CrtrClient {
426
429
  cancelHumanInboxTicket(ticketId, request) {
427
430
  return this.request('POST', routes.humanInboxCancel(this.ticketId(ticketId)), request ?? {});
428
431
  }
432
+ // ---- Durable programmatic human requests -------------------------------
433
+ /** Create one durable human request. Its `request_id` is the same opaque id
434
+ * the inbox routes address, so the request and the inbox ticket are one
435
+ * record. An unresolvable `action.name` is rejected before the page is
436
+ * published, leaving no inbox row behind. */
437
+ createHumanRequest(request) {
438
+ return this.request('POST', routes.humanRequests(), request);
439
+ }
440
+ /** Read one request: its current state, its answer when answered, and the
441
+ * delivery state of its completion action when it bound one. */
442
+ getHumanRequest(requestId) {
443
+ return this.request('GET', routes.humanRequest(this.ticketId(requestId)));
444
+ }
445
+ /** Revise a pending request's page in place. Identity, provenance, and the
446
+ * frozen action binding are preserved; a settled request refuses. */
447
+ replaceHumanRequest(requestId, request) {
448
+ return this.request('POST', routes.humanRequestReplace(this.ticketId(requestId)), request);
449
+ }
450
+ /** Settle a request `answered` programmatically. Races a human answer to the
451
+ * same first-writer-wins result. */
452
+ respondHumanRequest(requestId, request) {
453
+ return this.request('POST', routes.humanRequestRespond(this.ticketId(requestId)), request);
454
+ }
455
+ /** The recipient surface closing a request without answering. */
456
+ dismissHumanRequest(requestId, request = {}) {
457
+ return this.request('POST', routes.humanRequestDismiss(this.ticketId(requestId)), request);
458
+ }
459
+ /** The requester withdrawing its own request. */
460
+ cancelHumanRequest(requestId, request = {}) {
461
+ return this.request('POST', routes.humanRequestCancel(this.ticketId(requestId)), request);
462
+ }
429
463
  /** Resolve one page feedback comment — the bound companion's report that it
430
464
  * has been dealt with. `nodeId` names the caller; the daemon refuses any
431
465
  * node but the ticket's companion. Terminal for the comment; appends no
@@ -41,3 +41,16 @@ export interface ChatInventoryDTO {
41
41
  commands: ChatInventoryCommandDTO[];
42
42
  memory_refs: ChatInventoryMemoryRefDTO[];
43
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,88 @@
1
+ import type { IsoTime } from './common.js';
2
+ import type { InboxTicketIdDTO, PageResponsesDTO, TicketSourceDTO } from './inbox.js';
3
+ /** A request id IS an opaque inbox ticket id: lowercase 64-hex. */
4
+ export type HumanRequestIdDTO = InboxTicketIdDTO;
5
+ /** The complete authored page text, inline — never a path. */
6
+ export interface HumanRequestPageDTO {
7
+ dialect: 'jsx' | 'html';
8
+ source: string;
9
+ }
10
+ export interface HumanRequestDeliveryDTO {
11
+ placement: 'inline' | 'panel';
12
+ inbox: boolean;
13
+ reply: boolean;
14
+ }
15
+ /** Frozen at creation: the action name and its opaque payload. An omitted
16
+ * `payload` is frozen as JSON null, so the completion document always carries it. */
17
+ export interface HumanRequestActionDTO {
18
+ name: string;
19
+ payload?: unknown;
20
+ }
21
+ export interface CreateHumanRequestRequest {
22
+ page: HumanRequestPageDTO;
23
+ delivery?: HumanRequestDeliveryDTO;
24
+ source?: TicketSourceDTO;
25
+ creator_cwd: string;
26
+ action?: HumanRequestActionDTO;
27
+ }
28
+ export type HumanRequestState = 'pending' | 'answered' | 'dismissed' | 'canceled';
29
+ export type HumanRequestDeliveryState = 'none' | 'pending' | 'running' | 'accepted' | 'permanent_failed';
30
+ export interface CreateHumanRequestDTO {
31
+ request_id: HumanRequestIdDTO;
32
+ state: 'pending';
33
+ /** Omitted entirely when the request carries no action binding. */
34
+ action?: {
35
+ name: string;
36
+ };
37
+ delivery_state: HumanRequestDeliveryState;
38
+ }
39
+ export interface HumanRequestDeliveryFailureDTO {
40
+ kind: 'exit' | 'signal' | 'timeout' | 'spawn_error';
41
+ exit_code?: number;
42
+ signal?: string;
43
+ message?: string;
44
+ /** A bounded tail, not full output. */
45
+ stderr?: string;
46
+ }
47
+ export interface HumanRequestDeliveryDetailDTO {
48
+ state: HumanRequestDeliveryState;
49
+ /** Attempts started. */
50
+ attempt: number;
51
+ /** Present only while pending after a retryable failure. */
52
+ next_attempt_at?: IsoTime;
53
+ accepted_at?: IsoTime;
54
+ permanent_failed_at?: IsoTime;
55
+ last_failure?: HumanRequestDeliveryFailureDTO;
56
+ }
57
+ export interface HumanRequestDTO {
58
+ request_id: HumanRequestIdDTO;
59
+ state: HumanRequestState;
60
+ title: string;
61
+ subtitle?: string;
62
+ source: TicketSourceDTO;
63
+ emitted_at: IsoTime;
64
+ /** Present unless pending. */
65
+ settled_at?: IsoTime;
66
+ /** Present only when `state` is `answered`. */
67
+ responses?: PageResponsesDTO;
68
+ reason?: string;
69
+ actor?: string;
70
+ /** `action` and `delivery` are both omitted when no action is bound. */
71
+ action?: {
72
+ name: string;
73
+ payload: unknown;
74
+ };
75
+ delivery?: HumanRequestDeliveryDetailDTO;
76
+ }
77
+ export interface ReplaceHumanRequestRequest {
78
+ page: HumanRequestPageDTO;
79
+ delivery?: HumanRequestDeliveryDTO;
80
+ }
81
+ export interface RespondHumanRequestRequest {
82
+ responses: PageResponsesDTO;
83
+ actor?: string;
84
+ }
85
+ export interface SettleHumanRequestRequest {
86
+ reason?: string;
87
+ actor?: string;
88
+ }
@@ -0,0 +1,4 @@
1
+ // Durable programmatic human-request DTOs — crtrd `/v1/human/requests`. The
2
+ // envelope is snake_case; nested page-protocol objects keep their canonical
3
+ // camelCase names, matching the inbox DTOs.
4
+ export {};
@@ -44,6 +44,9 @@ export interface HumanResolveRequest {
44
44
  export interface HumanCancelRequest {
45
45
  reason?: string;
46
46
  actor?: string;
47
+ /** The recipient surface closing it sends `dismissed`; a requester retracting
48
+ * it sends `canceled` or omits the field. */
49
+ disposition?: 'canceled' | 'dismissed';
47
50
  }
48
51
  /** `POST /v1/human/tickets/{ticket_id}/resolve` result. */
49
52
  export interface HumanResolveResultDTO {
@@ -93,6 +93,8 @@ export interface ReviewCancelResultDTO {
93
93
  export interface CancelReviewRequest {
94
94
  reason?: string;
95
95
  actor?: string;
96
+ /** Recipient surfaces send `dismissed`; a requester withdrawal defaults to `canceled`. */
97
+ disposition?: 'canceled' | 'dismissed';
96
98
  }
97
99
  /** Daemon-derived coordinate base for the terminal review surface. */
98
100
  export interface ReviewDocumentBaseDTO {
@@ -25,6 +25,7 @@ export * from './dto/human.js';
25
25
  export * from './dto/files.js';
26
26
  export * from './dto/memory.js';
27
27
  export * from './dto/inbox.js';
28
+ export * from './dto/human-requests.js';
28
29
  export * from './dto/reviews.js';
29
30
  export * from './dto/review-comments.js';
30
31
  export * from './dto/chat-inventory.js';
package/dist/api/index.js CHANGED
@@ -26,6 +26,7 @@ export * from './dto/human.js';
26
26
  export * from './dto/files.js';
27
27
  export * from './dto/memory.js';
28
28
  export * from './dto/inbox.js';
29
+ export * from './dto/human-requests.js';
29
30
  export * from './dto/reviews.js';
30
31
  export * from './dto/review-comments.js';
31
32
  export * from './dto/chat-inventory.js';
@@ -12,6 +12,7 @@ export declare const routes: {
12
12
  readonly nodeSubject: (id: string) => string;
13
13
  readonly nodeSession: (id: string) => string;
14
14
  readonly nodeChatInventory: (id: string) => string;
15
+ readonly prospectiveChatInventory: () => string;
15
16
  readonly nodeTranscript: (id: string) => string;
16
17
  readonly nodeContext: (id: string) => string;
17
18
  readonly nodeArtifacts: (id: string) => string;
@@ -84,6 +85,12 @@ export declare const routes: {
84
85
  readonly humanInboxResponse: (ticketId: string) => string;
85
86
  readonly humanInboxCancel: (ticketId: string) => string;
86
87
  readonly humanInboxFeedbackResolve: (ticketId: string, commentId: string) => string;
88
+ readonly humanRequests: () => string;
89
+ readonly humanRequest: (requestId: string) => string;
90
+ readonly humanRequestReplace: (requestId: string) => string;
91
+ readonly humanRequestRespond: (requestId: string) => string;
92
+ readonly humanRequestDismiss: (requestId: string) => string;
93
+ readonly humanRequestCancel: (requestId: string) => string;
87
94
  readonly profiles: () => string;
88
95
  readonly profile: (name: string) => string;
89
96
  readonly modelAuths: () => string;
@@ -28,6 +28,7 @@ export const routes = {
28
28
  nodeSubject: (id) => `${V}/nodes/${id}/subject`,
29
29
  nodeSession: (id) => `${V}/nodes/${id}/session`,
30
30
  nodeChatInventory: (id) => `${V}/nodes/${id}/chat-inventory`,
31
+ prospectiveChatInventory: () => `${V}/prospective-chat-inventory`,
31
32
  nodeTranscript: (id) => `${V}/nodes/${id}/transcript`,
32
33
  nodeContext: (id) => `${V}/nodes/${id}/context`,
33
34
  nodeArtifacts: (id) => `${V}/nodes/${id}/artifacts`,
@@ -111,6 +112,15 @@ export const routes = {
111
112
  humanInboxResponse: (ticketId) => `${V}/human/inbox/${ticketId}/response`,
112
113
  humanInboxCancel: (ticketId) => `${V}/human/inbox/${ticketId}/cancel`,
113
114
  humanInboxFeedbackResolve: (ticketId, commentId) => `${V}/human/inbox/${ticketId}/feedback-comments/${commentId}/resolve`,
115
+ // Durable programmatic human requests. `request_id` is the same opaque
116
+ // inbox ticket id the `/v1/human/inbox` routes address, so one request is one
117
+ // record across both surfaces.
118
+ humanRequests: () => `${V}/human/requests`,
119
+ humanRequest: (requestId) => `${V}/human/requests/${requestId}`,
120
+ humanRequestReplace: (requestId) => `${V}/human/requests/${requestId}/replace`,
121
+ humanRequestRespond: (requestId) => `${V}/human/requests/${requestId}/respond`,
122
+ humanRequestDismiss: (requestId) => `${V}/human/requests/${requestId}/dismiss`,
123
+ humanRequestCancel: (requestId) => `${V}/human/requests/${requestId}/cancel`,
114
124
  // Profiles (deletion is daemon-owned because it crosses canvas state)
115
125
  profiles: () => `${V}/profiles`,
116
126
  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.221",
3
+ "version": "0.3.222",
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/api/index.js",