@agent-compose/sdk 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +66 -39
  2. package/dist/agent/__tests__/runtime-json-schema.test.d.ts +10 -0
  3. package/dist/agent/agent-context.d.ts +21 -1
  4. package/dist/agent/agent-loop.d.ts +24 -1
  5. package/dist/client.d.ts +338 -534
  6. package/dist/directives.d.ts +112 -0
  7. package/dist/display.d.ts +242 -0
  8. package/dist/errors.d.ts +24 -1
  9. package/dist/index.d.ts +34 -13
  10. package/dist/index.js +2984 -861
  11. package/dist/pause/wrappers.d.ts +31 -9
  12. package/dist/processors/ask-human.d.ts +30 -0
  13. package/dist/processors/ask-human.test.d.ts +1 -0
  14. package/dist/processors/index.d.ts +1 -0
  15. package/dist/runtimes/_acp-client.d.ts +46 -1
  16. package/dist/runtimes/_cli-agent.d.ts +58 -4
  17. package/dist/runtimes/_jsonl-guard.d.ts +103 -0
  18. package/dist/runtimes/amp.d.ts +2 -2
  19. package/dist/runtimes/claude-code.d.ts +59 -0
  20. package/dist/runtimes/claude-code.test.d.ts +14 -0
  21. package/dist/runtimes/claude.d.ts +16 -0
  22. package/dist/runtimes/claude.test.d.ts +8 -0
  23. package/dist/runtimes/codex.d.ts +9 -3
  24. package/dist/runtimes/cursor.d.ts +9 -0
  25. package/dist/runtimes/droid.d.ts +9 -0
  26. package/dist/runtimes/jsonl-guard.test.d.ts +19 -0
  27. package/dist/runtimes/openai-desktop.js +2922 -861
  28. package/dist/runtimes/opencode.d.ts +25 -0
  29. package/dist/runtimes/vercel.js +22 -1
  30. package/dist/sandbox/devbox.d.ts +42 -0
  31. package/dist/sandbox/exec-stream.d.ts +14 -0
  32. package/dist/sandbox/network-policy.d.ts +100 -0
  33. package/dist/sandbox/provider-def.d.ts +79 -0
  34. package/dist/sandbox/providers/desktop.d.ts +10 -0
  35. package/dist/sandbox/providers/e2b.d.ts +17 -0
  36. package/dist/sandbox/providers/local.d.ts +11 -0
  37. package/dist/sandbox/providers/vercel.d.ts +18 -0
  38. package/dist/sandbox/registry.d.ts +45 -0
  39. package/dist/sandbox/sizes.d.ts +68 -0
  40. package/dist/sandbox.d.ts +24 -299
  41. package/dist/step-invocation/__tests__/foreground-recovery.test.d.ts +1 -0
  42. package/dist/step-invocation/invoker.d.ts +24 -1
  43. package/dist/step-invocation/protocol.d.ts +13 -0
  44. package/dist/types/api-compliance.d.ts +71 -0
  45. package/dist/types/api-conversations.d.ts +492 -0
  46. package/dist/types/api-factory.d.ts +309 -0
  47. package/dist/types/api-projects.d.ts +131 -0
  48. package/dist/types/api-runs.d.ts +377 -0
  49. package/dist/types/api-scopes.d.ts +102 -0
  50. package/dist/types/conversation-stream.d.ts +191 -0
  51. package/dist/types/execution-context.d.ts +12 -2
  52. package/dist/types/protocol.d.ts +30 -1
  53. package/dist/types/sandbox-environment.d.ts +8 -5
  54. package/dist/types/sandbox.d.ts +79 -0
  55. package/dist/types/workflow-metadata.d.ts +33 -8
  56. package/dist/types/workflow-plan.d.ts +10 -0
  57. package/dist/types/workflow.d.ts +18 -193
  58. package/dist/utils/bundler.d.ts +12 -1
  59. package/dist/utils/errors.d.ts +9 -1
  60. package/dist/workflow-steps/index.d.ts +1 -1
  61. package/dist/workflow-steps/observability.d.ts +8 -1
  62. package/dist/workflow-steps/runner.d.ts +3 -3
  63. package/dist/workflow-steps/step.d.ts +15 -1
  64. package/dist/workflow-steps/types.d.ts +19 -5
  65. package/dist/workflow-steps/workflow.d.ts +22 -1
  66. package/dist/workflows/engine.d.ts +3 -2
  67. package/dist/workflows/invoke-child.d.ts +2 -2
  68. package/package.json +1 -1
  69. package/src/agent/agent-context.ts +206 -16
  70. package/src/agent/agent-loop.ts +40 -4
  71. package/src/agent/run-agent.ts +9 -1
  72. package/src/client.ts +909 -621
  73. package/src/directives.ts +184 -0
  74. package/src/display.ts +788 -0
  75. package/src/errors.ts +39 -0
  76. package/src/index.ts +117 -10
  77. package/src/pause/wrappers.ts +44 -9
  78. package/src/processors/ask-human.ts +136 -0
  79. package/src/processors/index.ts +5 -0
  80. package/src/runtimes/_acp-client.ts +72 -3
  81. package/src/runtimes/_cli-agent.ts +171 -38
  82. package/src/runtimes/_jsonl-guard.ts +219 -0
  83. package/src/runtimes/claude-code.ts +246 -0
  84. package/src/runtimes/claude.ts +32 -2
  85. package/src/runtimes/codex.ts +55 -3
  86. package/src/runtimes/cursor.ts +59 -0
  87. package/src/runtimes/droid.ts +63 -0
  88. package/src/runtimes/openai-desktop.ts +59 -14
  89. package/src/runtimes/opencode.ts +61 -0
  90. package/src/sandbox/devbox.ts +48 -0
  91. package/src/sandbox/exec-stream.ts +48 -0
  92. package/src/sandbox/network-policy.ts +181 -0
  93. package/src/sandbox/provider-def.ts +94 -0
  94. package/src/sandbox/providers/desktop.ts +57 -0
  95. package/src/sandbox/providers/e2b.ts +354 -0
  96. package/src/sandbox/providers/local.ts +106 -0
  97. package/src/sandbox/providers/vercel.ts +331 -0
  98. package/src/sandbox/registry.ts +198 -0
  99. package/src/sandbox/sizes.ts +95 -0
  100. package/src/sandbox.ts +59 -1263
  101. package/src/step-invocation/invoker.ts +319 -34
  102. package/src/step-invocation/protocol.ts +19 -0
  103. package/src/types/api-compliance.ts +79 -0
  104. package/src/types/api-conversations.ts +522 -0
  105. package/src/types/api-factory.ts +336 -0
  106. package/src/types/api-projects.ts +140 -0
  107. package/src/types/api-runs.ts +412 -0
  108. package/src/types/api-scopes.ts +102 -0
  109. package/src/types/conversation-stream.ts +231 -0
  110. package/src/types/execution-context.ts +10 -2
  111. package/src/types/protocol.ts +33 -0
  112. package/src/types/sandbox-environment.ts +28 -9
  113. package/src/types/sandbox.ts +78 -0
  114. package/src/types/workflow-metadata.ts +35 -8
  115. package/src/types/workflow-plan.ts +11 -0
  116. package/src/types/workflow.ts +25 -280
  117. package/src/utils/bundler.ts +32 -5
  118. package/src/utils/errors.ts +34 -2
  119. package/src/workflow-steps/index.ts +1 -0
  120. package/src/workflow-steps/observability.ts +19 -8
  121. package/src/workflow-steps/runner.ts +4 -4
  122. package/src/workflow-steps/step.ts +49 -1
  123. package/src/workflow-steps/types.ts +20 -5
  124. package/src/workflow-steps/workflow.ts +22 -1
  125. package/src/workflows/engine.ts +3 -2
  126. package/src/workflows/invoke-child.ts +2 -2
