@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,336 @@
1
+ /**
2
+ * Factory-facing wire types for `AgentComposeClient` — template
3
+ * registration, factories, drive files, schedules, secrets, API keys,
4
+ * and usage.
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 { SnapshotConfig, IOSchema, ConnectorRequirements, ConnectorOperationTag, InvokePolicy, SandboxResources, DriveMergePolicy } from "./workflow-metadata.js";
11
+ import type { WorkflowPlan } from "./workflow-plan.js";
12
+ import type { WorkflowManifest } from "../utils/bundler.js";
13
+ import type { ArtifactScope } from "./api-scopes.js";
14
+
15
+ export interface RegisterResult {
16
+ id: string;
17
+ name: string;
18
+ version: string;
19
+ runtimes?: RegisteredRuntime[];
20
+ }
21
+
22
+ export interface RegisteredRuntime {
23
+ id: string;
24
+ name: string;
25
+ version: string;
26
+ }
27
+
28
+ export interface RuntimeSourceInput {
29
+ name: string;
30
+ source: string;
31
+ }
32
+
33
+ /** GitHub provenance for a registered template's source file — stored as
34
+ * `metadata.source` on the registration. `cloud-build` stamps the built
35
+ * commit's sha; the dashboard's manual link path writes `sha: "manual"`. */
36
+ export interface TemplateSourceRef {
37
+ owner: string;
38
+ repo: string;
39
+ branch: string;
40
+ /** Repo-relative file path, e.g. `.agentc/workflows/workflow-deploy.ts`. */
41
+ path: string;
42
+ /** Commit sha the version was built from, or `"manual"` for hand-links. */
43
+ sha: string;
44
+ }
45
+
46
+ export interface RegisterWorkflowInput {
47
+ name: string;
48
+ source: string;
49
+ /** Structured attestation produced by `bundleWorkflow`. The server
50
+ * requires this on every registration; it proves the source was
51
+ * bundled by a `defineWorkflow`-aware toolchain. The server validates
52
+ * the manifest's shape and verifies `manifest.sourceHash` matches
53
+ * sha256(source) — the source bytes themselves are never parsed or
54
+ * executed on the server. */
55
+ manifest: WorkflowManifest;
56
+ version?: string;
57
+ /** Where the source file lives on GitHub — stored as `metadata.source`.
58
+ * Named `sourceRef` because `source` is the bundled code itself. */
59
+ sourceRef?: TemplateSourceRef;
60
+ schedule?: string;
61
+ runtimes?: RuntimeSourceInput[];
62
+ /** Human-readable description declared via
63
+ * `defineWorkflow({ description })`. Stored in template metadata and
64
+ * surfaced on the dashboard template card. */
65
+ description?: string;
66
+ networkPolicy?: unknown;
67
+ placeholders?: Record<string, string>;
68
+ /** All snapshot config — `bootFrom` (where to restore at run start),
69
+ * `save`, `retain`. See `WorkflowMetadata.snapshots`. */
70
+ snapshots?: SnapshotConfig;
71
+ /** Sandbox machine resources — size + provider (template defaults).
72
+ * See `WorkflowMetadata.resources`. */
73
+ resources?: SandboxResources;
74
+ /** Run-branch merge policy declared via `defineWorkflow({ mergePolicy })`.
75
+ * Omitted ⇒ `"auto"` on the server (today's behaviour) — see
76
+ * `WorkflowMetadata.mergePolicy`. */
77
+ mergePolicy?: DriveMergePolicy;
78
+ /** Provider-neutral execution plan detected by the CLI bundler. */
79
+ workflowPlan?: WorkflowPlan;
80
+ /** Connector requirements declared via `defineWorkflow({ connectors })`
81
+ * (ADR-0007). Validated against the server's provider registry at
82
+ * registration; tokens are injected at the network layer at dispatch. */
83
+ connectors?: ConnectorRequirements;
84
+ /** Connector-catalogue operation tag — see `ConnectorOperationTag`. */
85
+ connectorOperation?: ConnectorOperationTag;
86
+ /** Tier-1 invoke ACL declared via `defineWorkflow({ invokePolicy })`.
87
+ * Only meaningful when the workflow also declares `connectors` — the
88
+ * server gates dispatch on it before binding any grant. */
89
+ invokePolicy?: InvokePolicy;
90
+ /** Input schema extracted from the workflow's `input` zod schema. */
91
+ inputSchema?: IOSchema;
92
+ /** Output schema extracted from the workflow's `output` zod schema. */
93
+ outputSchema?: IOSchema;
94
+ /** Set by `defineSandboxEnvironment` — marks an environment build so the
95
+ * server skips the /factory mount for its runs (#13). See
96
+ * `WorkflowMetadata.environmentBuild`. */
97
+ environmentBuild?: boolean;
98
+ /** Factory slug. Defaults to `"default"`. */
99
+ factorySlug?: string;
100
+ }
101
+
102
+ export interface TemplateRow {
103
+ name: string;
104
+ version: string;
105
+ factorySlug: string;
106
+ /** Share scope (ADR-0045) — `null` = unscoped/grandfathered team tier. */
107
+ scope: ArtifactScope | null;
108
+ }
109
+
110
+ /** Template detail (`GET /factories/:slug/templates/:name`) — the typed
111
+ * subset the SDK pins; the route returns additional registration fields
112
+ * (contentHash, metadata timestamps) that flow through untyped. */
113
+ export interface TemplateDetail {
114
+ id: string;
115
+ name: string;
116
+ version: string;
117
+ factorySlug: string;
118
+ metadata: Record<string, unknown>;
119
+ /** `factory` = registered in this factory; `published` = platform
120
+ * template (fixed team-wide read+invoke, never write). */
121
+ origin: "factory" | "published";
122
+ /** Share scope (ADR-0045) — `null` = unscoped/grandfathered team tier. */
123
+ scope: ArtifactScope | null;
124
+ }
125
+
126
+ export interface ListTemplatesOptions {
127
+ factorySlug?: string;
128
+ }
129
+
130
+ // ── Factory-file search (wire shape mirrors routes/factory-files.ts) ────────
131
+
132
+ /** Public "anyone with the link" state — the additive `public` field on file
133
+ * rows (list/ls/search). The token is the whole capability, so an enabled
134
+ * row carries it ONLY for viewers holding the document's share authority
135
+ * (scope owner / internal); everyone else — read-only grantees, session
136
+ * toolbelt keys — gets the token-less badge. The PUT /files/public-link
137
+ * response (share-gated) always carries it. Files/docs only — sessions
138
+ * never go public (ADR-0052). */
139
+ export type PublicFileLinkState = { enabled: true; token?: string } | { enabled: false };
140
+
141
+ export interface FactoryFileSearchRow {
142
+ id: string;
143
+ path: string;
144
+ sizeBytes: number;
145
+ contentType: string | null;
146
+ contentHash: string;
147
+ deletedAt: string | null;
148
+ createdAt: string;
149
+ updatedAt: string;
150
+ /** Opening slice (≤320 chars) of the extracted text; null for binary. */
151
+ preview: string | null;
152
+ /** Share scope (ADR-0045) — `null` = unscoped/team tier. Optional: file
153
+ * list payloads gain it as the server's document surfaces land. */
154
+ scope?: ArtifactScope | null;
155
+ /** Public link state — additive beside `scope` (a link exists on scoped
156
+ * and unscoped files alike). Absent on payloads that predate the field. */
157
+ public?: PublicFileLinkState;
158
+ }
159
+
160
+ export interface SearchFactoryFilesOptions {
161
+ factorySlug?: string;
162
+ limit?: number;
163
+ /** Path cursor from a prior page's `next_cursor`. */
164
+ cursor?: string;
165
+ }
166
+
167
+ /** One DIRECTORY hit on `/files/search` — a distinct dir prefix (any depth)
168
+ * whose leaf segment matches the query, derived server-side from paths the
169
+ * viewer can see. Mirrors the `/files/ls` folders shape. */
170
+ export interface FactoryFolderSearchRow {
171
+ name: string;
172
+ path: string;
173
+ file_count: number;
174
+ total_size: number;
175
+ last_updated: string;
176
+ }
177
+
178
+ export interface FactoryFileSearchResult {
179
+ object: "list";
180
+ data: FactoryFileSearchRow[];
181
+ has_more: boolean;
182
+ next_cursor: string | null;
183
+ /** Directory hits (first page only — a `cursor` call pages FILES and
184
+ * answers `[]`). Optional: absent on payloads that predate the field. */
185
+ folders?: FactoryFolderSearchRow[];
186
+ /** True when more directories matched than the server's folder bound. */
187
+ folders_truncated?: boolean;
188
+ }
189
+
190
+ export interface FactoryFileWriteResult {
191
+ path: string;
192
+ contentHash: string;
193
+ sizeBytes: number;
194
+ created: boolean;
195
+ }
196
+
197
+ /** A factory: a project-level grouping of workflows inside a team. */
198
+ export interface FactoryRow {
199
+ id: string;
200
+ teamId: string;
201
+ slug: string;
202
+ name: string;
203
+ description: string | null;
204
+ createdAt: string;
205
+ updatedAt: string;
206
+ }
207
+
208
+ export interface CreateFactoryInput {
209
+ slug: string;
210
+ name: string;
211
+ description?: string;
212
+ }
213
+
214
+ export interface UpdateFactoryInput {
215
+ name?: string;
216
+ description?: string;
217
+ }
218
+
219
+ export interface ScheduleRow {
220
+ id: string;
221
+ name: string;
222
+ workflowName: string;
223
+ cron: string;
224
+ createdAt: string;
225
+ updatedAt: string;
226
+ nextFireAt: string | null;
227
+ lastFireAt: string | null;
228
+ }
229
+
230
+ export interface CreateScheduleInput {
231
+ /** Human-friendly schedule name. Unique within the factory. */
232
+ name: string;
233
+ /** The workflow this schedule should fire. Must already be registered
234
+ * in the same factory. */
235
+ workflow: string;
236
+ /** Cron expression (UTC). */
237
+ cron: string;
238
+ /** Factory to attach the schedule to. Defaults to `"default"`. */
239
+ factorySlug?: string;
240
+ }
241
+
242
+ export interface SecretOptions {
243
+ factorySlug?: string;
244
+ }
245
+
246
+ export interface SetSecretResult {
247
+ key: string;
248
+ }
249
+
250
+ export interface SecretListEntry {
251
+ key: string;
252
+ createdAt: string;
253
+ updatedAt: string;
254
+ }
255
+
256
+ export interface CreateApiKeyInput {
257
+ name?: string;
258
+ scopes?: string[];
259
+ expiresAt?: string;
260
+ factorySlug?: string;
261
+ }
262
+
263
+ /** Row shape returned by `GET /api-keys`. */
264
+ export interface ApiKey {
265
+ object: "api_key";
266
+ id: string;
267
+ name: string | null;
268
+ last4: string | null;
269
+ scopes: string[];
270
+ teamId: string;
271
+ createdByUserId: string | null;
272
+ /** Non-null when the key is restricted to a single factory. */
273
+ factoryId: string | null;
274
+ createdAt: string;
275
+ expiresAt: string | null;
276
+ lastUsedAt: string | null;
277
+ revokedAt: string | null;
278
+ }
279
+
280
+ /** Response from `POST /api-keys`. The `key` field is the plaintext token —
281
+ * shown once at creation, never retrievable again. */
282
+ export interface ApiKeyCreated extends ApiKey { key: string }
283
+
284
+ /** Single rollup row from `GET /api/v1/usage`. */
285
+ export interface UsageRollupRow {
286
+ eventType: string;
287
+ unit: string;
288
+ total: number;
289
+ tags: Record<string, unknown>;
290
+ }
291
+
292
+ /** Response from `GET /api/v1/usage`. */
293
+ export interface UsageResponse {
294
+ object: "list";
295
+ data: UsageRollupRow[];
296
+ has_more: boolean;
297
+ from: string | null;
298
+ to: string | null;
299
+ }
300
+
301
+ // ── GitHub-linked drive directories (ADR-0030 P1) ───────────────────────────
302
+
303
+ /** One drive-directory ⇄ GitHub-repo link (`/factories/:slug/repo-links`).
304
+ * The webhook secret ref is operator plumbing and never on the wire. */
305
+ export interface DriveRepoLink {
306
+ id: string;
307
+ factoryId: string;
308
+ /** Linked directory prefix under the drive root (relative, no slashes
309
+ * at either end). Unique per factory; overlaps are rejected. */
310
+ dirPrefix: string;
311
+ provider: string;
312
+ /** "org/repo". */
313
+ repoFullName: string;
314
+ /** The GitHub branch drive `main` syncs with. */
315
+ trackedBranch: string;
316
+ connectorGrantId: string | null;
317
+ /** v1 links are always 'write' (the round trip is the feature). */
318
+ access: "read" | "write";
319
+ lastSyncedGitSha: string | null;
320
+ lastSyncedAcgCommit: string | null;
321
+ syncState: "idle" | "syncing" | "diverged" | "reauth_required";
322
+ visibility: "team" | "restricted";
323
+ createdBy: string | null;
324
+ lastSyncedAt: string | null;
325
+ createdAt: string;
326
+ }
327
+
328
+ /** Input for `POST /factories/:slug/repo-links`. Requires the drive to be
329
+ * graph-authoritative (ADR-0058 Phase 4 promoted) — 409 otherwise. */
330
+ export interface CreateDriveRepoLinkInput {
331
+ dirPrefix: string;
332
+ repoFullName: string;
333
+ trackedBranch: string;
334
+ connectorGrantId: string;
335
+ visibility?: "team" | "restricted";
336
+ }
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Projects wire types (ADR-0045 projects extension).
3
+ *
4
+ * A project is a member-gated group (roles `owner > write > read`, mirroring
5
+ * conversation rosters) that also holds a collection of objects — factory
6
+ * files, conversations, and sessions (kind='session' conversations). Membership ⊆
7
+ * visibility: every project member sees every project object. Access is
8
+ * DERIVED (grant rows keyed `principal='project'`), never promoted into a
9
+ * personal scope — it exists only while `(member ∈ project) ∧ (object ∈
10
+ * project)`.
11
+ *
12
+ * Wire shapes are pinned tri-party: the server routes, this SDK, and the
13
+ * dashboard's own thin client update together. The dashboard NEVER imports
14
+ * the SDK — it mirrors these shapes over its own fetch wrapper.
15
+ */
16
+
17
+ /** Project role ladder — `owner > write > read`. `read` sees the project and
18
+ * every object in it; `write` additionally administers (rename, invite as
19
+ * write/read, add/remove objects); `owner` additionally re-roles members and
20
+ * deletes the project. Roles gate ADMINISTRATION only — never visibility. */
21
+ export type ProjectRole = "owner" | "write" | "read";
22
+
23
+ /** One project, as the caller sees it. `role` is the caller's own role;
24
+ * `createdBy` is provenance/display only (there is NO implicit creator
25
+ * authority — authority is the member row exclusively). */
26
+ export interface Project {
27
+ id: string;
28
+ name: string;
29
+ createdBy: string | null;
30
+ createdAt: string;
31
+ updatedAt: string;
32
+ role: ProjectRole;
33
+ memberCount: number;
34
+ objectCount: number;
35
+ }
36
+
37
+ /** A page of projects, newest-activity first. Cursor-paginated: pass the
38
+ * previous page's `next_cursor` (null when exhausted). */
39
+ export interface ProjectsPage {
40
+ projects: Project[];
41
+ next_cursor: string | null;
42
+ }
43
+
44
+ /** One human member of a project (roster row), with display identity merged
45
+ * in server-side. */
46
+ export interface ProjectMember {
47
+ userId: string;
48
+ role: ProjectRole;
49
+ name: string | null;
50
+ email: string | null;
51
+ addedBy: string | null;
52
+ createdAt: string;
53
+ }
54
+
55
+ /** One object referenced by a project — a LIVE link (grant row), never a
56
+ * copy/snapshot. Files are id-keyed (renames ride along); conversations and
57
+ * sessions are both keyed by `conversationId` (sessions ARE conversations
58
+ * with `kind='session'`). */
59
+ export type ProjectObject =
60
+ | {
61
+ id: string;
62
+ type: "file";
63
+ fileId: string;
64
+ path: string;
65
+ factorySlug: string;
66
+ /** True once the file carries an artifact scope; unscoped files are
67
+ * ref-only (grandfathered team-visible) until scoped. */
68
+ scoped: boolean;
69
+ addedBy: string | null;
70
+ /** Non-null when this file row was MATERIALIZED as part of a session
71
+ * add (it points at the session object row); null = directly added. */
72
+ addedViaObjectId: string | null;
73
+ createdAt: string;
74
+ }
75
+ | {
76
+ id: string;
77
+ type: "conversation" | "session";
78
+ conversationId: string;
79
+ title: string | null;
80
+ kind: "chat" | "session";
81
+ executor: "local" | "cloud" | null;
82
+ /** Resolved session model (per-session override, else the hosting
83
+ * agent's default) — lets clients render a provider mark from the
84
+ * object row itself. Null for chat conversations. */
85
+ model: string | null;
86
+ addedBy: string | null;
87
+ createdAt: string;
88
+ };
89
+
90
+ /** A page of project objects. Cursor-paginated (created_at DESC, id ASC). */
91
+ export interface ProjectObjectsPage {
92
+ objects: ProjectObject[];
93
+ next_cursor: string | null;
94
+ }
95
+
96
+ /** One file the caller could NOT contribute to a project when adding a
97
+ * session — only files the caller OWNS are materialized. `path` is present
98
+ * only when visible to the caller; paths concealed from the caller are
99
+ * silently omitted (never disclosed, not even counted). */
100
+ export interface ProjectSkippedFile {
101
+ path: string;
102
+ reason: "not_owner";
103
+ }
104
+
105
+ /** One file that WOULD be materialized (shared into the project) by adding a
106
+ * session. */
107
+ export interface ProjectPreviewFile {
108
+ fileId: string;
109
+ path: string;
110
+ factorySlug: string;
111
+ }
112
+
113
+ /** The dry-run result of a session add — powers the consent dialog's
114
+ * expandable file list + skipped line. No mutation, no audit, no push. */
115
+ export interface ProjectAddPreview {
116
+ files: ProjectPreviewFile[];
117
+ skipped: ProjectSkippedFile[];
118
+ }
119
+
120
+ /** Body for adding one object to a project. Conversations/sessions carry a
121
+ * `conversationId`; files carry a drive `path` (+ optional factory). The
122
+ * server derives the true object type from `conversations.kind` and rejects
123
+ * a mismatched declared `type` (400 `object_kind_mismatch`). */
124
+ export type AddProjectObjectInput =
125
+ | { type: "conversation" | "session"; conversationId: string }
126
+ | { type: "file"; path: string; factorySlug?: string };
127
+
128
+ /** Result of adding an object. A session add returns the session object plus
129
+ * the file objects materialized from the caller's owned scopes, and reports
130
+ * any owned-but-skipped entries. */
131
+ export interface AddProjectObjectResult {
132
+ objects: ProjectObject[];
133
+ skipped?: ProjectSkippedFile[];
134
+ }
135
+
136
+ /** Result of re-materializing a session object's file context (add-only). */
137
+ export interface RefreshProjectObjectResult {
138
+ objects: ProjectObject[];
139
+ skipped: ProjectSkippedFile[];
140
+ }