@agent-compose/sdk 0.7.0 → 0.8.1

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 (119) 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 +32 -1
  5. package/dist/agent/run-agent.d.ts +4 -0
  6. package/dist/client.d.ts +382 -534
  7. package/dist/directives.d.ts +112 -0
  8. package/dist/display.d.ts +258 -0
  9. package/dist/errors.d.ts +24 -1
  10. package/dist/index.d.ts +26 -14
  11. package/dist/index.js +3774 -1679
  12. package/dist/pause/wrappers.d.ts +31 -9
  13. package/dist/runtimes/_acp-client.d.ts +46 -1
  14. package/dist/runtimes/_cli-agent.d.ts +51 -4
  15. package/dist/runtimes/_jsonl-guard.d.ts +103 -0
  16. package/dist/runtimes/amp.d.ts +2 -2
  17. package/dist/runtimes/claude-code.d.ts +61 -0
  18. package/dist/runtimes/claude-code.test.d.ts +14 -0
  19. package/dist/runtimes/claude.d.ts +16 -0
  20. package/dist/runtimes/claude.test.d.ts +8 -0
  21. package/dist/runtimes/codex.d.ts +12 -3
  22. package/dist/runtimes/cursor.d.ts +2 -2
  23. package/dist/runtimes/droid.d.ts +2 -2
  24. package/dist/runtimes/jsonl-guard.test.d.ts +19 -0
  25. package/dist/runtimes/openai-desktop.js +3718 -1680
  26. package/dist/runtimes/opencode.d.ts +2 -2
  27. package/dist/runtimes/vercel.js +12 -1
  28. package/dist/sandbox/devbox.d.ts +42 -0
  29. package/dist/sandbox/exec-stream.d.ts +14 -0
  30. package/dist/sandbox/network-policy.d.ts +100 -0
  31. package/dist/sandbox/provider-def.d.ts +79 -0
  32. package/dist/sandbox/providers/desktop.d.ts +10 -0
  33. package/dist/sandbox/providers/e2b.d.ts +17 -0
  34. package/dist/sandbox/providers/local.d.ts +11 -0
  35. package/dist/sandbox/providers/vercel.d.ts +18 -0
  36. package/dist/sandbox/registry.d.ts +45 -0
  37. package/dist/sandbox/sizes.d.ts +68 -0
  38. package/dist/sandbox.d.ts +24 -299
  39. package/dist/step-invocation/__tests__/foreground-recovery.test.d.ts +1 -0
  40. package/dist/step-invocation/invoker.d.ts +10 -0
  41. package/dist/step-invocation/protocol.d.ts +5 -0
  42. package/dist/types/api-compliance.d.ts +71 -0
  43. package/dist/types/api-conversations.d.ts +523 -0
  44. package/dist/types/api-factory.d.ts +334 -0
  45. package/dist/types/api-projects.d.ts +131 -0
  46. package/dist/types/api-runs.d.ts +422 -0
  47. package/dist/types/api-scopes.d.ts +102 -0
  48. package/dist/types/conversation-stream.d.ts +191 -0
  49. package/dist/types/execution-context.d.ts +12 -2
  50. package/dist/types/protocol.d.ts +38 -1
  51. package/dist/types/sandbox-environment.d.ts +8 -5
  52. package/dist/types/sandbox.d.ts +74 -4
  53. package/dist/types/workflow-metadata.d.ts +41 -8
  54. package/dist/types/workflow-plan.d.ts +10 -0
  55. package/dist/types/workflow.d.ts +18 -205
  56. package/dist/utils/bundler.d.ts +68 -1
  57. package/dist/workflow-steps/index.d.ts +1 -1
  58. package/dist/workflow-steps/observability.d.ts +8 -1
  59. package/dist/workflow-steps/runner.d.ts +3 -3
  60. package/dist/workflow-steps/step.d.ts +15 -1
  61. package/dist/workflow-steps/types.d.ts +19 -5
  62. package/dist/workflow-steps/workflow.d.ts +29 -1
  63. package/dist/workflows/engine.d.ts +3 -2
  64. package/dist/workflows/invoke-child.d.ts +20 -2
  65. package/dist/workflows/invoke-child.test.d.ts +9 -0
  66. package/package.json +2 -2
  67. package/src/agent/agent-context.ts +186 -3
  68. package/src/agent/agent-loop.ts +40 -2
  69. package/src/agent/run-agent.ts +5 -0
  70. package/src/client.ts +1048 -625
  71. package/src/directives.ts +184 -0
  72. package/src/display.ts +834 -0
  73. package/src/errors.ts +39 -0
  74. package/src/index.ts +114 -12
  75. package/src/pause/wrappers.ts +44 -9
  76. package/src/runtimes/_acp-client.ts +72 -3
  77. package/src/runtimes/_cli-agent.ts +161 -36
  78. package/src/runtimes/_jsonl-guard.ts +219 -0
  79. package/src/runtimes/claude-code.ts +256 -0
  80. package/src/runtimes/claude.ts +32 -2
  81. package/src/runtimes/codex.ts +63 -3
  82. package/src/runtimes/openai-desktop.ts +59 -14
  83. package/src/sandbox/devbox.ts +48 -0
  84. package/src/sandbox/exec-stream.ts +48 -0
  85. package/src/sandbox/network-policy.ts +181 -0
  86. package/src/sandbox/provider-def.ts +94 -0
  87. package/src/sandbox/providers/desktop.ts +57 -0
  88. package/src/sandbox/providers/e2b.ts +354 -0
  89. package/src/sandbox/providers/local.ts +106 -0
  90. package/src/sandbox/providers/vercel.ts +331 -0
  91. package/src/sandbox/registry.ts +198 -0
  92. package/src/sandbox/sizes.ts +95 -0
  93. package/src/sandbox.ts +59 -1275
  94. package/src/step-invocation/invoker.ts +151 -28
  95. package/src/step-invocation/protocol.ts +8 -0
  96. package/src/types/api-compliance.ts +79 -0
  97. package/src/types/api-conversations.ts +547 -0
  98. package/src/types/api-factory.ts +368 -0
  99. package/src/types/api-projects.ts +140 -0
  100. package/src/types/api-runs.ts +459 -0
  101. package/src/types/api-scopes.ts +102 -0
  102. package/src/types/conversation-stream.ts +231 -0
  103. package/src/types/execution-context.ts +10 -2
  104. package/src/types/protocol.ts +41 -0
  105. package/src/types/sandbox-environment.ts +28 -9
  106. package/src/types/sandbox.ts +73 -4
  107. package/src/types/workflow-metadata.ts +44 -8
  108. package/src/types/workflow-plan.ts +11 -0
  109. package/src/types/workflow.ts +25 -292
  110. package/src/utils/bundler.ts +245 -8
  111. package/src/utils/errors.ts +16 -1
  112. package/src/workflow-steps/index.ts +1 -0
  113. package/src/workflow-steps/observability.ts +19 -8
  114. package/src/workflow-steps/runner.ts +4 -4
  115. package/src/workflow-steps/step.ts +49 -1
  116. package/src/workflow-steps/types.ts +20 -5
  117. package/src/workflow-steps/workflow.ts +29 -1
  118. package/src/workflows/engine.ts +3 -2
  119. package/src/workflows/invoke-child.ts +49 -13
