agent-relay-sdk 0.2.0 → 0.2.2

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/types.d.ts CHANGED
@@ -12,12 +12,335 @@ export interface AgentCard {
12
12
  status: AgentStatus;
13
13
  instanceId?: string;
14
14
  epoch: number;
15
+ providerCapabilities?: ProviderCapabilities;
16
+ context?: ContextState;
15
17
  meta?: Record<string, unknown>;
16
18
  lastSeen: number;
17
19
  createdAt: number;
18
20
  }
19
21
  export type AgentStatus = "online" | "idle" | "busy" | "stale" | "offline";
22
+ export type CapabilitySource = "catalog" | "provider" | "runtime" | "override" | "estimate";
23
+ export type CapabilityConfidence = "declared" | "reported" | "verified" | "estimated" | "unknown";
24
+ export interface ProviderCapabilities {
25
+ lifecycle: {
26
+ managed: boolean;
27
+ shutdownHard: boolean;
28
+ restartHard: boolean;
29
+ semanticStatus?: boolean;
30
+ reconnect?: boolean;
31
+ hibernate?: boolean;
32
+ resume?: boolean;
33
+ };
34
+ model?: {
35
+ provider?: SpawnProvider | string;
36
+ id?: string;
37
+ alias?: string;
38
+ providerModel?: string;
39
+ effort?: SpawnEffort | string;
40
+ source: CapabilitySource;
41
+ confidence: CapabilityConfidence;
42
+ lastUpdatedAt?: number;
43
+ };
44
+ session?: {
45
+ approvalMode?: SpawnApprovalMode | string;
46
+ fileRead?: boolean;
47
+ fileWrite?: boolean;
48
+ shell?: boolean;
49
+ source: CapabilitySource;
50
+ confidence: CapabilityConfidence;
51
+ lastUpdatedAt?: number;
52
+ };
53
+ context?: {
54
+ stats?: {
55
+ source: "api" | "statusline" | "hook" | "estimate";
56
+ confidence: "exact" | "reported" | "estimated";
57
+ };
58
+ compact?: boolean;
59
+ clear?: boolean;
60
+ inject?: boolean;
61
+ fork?: boolean;
62
+ rollback?: boolean;
63
+ archive?: boolean;
64
+ };
65
+ terminal?: {
66
+ live?: {
67
+ read?: boolean;
68
+ write?: boolean;
69
+ };
70
+ attach?: {
71
+ create?: boolean;
72
+ read?: boolean;
73
+ write?: boolean;
74
+ detach?: boolean;
75
+ };
76
+ };
77
+ source: CapabilitySource;
78
+ confidence: CapabilityConfidence;
79
+ lastUpdatedAt: number;
80
+ }
81
+ export type ContextLifecycleState = "fresh" | "primed" | "working" | "cooling" | "compacting" | "hibernating";
82
+ export interface ContextProbeMetrics {
83
+ agentId: string;
84
+ contextPercent: number;
85
+ tokensUsed?: number;
86
+ tokensMax?: number;
87
+ quotaUsed?: number;
88
+ quotaLimit?: number;
89
+ quotaResetIn?: number;
90
+ model?: string;
91
+ effort?: string;
92
+ source: "statusline" | "hook" | "api" | "estimate";
93
+ confidence: "exact" | "reported" | "estimated";
94
+ timestamp: number;
95
+ }
96
+ export interface ContextState {
97
+ utilization: number;
98
+ tokensUsed?: number;
99
+ tokensMax?: number;
100
+ lifecycleState: ContextLifecycleState;
101
+ warmTopics: string[];
102
+ activeMemories: string[];
103
+ tasksSinceCompact: number;
104
+ lastCompactedAt?: number;
105
+ lastUpdatedAt: number;
106
+ source: "statusline" | "hook" | "api" | "estimate";
107
+ confidence: "exact" | "reported" | "estimated";
108
+ }
109
+ export interface ContextSnapshot {
110
+ id: number;
111
+ agentId: string;
112
+ context: ContextState;
113
+ utilization: number;
114
+ lifecycleState: ContextLifecycleState;
115
+ tokensUsed?: number;
116
+ tokensMax?: number;
117
+ source: ContextState["source"];
118
+ confidence: ContextState["confidence"];
119
+ capturedAt: number;
120
+ }
121
+ export type MemoryType = "organization" | "role" | "project" | "task" | "interaction" | "agent";
122
+ export type MemoryVisibility = "private" | "project" | "org" | "public";
123
+ export type MemorySensitivity = "public" | "normal" | "sensitive" | "secret";
124
+ export type MemoryConfidence = "reported" | "inferred" | "verified";
125
+ export type MemoryRedactionState = "raw" | "redacted" | "rejected";
126
+ export interface Memory {
127
+ id: string;
128
+ type: MemoryType;
129
+ scope: string;
130
+ title: string;
131
+ content: string;
132
+ tags: string[];
133
+ visibility: MemoryVisibility;
134
+ sensitivity: MemorySensitivity;
135
+ confidence: MemoryConfidence;
136
+ redactionState: MemoryRedactionState;
137
+ relevanceScore: number;
138
+ sourceAgent?: string;
139
+ sourceTask?: number;
140
+ createdBy?: string;
141
+ contentHash?: string;
142
+ metadata: Record<string, unknown>;
143
+ accessCount: number;
144
+ lastAccessedAt?: number;
145
+ createdAt: number;
146
+ updatedAt: number;
147
+ expiresAt?: number;
148
+ }
149
+ export interface CreateMemoryInput {
150
+ type: MemoryType;
151
+ scope: string;
152
+ title: string;
153
+ content: string;
154
+ tags?: string[];
155
+ visibility?: MemoryVisibility;
156
+ sensitivity?: MemorySensitivity;
157
+ confidence?: MemoryConfidence;
158
+ redactionState?: MemoryRedactionState;
159
+ relevanceScore?: number;
160
+ sourceAgent?: string;
161
+ sourceTask?: number;
162
+ createdBy?: string;
163
+ metadata?: Record<string, unknown>;
164
+ ttlMs?: number;
165
+ }
166
+ export interface UpdateMemoryInput {
167
+ title?: string;
168
+ content?: string;
169
+ tags?: string[];
170
+ visibility?: MemoryVisibility;
171
+ sensitivity?: MemorySensitivity;
172
+ confidence?: MemoryConfidence;
173
+ redactionState?: MemoryRedactionState;
174
+ relevanceScore?: number;
175
+ metadata?: Record<string, unknown>;
176
+ expiresAt?: number | null;
177
+ }
178
+ export interface MemoryQuery {
179
+ type?: MemoryType;
180
+ scope?: string;
181
+ tags?: string[];
182
+ minRelevance?: number;
183
+ limit?: number;
184
+ includeExpired?: boolean;
185
+ visibility?: MemoryVisibility;
186
+ includeSensitive?: boolean;
187
+ }
188
+ export interface MemorySearchResult {
189
+ memories: Memory[];
190
+ total: number;
191
+ }
192
+ export interface PackagedMemory {
193
+ memory: Memory;
194
+ reason: string;
195
+ priority: 1 | 2 | 3;
196
+ score?: number;
197
+ }
198
+ export interface TaskRoutingHints {
199
+ id?: number;
200
+ title?: string;
201
+ text?: string;
202
+ scope?: string;
203
+ tags?: string[];
204
+ capabilities?: string[];
205
+ target?: string;
206
+ }
207
+ export interface ContextBudget {
208
+ maxTokens: number;
209
+ maxMemories: number;
210
+ priorityCutoff: 1 | 2 | 3;
211
+ }
212
+ export interface TaskHistorySummary {
213
+ taskId: number;
214
+ agentId: string;
215
+ status: string;
216
+ summary?: string;
217
+ completedAt?: number;
218
+ }
219
+ export interface ContextPackage {
220
+ memories: PackagedMemory[];
221
+ rolePrompt?: string;
222
+ recentContext?: string;
223
+ taskHistory?: TaskHistorySummary[];
224
+ estimatedTokens: number;
225
+ }
226
+ export interface ContextPackageRequest {
227
+ task: TaskRoutingHints;
228
+ agent: AgentCard;
229
+ budget: ContextBudget;
230
+ memories?: Memory[];
231
+ }
232
+ export interface MemoryStats {
233
+ total: number;
234
+ byType: Partial<Record<MemoryType, number>>;
235
+ byScope: Record<string, number>;
236
+ bySensitivity: Partial<Record<MemorySensitivity, number>>;
237
+ }
238
+ export type ActiveMemoryClearReason = "compact" | "clearContext" | "restart" | "shutdown" | "manual";
239
+ export interface MemoryBrokerCapabilities {
240
+ search: true;
241
+ create: boolean;
242
+ update: boolean;
243
+ delete: boolean;
244
+ stats: boolean;
245
+ assemble: boolean;
246
+ activeTracking: boolean;
247
+ activeList: boolean;
248
+ external: boolean;
249
+ }
250
+ export interface MemoryBrokerContext {
251
+ now: number;
252
+ actor: string;
253
+ scopes: string[];
254
+ relayUrl?: string;
255
+ requestId?: string;
256
+ }
257
+ export type MemoryBrokerKind = "sqlite" | "http" | "command";
258
+ export interface SqliteMemoryBrokerConfig {
259
+ type: "sqlite";
260
+ }
261
+ export interface HttpMemoryBrokerConfig {
262
+ type: "http";
263
+ url: string;
264
+ tokenEnv?: string;
265
+ timeoutMs?: number;
266
+ }
267
+ export interface CommandMemoryBrokerConfig {
268
+ type: "command";
269
+ command: string;
270
+ args?: string[];
271
+ timeoutMs?: number;
272
+ }
273
+ export type MemoryBrokerConfig = SqliteMemoryBrokerConfig | HttpMemoryBrokerConfig | CommandMemoryBrokerConfig;
20
274
  export type MessageKind = "chat" | "channel.event" | "task" | "pair" | "control" | "system";