@@ -0,0 +1,412 @@
1
+ /**
2
+ * Run-facing wire types for `AgentComposeClient` — invocation, status,
3
+ * pause/steer control, run detail/listing, lifecycle events, logs,
4
+ * artifacts, and snapshots.
5
+ *
6
+ * These are deliberate contract pins mirrored in `dashboard/src/lib/api.ts`;
7
+ * when the server changes a response shape, both update in the same change.
8
+ */
9
+
10
+ import type { SandboxNetworkPolicy, SandboxSize } from "../sandbox.js";
11
+ import type { SnapshotConfig } from "./workflow-metadata.js";
12
+ import type { RunContext } from "./api-scopes.js";
13
+
14
+ export type RunState = "running" | "success" | "failed" | "abandoned" | "canceled";
15
+
16
+ export interface InvokeWorkflowOptions {
17
+ /** Per-invocation snapshot config override. `snapshots.bootFrom`
18
+ * replaces the template's boot source; `snapshots.saveLatest` and
19
+ * `snapshots.retainSteps` override capture mode. Anything omitted
20
+ * falls back to the template's registered default. */
21
+ snapshots?: SnapshotConfig;
22
+ /** Per-invocation network policy override. Replaces the template-level
23
+ * policy for this run only — registered metadata is not mutated. */
24
+ networkPolicy?: SandboxNetworkPolicy;
25
+ /** Per-invocation placeholder override. Maps secret names referenced in
26
+ * `networkPolicy` ($VAR) to the values the runner should see for env
27
+ * vars after brokering. Replaces the template-level placeholders for
28
+ * this run only — registered metadata is not mutated. */
29
+ placeholders?: Record<string, string>;
30
+ /** Per-invocation machine-size override of the template's `resources.size`.
31
+ * `small` (default) | `medium` | `large`; omit → the template default,
32
+ * else `small`. Honoured on Vercel (→ vCPUs); E2B ignores it. */
33
+ size?: SandboxSize;
34
+ /** Explicit parent run id. Pass `null` to suppress ambient RUN_ID auto-detection. */
35
+ parentRunId?: string | null;
36
+ /** Agent loop inside the parent run that caused this invoke, when applicable. */
37
+ agentId?: string | null;
38
+ /** Factory slug. Defaults to `"default"`. */
39
+ factorySlug?: string;
40
+ /** Idempotency key — sent as the `Idempotency-Key` header. A repeat invoke
41
+ * with the same key inside the server's dedup window returns the original
42
+ * run instead of starting a new one (matches `resumePause`'s pattern). */
43
+ idempotencyKey?: string;
44
+ }
45
+
46
+ export interface InvokeAndWaitOptions extends InvokeWorkflowOptions {
47
+ timeoutMs?: number;
48
+ pollIntervalMs?: number;
49
+ }
50
+
51
+ export interface InvokeResult {
52
+ id: string;
53
+ }
54
+
55
+ export interface StreamRunLogsOptions {
56
+ lastEventId?: number;
57
+ signal?: AbortSignal;
58
+ }
59
+
60
+ export interface RunStatus<TOutput = unknown> {
61
+ id: string;
62
+ status: RunState;
63
+ output?: TOutput;
64
+ /** The run's latest (`saveLatest`) snapshot id, populated once the run has
65
+ * succeeded — the boot source to fork this run's evolved filesystem from
66
+ * (pass as `snapshots.bootFrom` on a follow-up invoke). `null` while the run
67
+ * is still in flight or when it captured no snapshot. Lets an orchestrator
68
+ * fork a child straight off the `invokeChild` result without a separate
69
+ * `listRunSnapshots` call. */
70
+ latestSnapshotId?: string | null;
71
+ }
72
+
73
+ /** ADR-0006 step 10 — actor record returned on a successful resume.
74
+ * Shape mirrors the server's `PauseResumeActor` type after the row
75
+ * has been stamped. Audit FKs (`userId` / `keyId` / `runId`) may be
76
+ * null when the referenced row was deleted between resume and the
77
+ * response render — the immutable `label` survives. */
78
+ export interface ResumePauseActor {
79
+ kind: "session_user" | "api_key" | "agent";
80
+ /** Better Auth user id when kind='session_user'. */
81
+ userId?: string | null;
82
+ /** api_keys.id when kind='api_key'. */
83
+ keyId?: string | null;
84
+ /** Caller-run id when kind='agent' (NOT the run being resumed). */
85
+ runId?: string | null;
86
+ /** Agent-instance within `runId` when kind='agent'. */
87
+ agentId?: string | null;
88
+ label: string;
89
+ }
90
+
91
+ /** Success branch of the resume HTTP response. The pause has reached
92
+ * a terminal state — `resolved` (workflow signal arrived), `expired`
93
+ * (TTL fired first), or `cancelled` (workflow terminated mid-pause).
94
+ * Only `resolved` carries the resume payload the user supplied. */
95
+ export interface ResumePauseSuccess {
96
+ status: "resolved" | "expired" | "cancelled";
97
+ pauseId: string;
98
+ resolvedAt: string | null;
99
+ resumePayload: unknown;
100
+ actor: ResumePauseActor | null;
101
+ }
102
+
103
+ /** Pending branch — the workflow accepted the signal but the row
104
+ * flip didn't observe within the route's 5s wait window. The
105
+ * operation is in-flight; retry with the same `Idempotency-Key`
106
+ * and the cache collapses the duplicate to a single canonical
107
+ * response. */
108
+ export interface ResumePausePending {
109
+ status: "pending";
110
+ pauseId: string;
111
+ timedOut: true;
112
+ }
113
+
114
+ export type ResumePauseResponse = ResumePauseSuccess | ResumePausePending;
115
+
116
+ export interface ResumePauseOptions {
117
+ /** Stripe-style retry-dedup key — same syntax as the workflow-invoke
118
+ * route: 1..255 chars of `[A-Za-z0-9_\-:.]`, no embedded CR/LF.
119
+ * Sent as the `Idempotency-Key` request header. (The server reads the
120
+ * header first, falling back to a body field for callers behind a
121
+ * header-stripping proxy; this client only sends the header.) */
122
+ idempotencyKey?: string;
123
+ /** Abort the HTTP request mid-wait (e.g. from a UI cancel button).
124
+ * The server's LISTEN tears down via the request's AbortSignal. */
125
+ signal?: AbortSignal;
126
+ }
127
+
128
+ export interface RequestAgentPauseOptions {
129
+ /** Human-readable note surfaced to the agent as the pause reason. */
130
+ reason?: string;
131
+ /** Your handle for answering this pause without the minted pauseId:
132
+ * pass the same value to `resumePauseByKey`. */
133
+ correlationKey?: string;
134
+ /** Abort the HTTP request. */
135
+ signal?: AbortSignal;
136
+ }
137
+
138
+ export interface AnswerSteerOptions extends ResumePauseOptions {
139
+ /** Who answered — surfaced to the agent as `[human steer from <actor>]`. */
140
+ actor?: string;
141
+ }
142
+
143
+ /** 202 envelope from a steer-pause request. The request is best-effort and
144
+ * fire-and-forget: it publishes a transient control message and returns
145
+ * immediately — the agent parks at its next iteration boundary (if it is
146
+ * `mode: "hitl"` and still running). Answer it via `answerSteerByKey`
147
+ * (pass the `correlationKey` you set here) or `answerSteer` (by pauseId). */
148
+ export interface RequestAgentPauseResponse {
149
+ status: "steer_requested";
150
+ runId: string;
151
+ agentId: string;
152
+ }
153
+
154
+ export interface SendAgentMessageOptions {
155
+ /** Transcript attribution. For non-session callers (API key, orchestrator)
156
+ * this names the sender; defaults to the caller's identity server-side. */
157
+ senderName?: string;
158
+ /** Abort the HTTP request. */
159
+ signal?: AbortSignal;
160
+ }
161
+
162
+ /** 202 envelope from a message-to-running-agent request. The message is queued
163
+ * durably and delivered mid-stream as the agent's next user turn — the workflow
164
+ * is NOT paused. `seq` is the message's per-run ordinal. */
165
+ export interface SendAgentMessageResponse {
166
+ status: "message_enqueued";
167
+ runId: string;
168
+ agentId: string;
169
+ seq: number;
170
+ }
171
+
172
+ export interface RunDetail<TOutput = unknown> {
173
+ runId: string;
174
+ title: string;
175
+ metadata: Record<string, unknown>;
176
+ outcome: string;
177
+ startedAt: string;
178
+ endedAt: string | null;
179
+ durationMs: number | null;
180
+ failureReason: string | null;
181
+ input: unknown;
182
+ output: TOutput | null;
183
+ /** Call context (ADR-0045 §3) — both ids null = team-visible ("Team");
184
+ * UI labels private runs "Only you" / "#channel-name". */
185
+ context: RunContext;
186
+ lifecycleEvents: Array<{ at: string; type: string; payload: unknown }>;
187
+ children?: RunDetail[];
188
+ }
189
+
190
+ /** The funding-lane vocabulary: 'platform' (gateway-metered), 'byok'
191
+ * (author's own key), 'subscription' (the initiating user's connected
192
+ * plan). */
193
+ export type FundingLane = "platform" | "byok" | "subscription";
194
+
195
+ /** One per-(step, credential) funding-lane stamp (ADR-0048), recorded at
196
+ * credential resolution — `GET /workflows/:id/funding`. Attribution only:
197
+ * non-platform lanes are the user's own money and are never metered. */
198
+ export interface RunFundingStamp {
199
+ stepIndex: number;
200
+ /** Env-var name (or auth-file path) the sandbox read the credential from. */
201
+ envVar: string;
202
+ /** Provider family — 'anthropic' | 'openai' | 'openrouter' | … */
203
+ provider: string;
204
+ lane: FundingLane;
205
+ /** Platform lane only — the gateway virtual key's alias. */
206
+ keyAlias: string | null;
207
+ }
208
+
209
+ /** One (provider, model) usage group of the run's gateway-attested platform
210
+ * cut — the ONLY usage the ledger records. */
211
+ export interface RunFundingUsageRow {
212
+ provider: string;
213
+ model: string;
214
+ promptTokens: number;
215
+ completionTokens: number;
216
+ cacheReadTokens: number;
217
+ cacheCreationTokens: number;
218
+ calls: number;
219
+ }
220
+
221
+ /** `GET /workflows/:id/funding` — the run's funding-lane surface: per-step
222
+ * lane stamps (recorded at resolution, never re-detected) and the run's
223
+ * gateway-attested platform dollars. Empty `stamps` = the run predates
224
+ * lane stamping. */
225
+ export interface RunFundingResponse {
226
+ object: "run.funding";
227
+ runId: string;
228
+ stamps: RunFundingStamp[];
229
+ stampsTruncated: boolean;
230
+ attested: {
231
+ totalUsd: number;
232
+ rows: Array<RunFundingUsageRow & { costUsd: number }>;
233
+ truncated: boolean;
234
+ };
235
+ }
236
+
237
+ /** One row from the factory runs list (`GET /factories/:slug/runs`) — the
238
+ * summary shape, a strict subset of what the route returns. */
239
+ export interface RunListEntry {
240
+ runId: string;
241
+ title: string;
242
+ /** System-stamped bag; `_workflow` names the registered workflow. */
243
+ metadata: Record<string, unknown>;
244
+ outcome: string;
245
+ paused: boolean;
246
+ startedAt: string;
247
+ endedAt: string | null;
248
+ durationMs: number | null;
249
+ failureReason: string | null;
250
+ /** Call context (ADR-0045 §3) — both ids null = team-visible ("Team"). */
251
+ context: RunContext;
252
+ }
253
+
254
+ export interface ListRunsOptions {
255
+ /** Factory the runs live in. Defaults to "default". */
256
+ factorySlug?: string;
257
+ /** Substring match on the registered workflow name (`metadata._workflow`). */
258
+ workflow?: string;
259
+ /** Substring match across title / task title / branch / run id. */
260
+ search?: string;
261
+ outcome?: string;
262
+ sort?: "newest" | "oldest" | "fastest" | "slowest";
263
+ limit?: number;
264
+ }
265
+
266
+ export interface TimelineEvent {
267
+ kind: string;
268
+ at: string;
269
+ seq: number;
270
+ type: string;
271
+ payload: Record<string, unknown>;
272
+ }
273
+
274
+ export type EventSubjectType = "run" | "agent" | "workflow" | "factory";
275
+
276
+ export interface EventRow {
277
+ id: string;
278
+ teamId: string;
279
+ subjectType: EventSubjectType | string;
280
+ subjectId: string;
281
+ runId: string | null;
282
+ agentId: string | null;
283
+ workflowId: string | null;
284
+ factoryId: string | null;
285
+ name: string;
286
+ body: unknown;
287
+ summary: string | null;
288
+ confidence: string | null;
289
+ timestamp: string;
290
+ attributes: Record<string, unknown>;
291
+ propagate: boolean;
292
+ idempotencyKey: string | null;
293
+ createdAt: string;
294
+ }
295
+
296
+ // The server emits these rows in snake_case; the client maps them to
297
+ // camelCase at the fetch boundary so the SDK surface stays uniform
298
+ // (`EventRow.createdAt`, `RunStatus.latestSnapshotId`, …).
299
+ export interface RunArtifactRow {
300
+ path: string;
301
+ factorySlug: string | null;
302
+ sizeBytes: number | null;
303
+ lastWriteAt: string;
304
+ /** Opening text of the file (≤320 chars) — null for binary/empty. */
305
+ preview: string | null;
306
+ }
307
+
308
+ export interface ReportEventInput {
309
+ name: string;
310
+ body: unknown;
311
+ summary?: string;
312
+ confidence?: number;
313
+ timestamp?: string | Date;
314
+ attributes?: Record<string, unknown>;
315
+ propagate?: boolean;
316
+ idempotencyKey?: string;
317
+ }
318
+
319
+ export interface ListEventsOptions {
320
+ factorySlug?: string;
321
+ limit?: number;
322
+ /** Case-insensitive substring match. Server uses `ILIKE %name%`, so
323
+ * `"site"` matches `site.created`, `site.failed`, etc. Pass the
324
+ * full event name for an effectively-exact filter (any string is a
325
+ * substring of itself). */
326
+ name?: string;
327
+ /** Date-range lower bound: only include events at or after this
328
+ * timestamp. Used by the dashboard's range toggle (1h / 24h / 7d
329
+ * / 30d). Same semantics as `from` on the runs list endpoint. */
330
+ from?: string;
331
+ /** Timestamp cursor for "load older" pagination. Pass the
332
+ * `timestamp` of the last row from the previous page; the server
333
+ * returns rows strictly older than that. Distinct from `from`:
334
+ * `from` filters a date range, `before` walks the page boundary.
335
+ * Both can be supplied together for a paginated range-query. */
336
+ before?: string;
337
+ }
338
+
339
+ export interface ListEventsResult {
340
+ events: EventRow[];
341
+ has_more: boolean;
342
+ }
343
+
344
+ /** One captured stdout or stderr line from a run's sandbox subprocess.
345
+ * `id` is per-run monotonically increasing — pass the highest `id`
346
+ * you've seen as `afterId` to paginate forward. */
347
+ export interface RunLogLine {
348
+ id: number;
349
+ at: string;
350
+ stream: "stdout" | "stderr";
351
+ line: string;
352
+ }
353
+
354
+ export interface ListRunLogsOptions {
355
+ /** Return only lines with `id > afterId` (forward pagination). */
356
+ afterId?: number;
357
+ /** Max lines (server clamps to [1, 1000], defaults to 200). */
358
+ limit?: number;
359
+ /** Stream direction. `"asc"` (default) returns the oldest lines first
360
+ * — use with `afterId` to paginate forward. `"desc"` returns the newest
361
+ * lines first — use to fetch the last N lines of a finished run. */
362
+ direction?: "asc" | "desc";
363
+ }
364
+
365
+ /** Response from `POST /api/v1/workflows/:id/cancel`. The endpoint is
366
+ * idempotent: cancelling a run that's already terminal returns its current
367
+ * outcome verbatim (rather than throwing or pretending it just canceled),
368
+ * so `status` widens to every terminal value the server might surface. */
369
+ export interface CancelRunResponse {
370
+ runId: string;
371
+ status: "canceled" | "success" | "failed" | "abandoned";
372
+ canceledAt: string;
373
+ }
374
+
375
+ export interface ListSnapshotsOptions {
376
+ /** Factory slug. Defaults to `"default"`. */
377
+ factorySlug?: string;
378
+ workflow?: string;
379
+ limit?: number;
380
+ /** Cursor returned as `next_cursor` from `listSnapshotsPage`. */
381
+ before?: string;
382
+ }
383
+
384
+ export interface SnapshotListEntry {
385
+ snapshotId: string;
386
+ kind: "latest" | "step";
387
+ stepIndex: number | null;
388
+ runId: string;
389
+ workflow: string | null;
390
+ version: string | null;
391
+ createdAt: string | null;
392
+ /** Provider-reported on-disk size, or null when unavailable. */
393
+ sizeBytes: number | null;
394
+ }
395
+
396
+ export interface SnapshotListResponse {
397
+ object: "list";
398
+ data: SnapshotListEntry[];
399
+ has_more: boolean;
400
+ next_cursor: string | null;
401
+ }
402
+
403
+ export interface RunSnapshotEntry {
404
+ snapshotId: string;
405
+ /** `"latest"` = current/last pointer on the run.
406
+ * `"step"` = retained per-step snapshot. */
407
+ kind: "latest" | "step";
408
+ stepIndex: number | null;
409
+ createdAt: string | null;
410
+ /** Provider-reported on-disk size, or null when unavailable. */
411
+ sizeBytes: number | null;
412
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Membership-scoped authorization wire types (ADR-0045).
3
+ *
4
+ * Conversation roles, artifact scopes, and run call-context. Wire shapes are
5
+ * pinned by docs/specs/membership-authz-contract.md §6 — the server, this
6
+ * SDK, and dashboard/src/lib/api.ts update together.
7
+ */
8
+
9
+ /** Conversation role ladder — `owner > write > read`. `read` sees the
10
+ * conversation and everything scoped to it; `write` additionally acts
11
+ * (send/react/invite/dispatch); `owner` additionally manages the roster
12
+ * and can delete the conversation. */
13
+ export type ConversationMemberRole = "owner" | "write" | "read";
14
+
15
+ /** One human member of a conversation (channel roster row), with display
16
+ * identity merged in server-side. */
17
+ export interface ConversationMember {
18
+ userId: string;
19
+ name: string | null;
20
+ email: string;
21
+ image: string | null;
22
+ /** Server-relative uploaded-avatar URL (ADR-0056), when set — takes
23
+ * precedence over `image`. Prefix with your API base. */
24
+ avatarUrl?: string | null;
25
+ addedBy: string | null;
26
+ createdAt: string;
27
+ role: ConversationMemberRole;
28
+ }
29
+
30
+ /** Document share capabilities. */
31
+ export type DocumentCapability = "read" | "write";
32
+ /** Template share capabilities. Implications are normative server-side:
33
+ * `write→read`, `invoke→read`, `see_runs→read`. `see_runs` = may view the
34
+ * template's runs (detail, logs, timeline, pauses, artifacts, stream)
35
+ * regardless of call context — read-only, never act. */
36
+ export type TemplateCapability = "read" | "write" | "invoke" | "see_runs";
37
+
38
+ /** One grant on an artifact scope. `team`/`user` are the editable tiers
39
+ * carried on a PUT (full-replace); `session`/`project` are DERIVED,
40
+ * read-only arms that appear only on READ payloads (the routes that manage
41
+ * them own their mutation — a scope PUT rejects them, 400 `invalid_principal`).
42
+ *
43
+ * Session and project grants carry FIXED capabilities `['read','write']`:
44
+ * the fs-gateway is concealment-only (no read/write dimension at the mount),
45
+ * so any grant that un-conceals a path is read-write for the granted
46
+ * session — the API therefore offers no read-only choice for these
47
+ * principals and every consent surface says "open and edit". */
48
+ export type ScopeGrant =
49
+ | { principal: "team"; capabilities: string[] }
50
+ | { principal: "user"; userId: string; capabilities: string[] }
51
+ | { principal: "session"; sessionId: string; conversationId: string; capabilities: string[] }
52
+ | {
53
+ principal: "project";
54
+ projectId: string;
55
+ projectName: string;
56
+ /** The project_objects row this grant hangs off — the handle the file's
57
+ * owner uses to ✕ a "via project" row from the SharePicker without
58
+ * being a project member (share implies unshare). Null only for
59
+ * transitional/legacy rows. */
60
+ projectObjectId: string | null;
61
+ capabilities: string[];
62
+ };
63
+
64
+ /** An artifact's share scope (documents and templates — one model).
65
+ * On wire payloads `null` = unscoped/grandfathered team tier. A scope row
66
+ * with no grants = private to its owner. Platform templates report a fixed
67
+ * synthetic `{ grants: [{ principal: 'team', capabilities: ['read','invoke'] }] }`. */
68
+ export interface ArtifactScope {
69
+ kind: "document" | "template";
70
+ ownerUserId: string | null;
71
+ /** Templates only — the owning conversation binding (a grant source:
72
+ * members of that conversation reach the template via their role). */
73
+ conversationId?: string | null;
74
+ grants: ScopeGrant[];
75
+ }
76
+
77
+ /** The call context stamped on a run at dispatch (ADR-0045 §3) — the
78
+ * anchor of run visibility. Both ids null = the grandfathered
79
+ * team-visible tier ("Team"); conversationId set = the channel/session
80
+ * the run was dispatched from; otherwise dispatchedByUserId is the
81
+ * private floor (the dispatcher, or a key's creator). */
82
+ export interface RunContext {
83
+ conversationId: string | null;
84
+ conversationTitle: string | null;
85
+ dispatchedByUserId: string | null;
86
+ }
87
+
88
+ /** Share-mutation body — ONE shape for both kinds. `grants` is a
89
+ * FULL-REPLACE of the scope's grant list (empty array = private to the
90
+ * owner). Capabilities are validated per kind server-side (`read|write`
91
+ * for documents; `read|write|invoke|see_runs` for templates; 400 on
92
+ * unknown). Mutating a scope requires owner or team admin. */
93
+ export interface SetScopeGrantsInput {
94
+ grants: ScopeGrant[];
95
+ }
96
+
97
+ export interface SetTemplateScopeInput extends SetScopeGrantsInput {
98
+ /** Bind (`uuid`) or unbind (`null`) the owning conversation; omit to
99
+ * leave the binding unchanged. Binding requires `owner` role in the
100
+ * target conversation. */
101
+ conversationId?: string | null;
102
+ }