@@ -0,0 +1,459 @@
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
+ import type { BundledWorkflow } from "../utils/bundler.js";
14
+
15
+ export type RunState = "running" | "success" | "failed" | "abandoned" | "canceled";
16
+
17
+ /** INLINE invoke payload (`POST /factories/:slug/invoke`): everything
18
+ * `bundleWorkflow` produced — source, the REQUIRED manifest binding the
19
+ * bytes, the workflow plan, and the build fields — plus the name the run
20
+ * reports as its workflow. The server runs it through the same
21
+ * validate/build core as registration but writes NO registry row: the run
22
+ * snapshots the validated source (auditable, replayable) and the name
23
+ * stays free for real registrations. */
24
+ export type InlineWorkflowPayload = BundledWorkflow & { name: string };
25
+
26
+ export interface InvokeWorkflowOptions {
27
+ /** Per-invocation snapshot config override. `snapshots.bootFrom`
28
+ * replaces the template's boot source; `snapshots.saveLatest` and
29
+ * `snapshots.retainSteps` override capture mode. Anything omitted
30
+ * falls back to the template's registered default. */
31
+ snapshots?: SnapshotConfig;
32
+ /** Per-invocation network policy override. Replaces the template-level
33
+ * policy for this run only — registered metadata is not mutated. */
34
+ networkPolicy?: SandboxNetworkPolicy;
35
+ /** Per-invocation placeholder override. Maps secret names referenced in
36
+ * `networkPolicy` ($VAR) to the values the runner should see for env
37
+ * vars after brokering. Replaces the template-level placeholders for
38
+ * this run only — registered metadata is not mutated. */
39
+ placeholders?: Record<string, string>;
40
+ /** Per-invocation machine-size override of the template's `resources.size`.
41
+ * `small` (default) | `medium` | `large`; omit → the template default,
42
+ * else `small`. Honoured on Vercel (→ vCPUs); E2B ignores it. */
43
+ size?: SandboxSize;
44
+ /** Explicit parent run id. Pass `null` to suppress ambient RUN_ID auto-detection. */
45
+ parentRunId?: string | null;
46
+ /** Agent loop inside the parent run that caused this invoke, when applicable. */
47
+ agentId?: string | null;
48
+ /** Factory slug. Defaults to `"default"`. */
49
+ factorySlug?: string;
50
+ /** Idempotency key — sent as the `Idempotency-Key` header. A repeat invoke
51
+ * with the same key inside the server's dedup window returns the original
52
+ * run instead of starting a new one (matches `resumePause`'s pattern). */
53
+ idempotencyKey?: string;
54
+ /** Who pays for this run's model calls:
55
+ *
56
+ * - `"default"` (Auto) — the initiating human's connected subscription
57
+ * when one is enabled for workflows, else platform credits;
58
+ * - `"platform"` — always platform credits (metered);
59
+ * - `"subscription"` — REQUIRE the initiating human's plan. If it
60
+ * cannot be honored the invoke FAILS (412) rather than quietly
61
+ * spending credits;
62
+ * - `"byok"` — a factory secret named by `fundingSecret`, injected as
63
+ * the runtime's raw provider key. Never metered.
64
+ *
65
+ * Omitted → the workflow's own default (its `settings.funding`), else
66
+ * Auto. */
67
+ funding?: FundingChoice;
68
+ /** `funding: "byok"` only — the FACTORY SECRET NAME whose value funds the
69
+ * run. Must be a provider key variable (ANTHROPIC_API_KEY,
70
+ * OPENAI_API_KEY, CODEX_API_KEY, OPENROUTER_API_KEY) — that is where the
71
+ * sandbox's runtimes read it. The name only; the value never leaves the
72
+ * server's secret store. */
73
+ fundingSecret?: string;
74
+ }
75
+
76
+ /** Inference-funding choice for a run — a lane the caller PINS, or
77
+ * `"default"` (Auto, the automatic ladder). Mirrors the same vocabulary
78
+ * cloud sessions use. */
79
+ export type FundingChoice = "default" | "platform" | "subscription" | "byok";
80
+
81
+ export interface InvokeAndWaitOptions extends InvokeWorkflowOptions {
82
+ timeoutMs?: number;
83
+ pollIntervalMs?: number;
84
+ }
85
+
86
+ /** Options for `invokeInline` — the named-invoke options plus the run-title
87
+ * override (an inline run has no registered template to inherit one from). */
88
+ export interface InvokeInlineOptions extends InvokeWorkflowOptions {
89
+ /** Run title override — defaults to the workflow name. */
90
+ title?: string;
91
+ }
92
+
93
+ export interface InvokeInlineAndWaitOptions extends InvokeInlineOptions {
94
+ timeoutMs?: number;
95
+ pollIntervalMs?: number;
96
+ }
97
+
98
+ export interface InvokeResult {
99
+ id: string;
100
+ }
101
+
102
+ export interface StreamRunLogsOptions {
103
+ lastEventId?: number;
104
+ signal?: AbortSignal;
105
+ }
106
+
107
+ export interface RunStatus<TOutput = unknown> {
108
+ id: string;
109
+ status: RunState;
110
+ output?: TOutput;
111
+ /** The run's latest (`saveLatest`) snapshot id, populated once the run has
112
+ * succeeded — the boot source to fork this run's evolved filesystem from
113
+ * (pass as `snapshots.bootFrom` on a follow-up invoke). `null` while the run
114
+ * is still in flight or when it captured no snapshot. Lets an orchestrator
115
+ * fork a child straight off the `invokeChild` result without a separate
116
+ * `listRunSnapshots` call. */
117
+ latestSnapshotId?: string | null;
118
+ }
119
+
120
+ /** ADR-0006 step 10 — actor record returned on a successful resume.
121
+ * Shape mirrors the server's `PauseResumeActor` type after the row
122
+ * has been stamped. Audit FKs (`userId` / `keyId` / `runId`) may be
123
+ * null when the referenced row was deleted between resume and the
124
+ * response render — the immutable `label` survives. */
125
+ export interface ResumePauseActor {
126
+ kind: "session_user" | "api_key" | "agent";
127
+ /** Better Auth user id when kind='session_user'. */
128
+ userId?: string | null;
129
+ /** api_keys.id when kind='api_key'. */
130
+ keyId?: string | null;
131
+ /** Caller-run id when kind='agent' (NOT the run being resumed). */
132
+ runId?: string | null;
133
+ /** Agent-instance within `runId` when kind='agent'. */
134
+ agentId?: string | null;
135
+ label: string;
136
+ }
137
+
138
+ /** Success branch of the resume HTTP response. The pause has reached
139
+ * a terminal state — `resolved` (workflow signal arrived), `expired`
140
+ * (TTL fired first), or `cancelled` (workflow terminated mid-pause).
141
+ * Only `resolved` carries the resume payload the user supplied. */
142
+ export interface ResumePauseSuccess {
143
+ status: "resolved" | "expired" | "cancelled";
144
+ pauseId: string;
145
+ resolvedAt: string | null;
146
+ resumePayload: unknown;
147
+ actor: ResumePauseActor | null;
148
+ }
149
+
150
+ /** Pending branch — the workflow accepted the signal but the row
151
+ * flip didn't observe within the route's 5s wait window. The
152
+ * operation is in-flight; retry with the same `Idempotency-Key`
153
+ * and the cache collapses the duplicate to a single canonical
154
+ * response. */
155
+ export interface ResumePausePending {
156
+ status: "pending";
157
+ pauseId: string;
158
+ timedOut: true;
159
+ }
160
+
161
+ export type ResumePauseResponse = ResumePauseSuccess | ResumePausePending;
162
+
163
+ export interface ResumePauseOptions {
164
+ /** Stripe-style retry-dedup key — same syntax as the workflow-invoke
165
+ * route: 1..255 chars of `[A-Za-z0-9_\-:.]`, no embedded CR/LF.
166
+ * Sent as the `Idempotency-Key` request header. (The server reads the
167
+ * header first, falling back to a body field for callers behind a
168
+ * header-stripping proxy; this client only sends the header.) */
169
+ idempotencyKey?: string;
170
+ /** Abort the HTTP request mid-wait (e.g. from a UI cancel button).
171
+ * The server's LISTEN tears down via the request's AbortSignal. */
172
+ signal?: AbortSignal;
173
+ }
174
+
175
+ export interface RequestAgentPauseOptions {
176
+ /** Human-readable note surfaced to the agent as the pause reason. */
177
+ reason?: string;
178
+ /** Your handle for answering this pause without the minted pauseId:
179
+ * pass the same value to `resumePauseByKey`. */
180
+ correlationKey?: string;
181
+ /** Abort the HTTP request. */
182
+ signal?: AbortSignal;
183
+ }
184
+
185
+ export interface AnswerSteerOptions extends ResumePauseOptions {
186
+ /** Who answered — surfaced to the agent as `[human steer from <actor>]`. */
187
+ actor?: string;
188
+ }
189
+
190
+ /** 202 envelope from a steer-pause request. The request is best-effort and
191
+ * fire-and-forget: it publishes a transient control message and returns
192
+ * immediately — the agent parks at its next iteration boundary (if it is
193
+ * `mode: "hitl"` and still running). Answer it via `answerSteerByKey`
194
+ * (pass the `correlationKey` you set here) or `answerSteer` (by pauseId). */
195
+ export interface RequestAgentPauseResponse {
196
+ status: "steer_requested";
197
+ runId: string;
198
+ agentId: string;
199
+ }
200
+
201
+ export interface SendAgentMessageOptions {
202
+ /** Transcript attribution. For non-session callers (API key, orchestrator)
203
+ * this names the sender; defaults to the caller's identity server-side. */
204
+ senderName?: string;
205
+ /** Abort the HTTP request. */
206
+ signal?: AbortSignal;
207
+ }
208
+
209
+ /** 202 envelope from a message-to-running-agent request. The message is queued
210
+ * durably and delivered mid-stream as the agent's next user turn — the workflow
211
+ * is NOT paused. `seq` is the message's per-run ordinal. */
212
+ export interface SendAgentMessageResponse {
213
+ status: "message_enqueued";
214
+ runId: string;
215
+ agentId: string;
216
+ seq: number;
217
+ }
218
+
219
+ export interface RunDetail<TOutput = unknown> {
220
+ runId: string;
221
+ title: string;
222
+ metadata: Record<string, unknown>;
223
+ outcome: string;
224
+ startedAt: string;
225
+ endedAt: string | null;
226
+ durationMs: number | null;
227
+ failureReason: string | null;
228
+ input: unknown;
229
+ output: TOutput | null;
230
+ /** Call context (ADR-0045 §3) — both ids null = team-visible ("Team");
231
+ * UI labels private runs "Only you" / "#channel-name". */
232
+ context: RunContext;
233
+ lifecycleEvents: Array<{ at: string; type: string; payload: unknown }>;
234
+ children?: RunDetail[];
235
+ }
236
+
237
+ /** The funding-lane vocabulary: 'platform' (gateway-metered), 'byok'
238
+ * (author's own key), 'subscription' (the initiating user's connected
239
+ * plan). */
240
+ export type FundingLane = "platform" | "byok" | "subscription";
241
+
242
+ /** One per-(step, credential) funding-lane stamp (ADR-0048), recorded at
243
+ * credential resolution — `GET /workflows/:id/funding`. Attribution only:
244
+ * non-platform lanes are the user's own money and are never metered. */
245
+ export interface RunFundingStamp {
246
+ stepIndex: number;
247
+ /** Env-var name (or auth-file path) the sandbox read the credential from. */
248
+ envVar: string;
249
+ /** Provider family — 'anthropic' | 'openai' | 'openrouter' | … */
250
+ provider: string;
251
+ lane: FundingLane;
252
+ /** Platform lane only — the gateway virtual key's alias. */
253
+ keyAlias: string | null;
254
+ }
255
+
256
+ /** One (provider, model) usage group of the run's gateway-attested platform
257
+ * cut — the ONLY usage the ledger records. */
258
+ export interface RunFundingUsageRow {
259
+ provider: string;
260
+ model: string;
261
+ promptTokens: number;
262
+ completionTokens: number;
263
+ cacheReadTokens: number;
264
+ cacheCreationTokens: number;
265
+ calls: number;
266
+ }
267
+
268
+ /** `GET /workflows/:id/funding` — the run's funding-lane surface: per-step
269
+ * lane stamps (recorded at resolution, never re-detected) and the run's
270
+ * gateway-attested platform dollars. Empty `stamps` = the run predates
271
+ * lane stamping. */
272
+ export interface RunFundingResponse {
273
+ object: "run.funding";
274
+ runId: string;
275
+ stamps: RunFundingStamp[];
276
+ stampsTruncated: boolean;
277
+ attested: {
278
+ totalUsd: number;
279
+ rows: Array<RunFundingUsageRow & { costUsd: number }>;
280
+ truncated: boolean;
281
+ };
282
+ }
283
+
284
+ /** One row from the factory runs list (`GET /factories/:slug/runs`) — the
285
+ * summary shape, a strict subset of what the route returns. */
286
+ export interface RunListEntry {
287
+ runId: string;
288
+ title: string;
289
+ /** System-stamped bag; `_workflow` names the registered workflow. */
290
+ metadata: Record<string, unknown>;
291
+ outcome: string;
292
+ paused: boolean;
293
+ startedAt: string;
294
+ endedAt: string | null;
295
+ durationMs: number | null;
296
+ failureReason: string | null;
297
+ /** Call context (ADR-0045 §3) — both ids null = team-visible ("Team"). */
298
+ context: RunContext;
299
+ }
300
+
301
+ export interface ListRunsOptions {
302
+ /** Factory the runs live in. Defaults to "default". */
303
+ factorySlug?: string;
304
+ /** Substring match on the registered workflow name (`metadata._workflow`). */
305
+ workflow?: string;
306
+ /** Substring match across title / task title / branch / run id. */
307
+ search?: string;
308
+ outcome?: string;
309
+ sort?: "newest" | "oldest" | "fastest" | "slowest";
310
+ limit?: number;
311
+ }
312
+
313
+ export interface TimelineEvent {
314
+ kind: string;
315
+ at: string;
316
+ seq: number;
317
+ type: string;
318
+ payload: Record<string, unknown>;
319
+ }
320
+
321
+ export type EventSubjectType = "run" | "agent" | "workflow" | "factory";
322
+
323
+ export interface EventRow {
324
+ id: string;
325
+ teamId: string;
326
+ subjectType: EventSubjectType | string;
327
+ subjectId: string;
328
+ runId: string | null;
329
+ agentId: string | null;
330
+ workflowId: string | null;
331
+ factoryId: string | null;
332
+ name: string;
333
+ body: unknown;
334
+ summary: string | null;
335
+ confidence: string | null;
336
+ timestamp: string;
337
+ attributes: Record<string, unknown>;
338
+ propagate: boolean;
339
+ idempotencyKey: string | null;
340
+ createdAt: string;
341
+ }
342
+
343
+ // The server emits these rows in snake_case; the client maps them to
344
+ // camelCase at the fetch boundary so the SDK surface stays uniform
345
+ // (`EventRow.createdAt`, `RunStatus.latestSnapshotId`, …).
346
+ export interface RunArtifactRow {
347
+ path: string;
348
+ factorySlug: string | null;
349
+ sizeBytes: number | null;
350
+ lastWriteAt: string;
351
+ /** Opening text of the file (≤320 chars) — null for binary/empty. */
352
+ preview: string | null;
353
+ }
354
+
355
+ export interface ReportEventInput {
356
+ name: string;
357
+ body: unknown;
358
+ summary?: string;
359
+ confidence?: number;
360
+ timestamp?: string | Date;
361
+ attributes?: Record<string, unknown>;
362
+ propagate?: boolean;
363
+ idempotencyKey?: string;
364
+ }
365
+
366
+ export interface ListEventsOptions {
367
+ factorySlug?: string;
368
+ limit?: number;
369
+ /** Case-insensitive substring match. Server uses `ILIKE %name%`, so
370
+ * `"site"` matches `site.created`, `site.failed`, etc. Pass the
371
+ * full event name for an effectively-exact filter (any string is a
372
+ * substring of itself). */
373
+ name?: string;
374
+ /** Date-range lower bound: only include events at or after this
375
+ * timestamp. Used by the dashboard's range toggle (1h / 24h / 7d
376
+ * / 30d). Same semantics as `from` on the runs list endpoint. */
377
+ from?: string;
378
+ /** Timestamp cursor for "load older" pagination. Pass the
379
+ * `timestamp` of the last row from the previous page; the server
380
+ * returns rows strictly older than that. Distinct from `from`:
381
+ * `from` filters a date range, `before` walks the page boundary.
382
+ * Both can be supplied together for a paginated range-query. */
383
+ before?: string;
384
+ }
385
+
386
+ export interface ListEventsResult {
387
+ events: EventRow[];
388
+ has_more: boolean;
389
+ }
390
+
391
+ /** One captured stdout or stderr line from a run's sandbox subprocess.
392
+ * `id` is per-run monotonically increasing — pass the highest `id`
393
+ * you've seen as `afterId` to paginate forward. */
394
+ export interface RunLogLine {
395
+ id: number;
396
+ at: string;
397
+ stream: "stdout" | "stderr";
398
+ line: string;
399
+ }
400
+
401
+ export interface ListRunLogsOptions {
402
+ /** Return only lines with `id > afterId` (forward pagination). */
403
+ afterId?: number;
404
+ /** Max lines (server clamps to [1, 1000], defaults to 200). */
405
+ limit?: number;
406
+ /** Stream direction. `"asc"` (default) returns the oldest lines first
407
+ * — use with `afterId` to paginate forward. `"desc"` returns the newest
408
+ * lines first — use to fetch the last N lines of a finished run. */
409
+ direction?: "asc" | "desc";
410
+ }
411
+
412
+ /** Response from `POST /api/v1/workflows/:id/cancel`. The endpoint is
413
+ * idempotent: cancelling a run that's already terminal returns its current
414
+ * outcome verbatim (rather than throwing or pretending it just canceled),
415
+ * so `status` widens to every terminal value the server might surface. */
416
+ export interface CancelRunResponse {
417
+ runId: string;
418
+ status: "canceled" | "success" | "failed" | "abandoned";
419
+ canceledAt: string;
420
+ }
421
+
422
+ export interface ListSnapshotsOptions {
423
+ /** Factory slug. Defaults to `"default"`. */
424
+ factorySlug?: string;
425
+ workflow?: string;
426
+ limit?: number;
427
+ /** Cursor returned as `next_cursor` from `listSnapshotsPage`. */
428
+ before?: string;
429
+ }
430
+
431
+ export interface SnapshotListEntry {
432
+ snapshotId: string;
433
+ kind: "latest" | "step";
434
+ stepIndex: number | null;
435
+ runId: string;
436
+ workflow: string | null;
437
+ version: string | null;
438
+ createdAt: string | null;
439
+ /** Provider-reported on-disk size, or null when unavailable. */
440
+ sizeBytes: number | null;
441
+ }
442
+
443
+ export interface SnapshotListResponse {
444
+ object: "list";
445
+ data: SnapshotListEntry[];
446
+ has_more: boolean;
447
+ next_cursor: string | null;
448
+ }
449
+
450
+ export interface RunSnapshotEntry {
451
+ snapshotId: string;
452
+ /** `"latest"` = current/last pointer on the run.
453
+ * `"step"` = retained per-step snapshot. */
454
+ kind: "latest" | "step";
455
+ stepIndex: number | null;
456
+ createdAt: string | null;
457
+ /** Provider-reported on-disk size, or null when unavailable. */
458
+ sizeBytes: number | null;
459
+ }
@@ -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
+ }