275
+ export type ArtifactKind = "image" | "audio" | "video" | "document" | "archive" | "other";
276
+ export type ArtifactSensitivity = "public" | "normal" | "sensitive" | "secret";
277
+ export type ArtifactVisibility = "private" | "project" | "org";
278
+ export type ArtifactRole = "media" | "patch" | "report" | "log" | "output" | "input";
279
+ export interface ArtifactBlob {
280
+ digest: string;
281
+ storageUri: string;
282
+ mediaType: string;
283
+ size: number;
284
+ createdAt: number;
285
+ }
286
+ export interface ArtifactLink {
287
+ id: string;
288
+ artifactId: string;
289
+ entityType: "message" | "task" | "recipeRun" | "recipeStep" | "channelEvent";
290
+ entityId: string;
291
+ role?: ArtifactRole;
292
+ title?: string;
293
+ createdBy: string;
294
+ createdAt: number;
295
+ }
296
+ export interface Artifact {
297
+ id: string;
298
+ blobDigest: string;
299
+ mediaType: string;
300
+ kind: ArtifactKind;
301
+ filename?: string;
302
+ size: number;
303
+ digest: string;
304
+ visibility: ArtifactVisibility;
305
+ sensitivity: ArtifactSensitivity;
306
+ createdBy: string;
307
+ createdAt: number;
308
+ expiresAt?: number;
309
+ metadata: Record<string, unknown>;
310
+ links?: ArtifactLink[];
311
+ url?: string;
312
+ }
313
+ export interface AttachmentRef {
314
+ artifactId: string;
315
+ kind?: ArtifactKind;
316
+ role?: ArtifactRole;
317
+ title?: string;
318
+ ref?: AttachmentSourceRef;
319
+ metadata?: Record<string, unknown>;
320
+ }
321
+ export interface ChannelAttachmentRef {
322
+ artifactId?: string;
323
+ kind?: ArtifactKind;
324
+ role?: ArtifactRole;
325
+ title?: string;
326
+ ref?: AttachmentSourceRef;
327
+ metadata?: Record<string, unknown>;
328
+ }
329
+ export type AttachmentSourceRef = {
330
+ type: "relay-blob";
331
+ id: string;
332
+ [key: string]: unknown;
333
+ } | {
334
+ type: "external-url";
335
+ url: string;
336
+ [key: string]: unknown;
337
+ } | {
338
+ type: "channel-file";
339
+ id: string;
340
+ provider?: string;
341
+ uniqueId?: string;
342
+ [key: string]: unknown;
343
+ };
21
344
  export interface Message {
22
345
  id: number;
23
346
  from: string;
@@ -33,11 +356,68 @@ export interface Message {
33
356
  claimedAt?: number;
34
357
  claimExpiresAt?: number;
35
358
  idempotencyKey?: string;
359
+ deliveryStatus?: MessageDeliveryStatus;
360
+ deliveryAttempts?: number;
361
+ deliveryLastError?: string;
362
+ deliveryNextRetryAt?: number;
363
+ deliveryPoisonReason?: string;
364
+ deliveryUpdatedAt?: number;
365
+ queuedAt?: number;
366
+ maxAgeSeconds?: number;
367
+ resolvedToAgent?: string;
36
368
  payload: Record<string, unknown>;
37
369
  meta?: Record<string, unknown>;
370
+ reactions?: MessageReaction[];
38
371
  readBy: string[];
39
372
  createdAt: number;
40
373
  }
374
+ export interface ReplyObligation {
375
+ messageId: number;
376
+ agentId: string;
377
+ from: string;
378
+ kind: MessageKind;
379
+ subject?: string;
380
+ channel?: string;
381
+ bodyPreview: string;
382
+ createdAt: number;
383
+ replyCommand: string;
384
+ }
385
+ export interface MessageReaction {
386
+ messageId: number;
387
+ actorId: string;
388
+ emoji: string;
389
+ createdAt: number;
390
+ updatedAt: number;
391
+ }
392
+ export type RelayNotificationKind = "message" | "reply" | "error" | "agent.blocked";
393
+ export type RelayNotificationSeverity = "info" | "warning" | "error";
394
+ export interface RelayNotification {
395
+ id: string;
396
+ kind: RelayNotificationKind;
397
+ severity: RelayNotificationSeverity;
398
+ title: string;
399
+ body: string;
400
+ messageId?: number;
401
+ agentId?: string;
402
+ threadPeer?: string;
403
+ view?: "chat" | "messages" | "agents" | "work" | "tasks" | "channels" | "overview";
404
+ createdAt: number;
405
+ }
406
+ export type MessageDeliveryStatus = "pending" | "delivered" | "queued" | "failed" | "dead";
407
+ export interface MessageDeliveryAttempt {
408
+ id: number;
409
+ messageId: number;
410
+ agentId?: string;
411
+ action: "attempt" | "retry-now" | "mark-dead" | "clear";
412
+ status: MessageDeliveryStatus;
413
+ error?: string;
414
+ nextRetryAt?: number;
415
+ poisonReason?: string;
416
+ createdAt: number;
417
+ }
418
+ export interface MessageDeliveryState extends Pick<Message, "id" | "to" | "deliveryStatus" | "deliveryAttempts" | "deliveryLastError" | "deliveryNextRetryAt" | "deliveryPoisonReason" | "deliveryUpdatedAt" | "queuedAt" | "maxAgeSeconds" | "resolvedToAgent"> {
419
+ attempts: MessageDeliveryAttempt[];
420
+ }
41
421
  export interface SendMessageInput {
42
422
  from: string;
43
423
  to: string;
@@ -48,6 +428,8 @@ export interface SendMessageInput {
48
428
  replyTo?: number;
49
429
  claimable?: boolean;
50
430
  idempotencyKey?: string;
431
+ maxAgeSeconds?: number;
432
+ attachments?: AttachmentRef[];
51
433
  payload?: Record<string, unknown>;
52
434
  meta?: Record<string, unknown>;
53
435
  }
@@ -152,6 +534,8 @@ export interface RegisterAgentInput {
152
534
  ready?: boolean;
153
535
  status?: AgentCard["status"];
154
536
  instanceId?: string;
537
+ providerCapabilities?: ProviderCapabilities;
538
+ context?: ContextState;
155
539
  meta?: Record<string, unknown>;
156
540
  }
157
541
  export interface AgentSessionGuard {
@@ -232,6 +616,7 @@ export interface IntegrationEventInput {
232
616
  channel?: string;
233
617
  dedupeKey?: string;
234
618
  externalUrl?: string;
619
+ attachments?: AttachmentRef[];
235
620
  metadata?: Record<string, unknown>;
236
621
  }
237
622
  export interface IntegrationTaskStats {
@@ -245,8 +630,19 @@ export interface IntegrationTaskStats {
245
630
  }
246
631
  export interface IntegrationSummary {
247
632
  name: string;
633
+ displayName?: string;
634
+ description?: string;
635
+ enabled: boolean;
248
636
  configured: boolean;
249
637
  observed: boolean;
638
+ type?: string;
639
+ icon?: string;
640
+ accentColor?: string;
641
+ tags: string[];
642
+ homepageUrl?: string;
643
+ repositoryUrl?: string;
644
+ docsUrl?: string;
645
+ manifest?: Record<string, unknown>;
250
646
  scopes: string[];
251
647
  targets: string[];
252
648
  channels: string[];
@@ -259,6 +655,23 @@ export interface IntegrationSummary {
259
655
  };
260
656
  taskStats: IntegrationTaskStats;
261
657
  }
658
+ export type RuntimeContractName = "relayApi" | "orchestratorProtocol" | "runnerProtocol" | "providerPluginProtocol";
659
+ export type RuntimeContracts = Partial<Record<RuntimeContractName, number>>;
660
+ export type RuntimeCapabilities = Record<string, boolean>;
661
+ export interface RuntimePackageMetadata {
662
+ name: string;
663
+ version: string;
664
+ }
665
+ export interface ContractCompatibilityIssue {
666
+ contract: string;
667
+ expected: string;
668
+ actual?: number;
669
+ }
670
+ export interface ContractCompatibility {
671
+ status: "compatible" | "incompatible" | "unknown";
672
+ compatible: boolean;
673
+ issues: ContractCompatibilityIssue[];
674
+ }
262
675
  export type AutomationKind = "scheduled_task";
263
676
  export type AutomationCatchUpPolicy = "skip" | "run_once" | "run_all";
264
677
  export type AutomationConcurrencyPolicy = "skip" | "queue" | "replace";
@@ -276,13 +689,22 @@ export interface AutomationExistingAgentPolicy {
276
689
  export interface AutomationOnDemandAgentPolicy {
277
690
  mode: "on_demand_agent";
278
691
  provider: SpawnProvider;
692
+ model?: string;
693
+ effort?: SpawnEffort;
279
694
  cwd?: string;
695
+ workspaceMode?: WorkspaceMode;
280
696
  profile?: string;
281
697
  approvalMode?: SpawnApprovalMode;
282
698
  keepAlive?: boolean;
699
+ runtimeBudget?: AutomationRuntimeBudget;
283
700
  shutdownAfterMs?: number;
284
701
  }
285
702
  export type AutomationTargetPolicy = AutomationExistingAgentPolicy | AutomationOnDemandAgentPolicy;
703
+ export interface AutomationRuntimeBudget {
704
+ maxRuntimeMs: number;
705
+ warnAtMs?: number;
706
+ warningMessage?: string;
707
+ }
286
708
  export interface AutomationTaskTemplate {
287
709
  title: string;
288
710
  body: string;
@@ -373,6 +795,9 @@ export type ChannelRouteTarget = {
373
795
  } | {
374
796
  type: "pool";
375
797
  id: string;
798
+ } | {
799
+ type: "policy";
800
+ id: string;
376
801
  };
377
802
  export type ChannelBindingMode = "exclusive" | "broadcast";
378
803
  export interface ChannelBinding {
@@ -423,6 +848,20 @@ export interface ChannelSummary {
423
848
  lastSeen: number;
424
849
  meta?: Record<string, unknown>;
425
850
  }
851
+ export interface ChannelEventInput {
852
+ body?: string;
853
+ payload: Record<string, unknown>;
854
+ attachments?: ChannelAttachmentRef[];
855
+ conversationId?: string;
856
+ idempotencyKey?: string;
857
+ instanceId?: string;
858
+ epoch?: number;
859
+ }
860
+ export interface ChannelEventResult {
861
+ messages: Message[];
862
+ bindings: ChannelBinding[];
863
+ created: boolean;
864
+ }
426
865
  export interface TaskStatusInput {
427
866
  status: TaskStatus;
428
867
  agentId?: string;
@@ -452,6 +891,26 @@ export interface InboxState {
452
891
  threads: InboxThreadState[];
453
892
  drafts: InboxDraft[];
454
893
  }
894
+ export interface ChatHistoryImportEntry {
895
+ position: number;
896
+ originalMessageId: number;
897
+ originalFrom: string;
898
+ originalTo: string;
899
+ originalCreatedAt: number;
900
+ message: Message;
901
+ }
902
+ export interface ChatHistoryImport {
903
+ id: string;
904
+ targetAgentId?: string;
905
+ targetSpawnRequestId?: string;
906
+ sourcePeerId: string;
907
+ sourceAgentId?: string;
908
+ sourceThreadId?: string;
909
+ sourceAgentLabel?: string;
910
+ importedBy: string;
911
+ importedAt: number;
912
+ entries: ChatHistoryImportEntry[];
913
+ }
455
914
  export type ActivityKind = "message" | "reply" | "question" | "operator" | "pair" | "task" | "state";
456
915
  export interface ActivityEvent {
457
916
  id: number;
@@ -490,70 +949,555 @@ export interface ActivityEventInput {
490
949
  export type OrchestratorStatus = "online" | "offline";
491
950
  export type SpawnProvider = "claude" | "codex";
492
951
  export type SpawnApprovalMode = "open" | "guarded" | "read-only";
952
+ export type SpawnEffort = "low" | "medium" | "high" | "xhigh" | "max";
953
+ export type WorkspaceMode = "isolated" | "shared" | "inherit";
954
+ export type WorkspaceStatus = "active" | "ready" | "conflict" | "review_requested" | "merge_planned" | "merged" | "abandoned" | "cleanup_requested" | "cleaned";
955
+ /** How a workspace's work is integrated back into its base branch. */
956
+ export type WorkspaceMergeStrategy = "pr" | "rebase-ff" | "auto";
957
+ export interface WorkspaceProbeWorktree {
958
+ path: string;
959
+ branch?: string;
960
+ headSha?: string;
961
+ bare?: boolean;
962
+ detached?: boolean;
963
+ prunable?: boolean;
964
+ locked?: boolean;
965
+ reason?: string;
966
+ }
967
+ export interface WorkspaceProbe {
968
+ path: string;
969
+ isGitRepo: boolean;
970
+ repoRoot?: string;
971
+ branch?: string;
972
+ headSha?: string;
973
+ dirty?: boolean;
974
+ detached?: boolean;
975
+ worktrees?: WorkspaceProbeWorktree[];
976
+ error?: string;
977
+ }
978
+ export interface WorkspaceGitCommit {
979
+ sha: string;
980
+ message: string;
981
+ at?: number;
982
+ }
983
+ /**
984
+ * Live git state of a workspace worktree, computed on the host by the
985
+ * orchestrator. Used to surface whether a worktree contains actual work
986
+ * (commits ahead of base, dirty files) so the dashboard isn't a black box and
987
+ * so exit-time reconcile can decide cleanup-vs-flag.
988
+ */
989
+ export interface WorkspaceGitState {
990
+ /** Commits on the agent branch not yet in base (work the agent produced). */
991
+ ahead?: number;
992
+ /** Commits in base not in the agent branch (how far base moved on). */
993
+ behind?: number;
994
+ /** True if the worktree has uncommitted/untracked changes. */
995
+ dirty?: boolean;
996
+ /** Number of dirty (porcelain) entries. */
997
+ dirtyCount?: number;
998
+ /** Most recent commit in the worktree. */
999
+ lastCommit?: WorkspaceGitCommit;
1000
+ /** Ref/sha the ahead/behind counts were computed against. */
1001
+ baseRef?: string;
1002
+ /** Set when the worktree path no longer exists on disk. */
1003
+ missing?: boolean;
1004
+ /** Populated when git interrogation failed. */
1005
+ error?: string;
1006
+ }
1007
+ /**
1008
+ * Pre-flight check for integrating a workspace's work, computed on the host.
1009
+ * Reports whether the merge would be clean, conflict, or is a no-op, and which
1010
+ * strategy `auto` would pick — so the dashboard can warn before the user acts.
1011
+ */
1012
+ export interface WorkspaceMergePreview {
1013
+ /** Strategy `auto` would resolve to given the repo's remote/gh state. */
1014
+ strategy: "pr" | "rebase-ff";
1015
+ /** Commits on the agent branch not yet in base. */
1016
+ ahead?: number;
1017
+ /** Commits in base not in the agent branch. */
1018
+ behind?: number;
1019
+ /** Uncommitted/untracked entries in the worktree. */
1020
+ dirtyCount?: number;
1021
+ /** True if the three-way merge of base and the branch would conflict. */
1022
+ conflict?: boolean;
1023
+ /** True if base can fast-forward to the branch with no rebase needed. */
1024
+ cleanFastForward?: boolean;
1025
+ /** Whether an `origin` remote is configured. */
1026
+ hasRemote?: boolean;
1027
+ /** Whether the `gh` CLI is available on the host. */
1028
+ ghAvailable?: boolean;
1029
+ /** Resolved base branch name the work would land on. */
1030
+ baseRef?: string;
1031
+ /** Human-readable reason a merge can't proceed (no work, dirty, missing). */
1032
+ reason?: string;
1033
+ /** Set when the worktree path no longer exists. */
1034
+ missing?: boolean;
1035
+ /** Populated when git interrogation failed. */
1036
+ error?: string;
1037
+ }
1038
+ /** Outcome of a `workspace.merge` command executed on the host. */
1039
+ export interface WorkspaceMergeResult {
1040
+ workspaceId?: string;
1041
+ /** Strategy actually used. */
1042
+ strategy: "pr" | "rebase-ff";
1043
+ /** True when work was landed locally (rebase-ff into base). */
1044
+ merged: boolean;
1045
+ /** True when a merge was prevented by conflicts. */
1046
+ conflict?: boolean;
1047
+ /** PR URL when the pr strategy opened one. */
1048
+ prUrl?: string;
1049
+ branch?: string;
1050
+ baseRef?: string;
1051
+ /** SHA base now points at after a successful rebase-ff. */
1052
+ mergedSha?: string;
1053
+ branchDeleted?: boolean;
1054
+ worktreeRemoved?: boolean;
1055
+ /** Resulting workspace status the relay should record. */
1056
+ status: WorkspaceStatus;
1057
+ /** Populated when the merge could not complete. */
1058
+ error?: string;
1059
+ }
1060
+ /** One changed file in a workspace diff against its base. */
1061
+ export interface WorkspaceDiffFile {
1062
+ path: string;
1063
+ /** Lines added (undefined for binary files). */
1064
+ additions?: number;
1065
+ /** Lines removed (undefined for binary files). */
1066
+ deletions?: number;
1067
+ binary?: boolean;
1068
+ }
1069
+ /** Diff of a workspace's committed work against its base, computed on the host. */
1070
+ export interface WorkspaceDiff {
1071
+ baseRef?: string;
1072
+ ahead?: number;
1073
+ files: WorkspaceDiffFile[];
1074
+ /** Unified patch text (may be truncated). */
1075
+ patch?: string;
1076
+ /** True when the patch was capped at the size limit. */
1077
+ truncated?: boolean;
1078
+ /** Uncommitted entries in the worktree, not part of the committed diff. */
1079
+ dirtyCount?: number;
1080
+ missing?: boolean;
1081
+ error?: string;
1082
+ }
1083
+ /** A worktree found on disk with no matching active workspace row. */
1084
+ export interface WorkspaceOrphan {
1085
+ worktreePath: string;
1086
+ repoRoot: string;
1087
+ branch?: string;
1088
+ headSha?: string;
1089
+ /** True if a DB row exists for this path but is already terminal (cleaned/merged). */
1090
+ hadTerminalRow?: boolean;
1091
+ }
1092
+ export interface WorkspaceMetadata {
1093
+ id?: string;
1094
+ mode: WorkspaceMode;
1095
+ requestedMode?: WorkspaceMode;
1096
+ repoRoot?: string;
1097
+ sourceCwd?: string;
1098
+ worktreePath?: string;
1099
+ branch?: string;
1100
+ baseRef?: string;
1101
+ baseSha?: string;
1102
+ status?: WorkspaceStatus;
1103
+ stewardAgentId?: string;
1104
+ probe?: WorkspaceProbe;
1105
+ }
1106
+ export interface WorkspaceRecord {
1107
+ id: string;
1108
+ repoRoot: string;
1109
+ sourceCwd: string;
1110
+ worktreePath: string;
1111
+ branch?: string;
1112
+ baseRef?: string;
1113
+ baseSha?: string;
1114
+ mode: WorkspaceMode;
1115
+ requestedMode?: WorkspaceMode;
1116
+ status: WorkspaceStatus;
1117
+ ownerAgentId?: string;
1118
+ ownerPolicyName?: string;
1119
+ ownerAutomationRunId?: string;
1120
+ stewardAgentId?: string;
1121
+ metadata: Record<string, unknown>;
1122
+ createdAt: number;
1123
+ updatedAt: number;
1124
+ readyAt?: number;
1125
+ cleanedAt?: number;
1126
+ }
1127
+ export interface ConfigEntry<T = unknown> {
1128
+ namespace: string;
1129
+ key: string;
1130
+ value: T;
1131
+ version: number;
1132
+ updatedAt: string;
1133
+ updatedBy?: string;
1134
+ }
1135
+ export interface ConfigHistoryEntry<T = unknown> {
1136
+ id: number;
1137
+ namespace: string;
1138
+ key: string;
1139
+ value: T;
1140
+ version: number;
1141
+ changedAt: string;
1142
+ changedBy?: string;
1143
+ }
1144
+ export type ManagedAgentStatus = "stopped" | "starting" | "running" | "stopping" | "backoff";
1145
+ export interface ManagedAgentState {
1146
+ policyName: string;
1147
+ status: ManagedAgentStatus;
1148
+ agentId?: string;
1149
+ orchestratorId: string;
1150
+ provider: SpawnProvider;
1151
+ tmuxSession?: string;
1152
+ spawnRequestId?: string;
1153
+ workspaceId?: string;
1154
+ workspacePath?: string;
1155
+ workspaceBranch?: string;
1156
+ lastSpawnAt?: number;
1157
+ lastStopAt?: number;
1158
+ healthySince?: number;
1159
+ restartCount: number;
1160
+ consecutiveFailures: number;
1161
+ backoffUntil?: number;
1162
+ lastError?: string;
1163
+ updatedAt: number;
1164
+ }
1165
+ export type SpawnPolicyMode = "always-on" | "on-demand";
1166
+ export type AgentProfileProvider = SpawnProvider | "any";
1167
+ export type AgentProfileBase = "host" | "minimal" | "isolated";
1168
+ export type AgentProfileInstructionPolicy = "allow" | "ignore";
1169
+ export type AgentProfileCategoryMode = "host" | "profile" | "repo" | "none";
1170
+ export type AgentProfileFilesystemScope = "repo" | "workspace" | "host";
1171
+ export interface AgentProfileAssetRef {
1172
+ source: "relay" | "repo" | "inline" | "provider";
1173
+ ref: string;
1174
+ enabled: boolean;
1175
+ provider?: AgentProfileProvider;
1176
+ meta?: Record<string, unknown>;
1177
+ }
1178
+ export interface AgentProfile {
1179
+ name: string;
1180
+ description?: string;
1181
+ provider?: AgentProfileProvider;
1182
+ base: AgentProfileBase;
1183
+ builtIn?: boolean;
1184
+ instructions: {
1185
+ system?: string;
1186
+ append: string[];
1187
+ repoInstructions: AgentProfileInstructionPolicy;
1188
+ globalInstructions: AgentProfileInstructionPolicy;
1189
+ };
1190
+ relay: {
1191
+ context: boolean;
1192
+ skills: boolean;
1193
+ plugins: boolean;
1194
+ statusLine: boolean;
1195
+ };
1196
+ skills: AgentProfileAssetRef[];
1197
+ plugins: AgentProfileAssetRef[];
1198
+ mcp: {
1199
+ mode: AgentProfileCategoryMode;
1200
+ servers?: Record<string, unknown>;
1201
+ };
1202
+ hooks: {
1203
+ mode: AgentProfileCategoryMode;
1204
+ };
1205
+ permissions: {
1206
+ mode?: SpawnApprovalMode;
1207
+ filesystem: AgentProfileFilesystemScope;
1208
+ };
1209
+ env: Record<string, string>;
1210
+ providerOptions: Record<string, unknown>;
1211
+ }
1212
+ export type AgentProfileProjectionResult = "applied" | "partial" | "unsupported" | "not-applicable";
1213
+ export interface AgentProfileProjectionEntry {
1214
+ capability: string;
1215
+ requested: string;
1216
+ result: AgentProfileProjectionResult;
1217
+ detail: string;
1218
+ }
1219
+ export interface AgentProfileProjectionReport {
1220
+ profileName: string;
1221
+ provider: SpawnProvider;
1222
+ base: AgentProfileBase;
1223
+ generatedAt: number;
1224
+ entries: AgentProfileProjectionEntry[];
1225
+ warnings: string[];
1226
+ unsupported: string[];
1227
+ }
1228
+ export interface SpawnPolicy {
1229
+ name: string;
1230
+ description?: string;
1231
+ enabled?: boolean;
1232
+ orchestratorId: string;
1233
+ cwd: string;
1234
+ provider: SpawnProvider;
1235
+ workspaceMode?: WorkspaceMode;
1236
+ rig?: string;
1237
+ model?: string;
1238
+ effort?: SpawnEffort;
1239
+ profile?: string;
1240
+ providerArgs: string[];
1241
+ prompt?: string;
1242
+ tags: string[];
1243
+ capabilities: string[];
1244
+ label?: string;
1245
+ mode: SpawnPolicyMode;
1246
+ permissionMode: SpawnApprovalMode;
1247
+ restartOnUpdate: boolean;
1248
+ scheduledDailyRestart: boolean;
1249
+ onDemand?: {
1250
+ keepaliveSeconds: number;
1251
+ idleDefinition: "no-activity";
1252
+ };
1253
+ backoff: {
1254
+ schedule: number[];
1255
+ resetAfterSeconds: number;
1256
+ };
1257
+ binding?: {
1258
+ type: "channel";
1259
+ channelId: string;
1260
+ };
1261
+ }
493
1262
  export interface Orchestrator {
494
1263
  id: string;
495
1264
  hostname: string;
496
1265
  status: OrchestratorStatus;
497
1266
  agentId: string;
498
1267
  providers: SpawnProvider[];
1268
+ providerStatus?: ProviderStatusReport[];
1269
+ providerCatalog?: ProviderCatalogSummary[];
499
1270
  baseDir: string;
500
1271
  apiUrl?: string;
501
1272
  envKeys: string[];
1273
+ package?: RuntimePackageMetadata;
1274
+ contracts?: RuntimeContracts;
1275
+ capabilities?: RuntimeCapabilities;
1276
+ contractCompatibility?: ContractCompatibility;
502
1277
  version?: string;
503
1278
  protocolVersion?: number;
504
1279
  gitSha?: string;
505
1280
  health?: OrchestratorHealth;
1281
+ supervisor?: "process" | "systemd" | "unknown";
1282
+ selfUnit?: string;
1283
+ runtimePrefix?: string;
1284
+ upgrade?: OrchestratorUpgradeState;
506
1285
  meta: Record<string, unknown>;
507
1286
  managedAgents: ManagedAgent[];
508
1287
  lastSeen: number;
509
1288
  createdAt: number;
510
1289
  }
1290
+ export interface OrchestratorUpgradeState {
1291
+ desiredVersion: string;
1292
+ status: "pending" | "succeeded" | "failed";
1293
+ commandId?: string;
1294
+ providers?: string[];
1295
+ fromVersion?: string;
1296
+ requestedBy?: string;
1297
+ requestedAt: number;
1298
+ settledAt?: number;
1299
+ error?: string;
1300
+ }
511
1301
  export interface OrchestratorHealth {
512
- status: "ok" | "warn" | "error";
1302
+ status: "ok" | "warn" | "restart-required" | "upgrade-required" | "unknown";
513
1303
  restartRequired: boolean;
1304
+ upgradeRequired?: boolean;
514
1305
  issues: Array<{
515
- code: "missing-version" | "outdated" | "protocol-mismatch" | "restart-required";
1306
+ code: "missing-version" | "package-drift" | "missing-contract" | "protocol-mismatch" | "restart-required" | "upgrade-required";
516
1307
  detail: string;
517
1308
  }>;
518
1309
  }
519
1310
  export interface ManagedAgent {
520
1311
  agentId: string;
521
1312
  provider: SpawnProvider;
1313
+ model?: string;
1314
+ effort?: SpawnEffort;
1315
+ profile?: string;
1316
+ workspaceMode?: WorkspaceMode;
1317
+ workspace?: WorkspaceMetadata;
1318
+ sessionName?: string;
1319
+ supervisor?: "process" | "systemd" | "unknown";
1320
+ systemdUnit?: string;
1321
+ terminalSession?: string;
1322
+ terminalAvailable?: boolean;
522
1323
  tmuxSession: string;
523
1324
  cwd: string;
524
1325
  label?: string;
525
1326
  approvalMode: SpawnApprovalMode;
1327
+ policyName?: string;
1328
+ spawnRequestId?: string;
1329
+ automationRunId?: string;
526
1330
  pid?: number;
527
1331
  startedAt: number;
528
1332
  }
1333
+ export interface ManagedSessionExitDiagnostics {
1334
+ agentId: string;
1335
+ provider: SpawnProvider;
1336
+ workspaceMode?: WorkspaceMode;
1337
+ workspace?: WorkspaceMetadata;
1338
+ sessionName?: string;
1339
+ tmuxSession: string;
1340
+ cwd: string;
1341
+ label?: string;
1342
+ policyName?: string;
1343
+ spawnRequestId?: string;
1344
+ automationRunId?: string;
1345
+ supervisor: "process" | "systemd" | "unknown";
1346
+ systemdUnit?: string;
1347
+ terminalSession?: string;
1348
+ terminalAvailable?: boolean;
1349
+ pid?: number;
1350
+ currentPid?: number;
1351
+ startedAt: number;
1352
+ detectedAt: number;
1353
+ runtimeMs: number;
1354
+ logFile?: string;
1355
+ logBytes?: number;
1356
+ logEmpty?: boolean;
1357
+ logTail?: string[];
1358
+ runnerInfoFile?: string;
1359
+ runnerInfoPresent?: boolean;
1360
+ systemd?: {
1361
+ unit: string;
1362
+ activeState?: string;
1363
+ subState?: string;
1364
+ result?: string;
1365
+ execMainCode?: string;
1366
+ execMainStatus?: string;
1367
+ mainPid?: number;
1368
+ unavailable?: string;
1369
+ };
1370
+ unavailable?: string[];
1371
+ lastError: string;
1372
+ }
529
1373
  export interface RegisterOrchestratorInput {
530
1374
  id: string;
531
1375
  hostname: string;
532
1376
  providers: SpawnProvider[];
1377
+ providerStatus?: ProviderStatusReport[];
1378
+ providerCatalog?: ProviderCatalogSummary[];
533
1379
  baseDir: string;
534
1380
  apiUrl?: string;
535
1381
  envKeys?: string[];
1382
+ package?: RuntimePackageMetadata;
1383
+ contracts?: RuntimeContracts;
1384
+ capabilities?: RuntimeCapabilities;
536
1385
  version?: string;
537
1386
  protocolVersion?: number;
538
1387
  gitSha?: string;
539
1388
  meta?: Record<string, unknown>;
540
1389
  }
541
1390
  export interface OrchestratorRuntimeInput {
1391
+ package?: RuntimePackageMetadata;
1392
+ contracts?: RuntimeContracts;
1393
+ capabilities?: RuntimeCapabilities;
542
1394
  version?: string;
543
1395
  protocolVersion?: number;
544
1396
  gitSha?: string;
1397
+ providers?: SpawnProvider[];
1398
+ providerStatus?: ProviderStatusReport[];
1399
+ providerCatalog?: ProviderCatalogSummary[];
545
1400
  }
546
1401
  export interface OrchestratorSpawnInput {
547
1402
  provider: SpawnProvider;
1403
+ model?: string;
1404
+ effort?: SpawnEffort;
548
1405
  cwd?: string;
1406
+ workspaceMode?: WorkspaceMode;
549
1407
  label?: string;
550
1408
  approvalMode?: SpawnApprovalMode;
551
1409
  prompt?: string;
1410
+ systemPromptAppend?: string;
552
1411
  env?: Record<string, string>;
553
1412
  }
1413
+ export interface ProviderStatusReport {
1414
+ name: SpawnProvider;
1415
+ available: boolean;
1416
+ checkedAt: number;
1417
+ reason?: string;
1418
+ version?: string;
1419
+ features?: Record<string, boolean>;
1420
+ cli?: {
1421
+ command: string;
1422
+ path?: string;
1423
+ ok: boolean;
1424
+ version?: string;
1425
+ error?: string;
1426
+ };
1427
+ runner?: {
1428
+ command: string;
1429
+ path?: string;
1430
+ ok: boolean;
1431
+ version?: string;
1432
+ error?: string;
1433
+ };
1434
+ }
1435
+ export interface ProviderCatalogSummary {
1436
+ provider: SpawnProvider;
1437
+ label: string;
1438
+ defaultModel?: string;
1439
+ models: Array<{
1440
+ alias: string;
1441
+ label: string;
1442
+ providerModel: string;
1443
+ efforts: SpawnEffort[];
1444
+ defaultEffort?: SpawnEffort;
1445
+ limits?: {
1446
+ contextWindowTokens?: {
1447
+ value: number;
1448
+ source: "catalog" | "provider" | "runtime" | "override";
1449
+ confidence: "declared" | "verified" | "estimated" | "unknown";
1450
+ lastUpdatedAt?: number;
1451
+ };
1452
+ maxOutputTokens?: {
1453
+ value: number;
1454
+ source: "catalog" | "provider" | "runtime" | "override";
1455
+ confidence: "declared" | "verified" | "estimated" | "unknown";
1456
+ lastUpdatedAt?: number;
1457
+ };
1458
+ };
1459
+ capabilities?: {
1460
+ modalities: {
1461
+ input: {
1462
+ text: boolean;
1463
+ image?: boolean;
1464
+ audio?: boolean;
1465
+ video?: boolean;
1466
+ pdf?: boolean;
1467
+ };
1468
+ output: {
1469
+ text: boolean;
1470
+ image?: boolean;
1471
+ audio?: boolean;
1472
+ video?: boolean;
1473
+ };
1474
+ };
1475
+ tools?: {
1476
+ code?: boolean;
1477
+ review?: boolean;
1478
+ debug?: boolean;
1479
+ refactor?: boolean;
1480
+ shell?: boolean;
1481
+ fileRead?: boolean;
1482
+ fileWrite?: boolean;
1483
+ webSearch?: boolean;
1484
+ imageGeneration?: boolean;
1485
+ imageEditing?: boolean;
1486
+ };
1487
+ source: "catalog" | "provider" | "runtime" | "override";
1488
+ confidence: "declared" | "verified" | "estimated" | "unknown";
1489
+ lastUpdatedAt?: number;
1490
+ };
1491
+ }>;
1492
+ }
554
1493
  export interface OrchestratorSpawnResult {
555
1494
  orchestratorId: string;
556
1495
  provider: SpawnProvider;
1496
+ sessionName?: string;
1497
+ supervisor?: "process" | "systemd" | "unknown";
1498
+ systemdUnit?: string;
1499
+ terminalSession?: string;
1500
+ terminalAvailable?: boolean;
557
1501
  tmuxSession: string;
558
1502
  cwd: string;
559
1503
  label?: string;
@@ -577,9 +1521,11 @@ export interface RecipeAgent {
577
1521
  capabilities: string[];
578
1522
  label?: string;
579
1523
  tags?: string[];
1524
+ memoryTags?: string[];
580
1525
  approvalMode?: "open" | "guarded" | "read-only";
581
1526
  prompt?: string;
582
1527
  model?: string;
1528
+ effort?: SpawnEffort;
583
1529
  env?: Record<string, string>;
584
1530
  }
585
1531
  export interface RecipeWorkflow {
@@ -595,6 +1541,19 @@ export interface RecipeRoute {
595
1541
  export interface RecipeLifecycle {
596
1542
  mode?: "persistent" | "ephemeral";
597
1543
  idleTimeoutMs?: number;
1544
+ memory?: RecipeMemoryPolicy;
1545
+ }
1546
+ export interface RecipeMemoryPolicy {
1547
+ injectOnAssign?: boolean;
1548
+ autoCapture?: boolean;
1549
+ captureTypes?: MemoryType[];
1550
+ memoryTags?: string[];
1551
+ alwaysReload?: string[];
1552
+ scope?: string;
1553
+ maxTokens?: number;
1554
+ maxMemories?: number;
1555
+ priorityCutoff?: 1 | 2 | 3;
1556
+ ttlMs?: number;
598
1557
  }
599
1558
  export interface RecipeInstance {
600
1559
  id: string;
@@ -604,6 +1563,7 @@ export interface RecipeInstance {
604
1563
  orchestratorId: string;
605
1564
  status: "starting" | "running" | "stopping" | "stopped" | "failed";
606
1565
  agents: RecipeAgentInstance[];
1566
+ artifacts?: Artifact[];
607
1567
  startedAt: number;
608
1568
  stoppedAt?: number;
609
1569
  startedBy: string;
@@ -620,16 +1580,105 @@ export interface ComponentToken {
620
1580
  sub: string;
621
1581
  role: "provider" | "channel" | "orchestrator" | "admin" | "dashboard" | string;
622
1582
  scope: string[];
1583
+ constraints?: TokenConstraints;
623
1584
  iat: number;
624
1585
  exp?: number;
625
1586
  jti?: string;
626
1587
  }
627
- export type TokenScope = "agent:read" | "agent:write" | "message:send" | "message:read" | "command:spawn" | "command:shutdown" | "command:*" | "task:read" | "task:write" | "recipe:start" | "recipe:stop" | "admin:*";
1588
+ export interface TokenRecord {
1589
+ jti: string;
1590
+ sub: string;
1591
+ role: string;
1592
+ scope: string[];
1593
+ constraints?: TokenConstraints;
1594
+ profileId?: string;
1595
+ issuedAt: number;
1596
+ expiresAt?: number;
1597
+ revokedAt?: number;
1598
+ createdBy?: string;
1599
+ }
1600
+ export interface TokenProfile {
1601
+ id: string;
1602
+ name: string;
1603
+ description?: string;
1604
+ role: string;
1605
+ scope: string[];
1606
+ constraints?: TokenConstraints;
1607
+ ttlSeconds?: number;
1608
+ builtIn: boolean;
1609
+ createdAt: number;
1610
+ updatedAt: number;
1611
+ createdBy?: string;
1612
+ }
1613
+ export interface CreateTokenProfileInput {
1614
+ id?: string;
1615
+ name: string;
1616
+ description?: string;
1617
+ role: string;
1618
+ scope: string[];
1619
+ constraints?: TokenConstraints;
1620
+ ttlSeconds?: number;
1621
+ createdBy?: string;
1622
+ }
1623
+ export type UpdateTokenProfileInput = Partial<Omit<CreateTokenProfileInput, "id">>;
1624
+ export interface TokenConstraints {
1625
+ agents?: string[];
1626
+ policies?: string[];
1627
+ parentAgents?: string[];
1628
+ targets?: string[];
1629
+ channels?: string[];
1630
+ orchestrators?: string[];
1631
+ hosts?: string[];
1632
+ cwd?: string;
1633
+ cwdPrefixes?: string[];
1634
+ taskIds?: string[];
1635
+ memoryScopes?: string[];
1636
+ integrationNames?: string[];
1637
+ spawnRequestIds?: string[];
1638
+ terminalAttach?: boolean;
1639
+ logsRead?: boolean;
1640
+ canDelegate?: boolean;
1641
+ }
1642
+ export type TokenScope = "system:admin" | "token:read" | "token:write" | "agent:read" | "agent:write" | "message:read" | "message:send" | "task:read" | "task:write" | "command:read" | "command:write" | "command:*" | "artifact:read" | "artifact:write" | "artifact:admin" | "memory:read" | "memory:write" | "memory:admin" | "mcp:use" | "terminal:attach" | "logs:read" | "integration:read" | "integration:write" | "channel:read" | "channel:write" | "stats:read" | "health:read" | "events:read" | "command:spawn" | "command:shutdown" | "recipe:start" | "recipe:stop" | "admin:*";
1643
+ export interface MaintenanceJob {
1644
+ id: string;
1645
+ title: string;
1646
+ description?: string;
1647
+ intervalMs: number;
1648
+ timeoutMs: number;
1649
+ enabled: boolean;
1650
+ runOnStart: boolean;
1651
+ lastRunAt?: number;
1652
+ nextRunAt?: number;
1653
+ lastDurationMs?: number;
1654
+ lastStatus: "idle" | "running" | "succeeded" | "failed" | "disabled";
1655
+ lastError?: string;
1656
+ lastResult?: Record<string, unknown>;
1657
+ consecutiveFailures: number;
1658
+ running: boolean;
1659
+ leaseUntil?: number;
1660
+ updatedAt: number;
1661
+ }
1662
+ export interface MaintenanceJobRun {
1663
+ id: string;
1664
+ status: "succeeded" | "failed" | "skipped";
1665
+ startedAt: number;
1666
+ finishedAt: number;
1667
+ durationMs: number;
1668
+ result?: Record<string, unknown>;
1669
+ error?: string;
1670
+ }
628
1671
  export interface HealthCheck {
629
1672
  name: string;
630
1673
  status: "ok" | "warn" | "error";
631
1674
  detail?: string;
632
1675
  count?: number;
1676
+ subjects?: Array<{
1677
+ id: string;
1678
+ label?: string;
1679
+ status?: string;
1680
+ detail?: string;
1681
+ }>;
633
1682
  }
634
1683
  export interface HealthReport {
635
1684
  status: "ok" | "degraded" | "error";