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