@north-light/api 0.3.511 → 0.3.513

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.
@@ -1,6 +1,6 @@
1
1
  import { ApiError } from './errors.js';
2
2
  import type { AppLimitsChangeDTO, LimitsDTO, SetAppLimitsRequest } from './dto/limits.js';
3
- import type { DaemonAdmitDTO, DaemonRestartDTO, DueDTO, HealthDTO, MigrateStateDTO, MigrateStateRequest, StatusDTO } from './dto/health.js';
3
+ import type { DaemonAdmitDTO, DaemonRestartDTO, DueDTO, HealthDTO, ReadyDTO, MigrateStateDTO, MigrateStateRequest, StatusDTO } from './dto/health.js';
4
4
  import type { BashJobStatusDTO, BashJobStopResultDTO } from './dto/bash-jobs.js';
5
5
  import type { ContextListDTO, CreateNodeRequest, ListNodesQuery, NodeDetailDTO, NodeMessagesPageDTO, NodeMessagesQuery, NodeSessionDTO, NodeSnapshotDTO, NodeSubjectDTO, NodeSummaryDTO, TranscriptDTO, TranscriptQuery } from './dto/nodes.js';
6
6
  import type { NodeOutcomeResponseDTO, OutcomeDeliveryDTO, RegisterOutcomeDeliveryRequest } from './dto/node-outcomes.js';
@@ -123,6 +123,8 @@ export declare class CrtrClient {
123
123
  /** One `/healthz` observation without cold-socket recovery. Availability
124
124
  * waiters own retry policy and pass their remaining wall-clock budget here. */
125
125
  probeHealthz(timeoutMs: number): Promise<HealthDTO>;
126
+ /** `GET /v1/ready`: 200 ready, 503 not yet; both answer a `ReadyDTO`. */
127
+ ready(): Promise<ReadyDTO>;
126
128
  status(): Promise<StatusDTO>;
127
129
  /** Busy and next-due state, the truth behind sandbox sleep and wake. */
128
130
  due(): Promise<DueDTO>;
@@ -107,6 +107,19 @@ export class CrtrClient {
107
107
  }
108
108
  return parse(response);
109
109
  }
110
+ /** `GET /v1/ready`: 200 ready, 503 not yet; both answer a `ReadyDTO`. */
111
+ async ready() {
112
+ const response = await this.transport('GET', routes.ready(), undefined, {});
113
+ if (response.status === 503) {
114
+ try {
115
+ const body = await response.clone().json();
116
+ if (body.ready === false)
117
+ return body;
118
+ }
119
+ catch { /* `parse` reports a malformed 503 normally */ }
120
+ }
121
+ return parse(response);
122
+ }
110
123
  status() {
111
124
  return this.request('GET', routes.status());
112
125
  }
@@ -8,7 +8,7 @@ export const MAX_KIND_EVENTS = 64;
8
8
  export const MIN_EVENT_LEVEL = 1;
9
9
  export const MAX_EVENT_LEVEL = 10;
10
10
  const KIND_KEYS = new Set(['description', 'events', 'read']);
11
- const EVENT_KEYS = new Set(['level', 'supersedes']);
11
+ const EVENT_KEYS = new Set(['level', 'supersedes', 'ends_wait']);
12
12
  function isRecord(value) {
13
13
  return typeof value === 'object' && value !== null && !Array.isArray(value);
14
14
  }
@@ -25,7 +25,7 @@ export function eventCatalogReasons(events, where) {
25
25
  if (!LOCAL.test(local))
26
26
  reasons.push(`${at} is not a valid event name`);
27
27
  if (!isRecord(spec)) {
28
- reasons.push(`${at} must be an object { level, supersedes? }`);
28
+ reasons.push(`${at} must be an object { level, supersedes?, ends_wait? }`);
29
29
  continue;
30
30
  }
31
31
  for (const key of Object.keys(spec))
@@ -36,6 +36,8 @@ export function eventCatalogReasons(events, where) {
36
36
  reasons.push(`${at} level must be an integer ${MIN_EVENT_LEVEL}-${MAX_EVENT_LEVEL}`);
37
37
  if (spec['supersedes'] !== undefined && typeof spec['supersedes'] !== 'boolean')
38
38
  reasons.push(`${at} supersedes must be a boolean`);
39
+ if (spec['ends_wait'] !== undefined && typeof spec['ends_wait'] !== 'boolean')
40
+ reasons.push(`${at} ends_wait must be a boolean`);
39
41
  }
40
42
  return reasons;
41
43
  }
@@ -1,5 +1,5 @@
1
1
  /** The contract level this build serves and requires. Written by `scripts/contract.mjs release`; never edit by hand. */
2
- export declare const CONTRACT_LEVEL = "1.21";
2
+ export declare const CONTRACT_LEVEL = "1.23";
3
3
  /** Request header naming the one contract level the caller needs, e.g. `1.3`. Optional: absent means no check. */
4
4
  export declare const REQUIRED_CONTRACT_HEADER = "Crouter-Required-Contract";
5
5
  /** Response header listing the contract levels the server serves, comma-separated, one per major, e.g. `1.3`. */
@@ -12,7 +12,7 @@
12
12
  //
13
13
  // PURITY (spec §3.1): Node built-ins + `src/api/*` only.
14
14
  /** The contract level this build serves and requires. Written by `scripts/contract.mjs release`; never edit by hand. */
15
- export const CONTRACT_LEVEL = '1.21';
15
+ export const CONTRACT_LEVEL = '1.23';
16
16
  /** Request header naming the one contract level the caller needs, e.g. `1.3`. Optional: absent means no check. */
17
17
  export const REQUIRED_CONTRACT_HEADER = 'Crouter-Required-Contract';
18
18
  /** Response header listing the contract levels the server serves, comma-separated, one per major, e.g. `1.3`. */
@@ -276,6 +276,18 @@ export interface RosterDTO {
276
276
  generated_at: IsoTime;
277
277
  nodes: RosterNodeDTO[];
278
278
  edges: RosterEdgeDTO[];
279
+ /** Every live wait a node holds on a watched canvas object (a workflow run until it completes), oldest
280
+ * first per node. The attach viewer lists this node's below the editor beside its child and cron rows. */
281
+ object_waits?: RosterObjectWaitDTO[];
282
+ }
283
+ /** One node's live wait on a watched object: the object's kind (`github.run`) and name identify it to a
284
+ * person; `crtr canvas read <object_id>` reads it. */
285
+ export interface RosterObjectWaitDTO {
286
+ node_id: NodeIdDTO;
287
+ object_id: string;
288
+ object_type: string;
289
+ object_name: string;
290
+ created: IsoTime;
279
291
  }
280
292
  /** Browse's initial frame needs the dashboard fields and topology, not the full
281
293
  * node detail/list projection. Transported as gzip JSON (application/gzip) over
@@ -2,6 +2,7 @@ import type { PrivacyName } from './objects.js';
2
2
  export interface CustomEventSpecDTO {
3
3
  level: number;
4
4
  supersedes?: boolean;
5
+ ends_wait?: boolean;
5
6
  }
6
7
  export type CustomReceiverDTO = 'queue' | {
7
8
  url: string;
@@ -13,6 +13,14 @@ export interface HealthDTO {
13
13
  /** Always present; only `ready` admits normal daemon work. */
14
14
  startup_phase: StartupPhaseDTO;
15
15
  }
16
+ /** `GET /v1/ready` — whether this listener can admit ordinary work (200) or not (503, with `reason`). Reveals nothing else. */
17
+ export type ReadyDTO = {
18
+ ready: true;
19
+ } | {
20
+ ready: false;
21
+ reason: 'startup_pending' | 'jwks_pending' | 'grant_snapshot_missing';
22
+ message: string;
23
+ };
16
24
  /** `GET /v1/status` — daemon status snapshot. Backs `crtr sys daemon status`
17
25
  * state and the `crtr canvas dashboard` header. `runtime_version` is also
18
26
  * checked by Core's minimum-runtime capability gate. */
@@ -13,6 +13,7 @@ export interface ObjectKindDeclDTO {
13
13
  events: Record<string, {
14
14
  level: number;
15
15
  supersedes?: boolean;
16
+ ends_wait?: boolean;
16
17
  }>;
17
18
  owner: {
18
19
  id: string;
@@ -3,6 +3,7 @@ export declare const API_VERSION = "v1";
3
3
  /** Route path builders. Keys mirror the spec §6 route table. */
4
4
  export declare const routes: {
5
5
  readonly healthz: () => string;
6
+ readonly ready: () => string;
6
7
  readonly status: () => string;
7
8
  readonly due: () => string;
8
9
  readonly daemonRestart: () => string;
@@ -17,6 +17,7 @@ const V = `/${API_VERSION}`;
17
17
  export const routes = {
18
18
  // Health / status
19
19
  healthz: () => '/healthz',
20
+ ready: () => `${V}/ready`,
20
21
  status: () => `${V}/status`,
21
22
  due: () => `${V}/due`,
22
23
  daemonRestart: () => `${V}/daemon/restart`,
package/dist/types.d.ts CHANGED
@@ -66,6 +66,7 @@ export interface ObjectKindDeclaration {
66
66
  events: Record<string, {
67
67
  level: number;
68
68
  supersedes?: boolean;
69
+ ends_wait?: boolean;
69
70
  }>;
70
71
  /** A leaf path of the plugin's own commands, run to render an instance as markdown. */
71
72
  read?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/api",
3
- "version": "0.3.511",
3
+ "version": "0.3.513",
4
4
  "description": "Typed crtrd /v1 API contract — DTOs, route builders, the error contract, the CrtrClient, and the command-plugin manifest format. Zero runtime dependencies.",
5
5
  "type": "module",
6
6
  "main": "./dist/api/index.js",