antpath 0.9.2 → 0.10.7

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.
@@ -135,6 +135,55 @@ export declare const TRANSIENT_CONTENT_HASH_PATTERN: RegExp;
135
135
  export declare function isWorkspaceSkillRef(ref: SkillRef): ref is WorkspaceSkillRef;
136
136
  export declare function isProviderSkillRef(ref: SkillRef): ref is ProviderSkillRef;
137
137
  export declare function isTransientSkillRef(ref: SkillRef): ref is TransientSkillRef;
138
+ export type AgentsMdRef = WorkspaceAgentsMdRef | TransientAgentsMdRef;
139
+ export interface WorkspaceAgentsMdRef {
140
+ readonly kind: "workspace_agentsmd";
141
+ readonly id: string;
142
+ }
143
+ /**
144
+ * Inline-supplied AgentsMd content that arrives as the
145
+ * `agentsmd:<slot>` part of a multipart `submitRun` body. The BFF
146
+ * ingests the bytes into `workspace_files` (kind='agentsmd') at
147
+ * submission time and rewrites the ref to `WorkspaceAgentsMdRef`
148
+ * before the rest of the run-submission pipeline runs.
149
+ *
150
+ * `name` becomes the prefix of the auto-suffixed workspace name,
151
+ * mirroring the `Skill` per-run-artifact model. `contentHash` is
152
+ * the SDK's advisory `sha256:<hex>` for tamper detection.
153
+ */
154
+ export interface TransientAgentsMdRef {
155
+ readonly kind: "transient_agentsmd";
156
+ readonly slot: string;
157
+ readonly name: string;
158
+ readonly contentHash: string;
159
+ }
160
+ export declare function isWorkspaceAgentsMdRef(ref: AgentsMdRef): ref is WorkspaceAgentsMdRef;
161
+ export declare function isTransientAgentsMdRef(ref: AgentsMdRef): ref is TransientAgentsMdRef;
162
+ export type FileRef = WorkspaceFileRef | TransientFileRef;
163
+ export interface WorkspaceFileRef {
164
+ readonly kind: "workspace_file";
165
+ readonly id: string;
166
+ }
167
+ /**
168
+ * Inline-supplied File content that arrives as the `file:<slot>`
169
+ * part of a multipart `submitRun` body. Single file or a zipped
170
+ * folder. The BFF ingests and rewrites the ref to
171
+ * `WorkspaceFileRef` before run submission proceeds.
172
+ *
173
+ * `name` is the workspace-visible name prefix. `contentHash` is the
174
+ * SDK's advisory `sha256:<hex>`. `mountPath` is optional — when
175
+ * present it overrides the default `/antpath/files/<id>/<rel>` mount
176
+ * layout (e.g. user-chosen `/workspace/data`).
177
+ */
178
+ export interface TransientFileRef {
179
+ readonly kind: "transient_file";
180
+ readonly slot: string;
181
+ readonly name: string;
182
+ readonly contentHash: string;
183
+ readonly mountPath?: string;
184
+ }
185
+ export declare function isWorkspaceFileRef(ref: FileRef): ref is WorkspaceFileRef;
186
+ export declare function isTransientFileRef(ref: FileRef): ref is TransientFileRef;
138
187
  /**
139
188
  * Options accepted by `parseSkillRef`. The default (`allowTransient: true`)
140
189
  * is the BFF submission parser path. The Blueprint parser passes
@@ -201,14 +250,20 @@ export declare function validateSkillBundleEntry(input: {
201
250
  readonly mode?: number;
202
251
  }): SkillBundleEntry;
203
252
  /**
204
- * Validate a full manifest. Enforces:
253
+ * Validate a full **skill bundle** manifest. Enforces:
205
254
  * - entries is a non-empty array
206
- * - `SKILL.md` exists at the bundle root (Claude's auto-discovery key)
255
+ * - `SKILL.md` exists at the bundle root (this is what makes a
256
+ * bundle a skill rather than a plain workspace file)
207
257
  * - file count <= maxFiles
208
258
  * - total uncompressed size <= maxDecompressedBytes
209
259
  * - per-entry validation (see `validateSkillBundleEntry`)
210
260
  * - no duplicate paths
211
261
  *
262
+ * Per the May-2026 decision log in
263
+ * `references/agent-context-uploads.md`, **skill** means "Claude
264
+ * Skill" — bundles without `SKILL.md` are not skills and must go
265
+ * through the `AgentsMd` or `File` upload concepts instead.
266
+ *
212
267
  * Returns a canonical manifest with totals computed.
213
268
  */
214
269
  export declare function validateSkillBundleManifest(input: ReadonlyArray<{
@@ -216,6 +271,19 @@ export declare function validateSkillBundleManifest(input: ReadonlyArray<{
216
271
  readonly size: number;
217
272
  readonly mode?: number;
218
273
  }>): SkillBundleManifest;
274
+ /**
275
+ * Returns true when the manifest carries a `SKILL.md` entry at the
276
+ * bundle root. The presence of this file is Anthropic's
277
+ * skill-auto-discovery signal — bundles that have it are treated as
278
+ * Claude skills and mounted accordingly; bundles that don't are still
279
+ * usable agent context (AGENTS.md, settings files, folders of helper
280
+ * data) but the agent won't pick them up via the skills mechanism.
281
+ *
282
+ * The check is intentionally a separate, callable predicate (rather
283
+ * than baked into `validateSkillBundleManifest`) so the storage and
284
+ * the attach layers can remain independent.
285
+ */
286
+ export declare function hasSkillMdAtRoot(manifest: SkillBundleManifest): boolean;
219
287
  /**
220
288
  * The non-secret half of an MCP server declaration. This is what enters
221
289
  * the hashed submission, the run snapshot, and any audit log. `name`
@@ -105,6 +105,18 @@ export function isProviderSkillRef(ref) {
105
105
  export function isTransientSkillRef(ref) {
106
106
  return ref.kind === "transient";
107
107
  }
108
+ export function isWorkspaceAgentsMdRef(ref) {
109
+ return ref.kind === "workspace_agentsmd";
110
+ }
111
+ export function isTransientAgentsMdRef(ref) {
112
+ return ref.kind === "transient_agentsmd";
113
+ }
114
+ export function isWorkspaceFileRef(ref) {
115
+ return ref.kind === "workspace_file";
116
+ }
117
+ export function isTransientFileRef(ref) {
118
+ return ref.kind === "transient_file";
119
+ }
108
120
  /**
109
121
  * Parse a `SkillRef` from untrusted input. Used by the BFF run parser
110
122
  * and by the operations module when deserialising API responses. Throws
@@ -265,14 +277,20 @@ export function validateSkillBundleEntry(input) {
265
277
  return { path, size: input.size, mode };
266
278
  }
267
279
  /**
268
- * Validate a full manifest. Enforces:
280
+ * Validate a full **skill bundle** manifest. Enforces:
269
281
  * - entries is a non-empty array
270
- * - `SKILL.md` exists at the bundle root (Claude's auto-discovery key)
282
+ * - `SKILL.md` exists at the bundle root (this is what makes a
283
+ * bundle a skill rather than a plain workspace file)
271
284
  * - file count <= maxFiles
272
285
  * - total uncompressed size <= maxDecompressedBytes
273
286
  * - per-entry validation (see `validateSkillBundleEntry`)
274
287
  * - no duplicate paths
275
288
  *
289
+ * Per the May-2026 decision log in
290
+ * `references/agent-context-uploads.md`, **skill** means "Claude
291
+ * Skill" — bundles without `SKILL.md` are not skills and must go
292
+ * through the `AgentsMd` or `File` upload concepts instead.
293
+ *
276
294
  * Returns a canonical manifest with totals computed.
277
295
  */
278
296
  export function validateSkillBundleManifest(input) {
@@ -302,10 +320,27 @@ export function validateSkillBundleManifest(input) {
302
320
  entries.push(entry);
303
321
  }
304
322
  if (!hasSkillMd) {
305
- throw new SkillBundleValidationError("bundle manifest must contain a 'SKILL.md' entry at the bundle root");
323
+ throw new SkillBundleValidationError("skill bundle manifest must contain a 'SKILL.md' entry at the bundle root. " +
324
+ "If you want to upload an instructions file or generic agent context, use " +
325
+ "AgentsMd or File instead — see references/agent-context-uploads.md");
306
326
  }
307
327
  return { entries, totalSize, fileCount: entries.length };
308
328
  }
329
+ /**
330
+ * Returns true when the manifest carries a `SKILL.md` entry at the
331
+ * bundle root. The presence of this file is Anthropic's
332
+ * skill-auto-discovery signal — bundles that have it are treated as
333
+ * Claude skills and mounted accordingly; bundles that don't are still
334
+ * usable agent context (AGENTS.md, settings files, folders of helper
335
+ * data) but the agent won't pick them up via the skills mechanism.
336
+ *
337
+ * The check is intentionally a separate, callable predicate (rather
338
+ * than baked into `validateSkillBundleManifest`) so the storage and
339
+ * the attach layers can remain independent.
340
+ */
341
+ export function hasSkillMdAtRoot(manifest) {
342
+ return manifest.entries.some((entry) => entry.path === "SKILL.md");
343
+ }
309
344
  export const MCP_SERVER_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,62}$/;
310
345
  export function parseMcpServerRef(input, path) {
311
346
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
@@ -1,6 +1,6 @@
1
1
  import type { HttpClient } from "./http.js";
2
2
  import type { RunUnit } from "./run-unit.js";
3
- import type { Output, Run, RunEvent, SignedOutputLink, Skill, WhoAmI } from "./runtime-types.js";
3
+ import type { AgentsMdRecord, FileRecord, Output, Run, RunEvent, SignedOutputLink, Skill, WhoAmI } from "./runtime-types.js";
4
4
  import type { PlatformFlatRunSubmissionInput, PlatformRunSubmissionInput } from "./submission.js";
5
5
  /**
6
6
  * The single source of truth for SDK<->BFF transport. The SDK class
@@ -52,22 +52,32 @@ export declare function downloadRunArchive(http: HttpClient, runId: string): Pro
52
52
  export declare function submitRunFlat(http: HttpClient, request: PlatformFlatRunSubmissionInput): Promise<Run>;
53
53
  /**
54
54
  * Multipart variant of `submitRunFlat` for runs that carry transient
55
- * (per-run) skill bundles. The JSON submission travels as the
56
- * `submission` part; each `TransientSkillRef.slot` in
57
- * `request.submission.skills` MUST be mirrored by exactly one
58
- * `skill:<slot>` part with the bundle bytes.
55
+ * (per-run) skill bundles and/or transient AgentsMd content.
59
56
  *
60
- * The BFF re-canonicalises and re-hashes each bundle; a `contentHash`
61
- * mismatch between the JSON ref and the recomputed hash of the bytes
62
- * is rejected with a deterministic error.
57
+ * The JSON submission travels as the `submission` part; each
58
+ * `TransientSkillRef.slot` in `request.submission.skills` MUST be
59
+ * mirrored by exactly one `skill:<slot>` part with the bundle bytes.
60
+ * Each `TransientAgentsMdRef.slot` in `request.submission.agentsMd`
61
+ * MUST be mirrored by exactly one `agentsmd:<slot>` part with the
62
+ * markdown text.
63
63
  *
64
- * Bytes never persist on antpath storage; the dashboard BFF uploads
65
- * them straight to Anthropic Files for the lifetime of the run.
64
+ * The BFF re-canonicalises and re-hashes each bundle/file; a
65
+ * `contentHash` mismatch is rejected with a deterministic error.
66
+ *
67
+ * At least one of `bundles` or `agentsMdParts` must be non-empty.
66
68
  */
67
69
  export declare function submitRunFlatMultipart(http: HttpClient, request: PlatformFlatRunSubmissionInput, bundles: ReadonlyArray<{
68
70
  readonly slot: string;
69
71
  readonly bytes: Uint8Array;
70
72
  readonly filename: string;
73
+ }>, agentsMdParts?: ReadonlyArray<{
74
+ readonly slot: string;
75
+ readonly content: string;
76
+ readonly filename: string;
77
+ }>, fileParts?: ReadonlyArray<{
78
+ readonly slot: string;
79
+ readonly bytes: Uint8Array;
80
+ readonly filename: string;
71
81
  }>): Promise<Run>;
72
82
  /**
73
83
  * Upload a workspace skill bundle as a zip blob. The dashboard BFF runs
@@ -106,3 +116,68 @@ export declare function findSkillByHash(http: HttpClient, args: {
106
116
  * indexed by-hash route is reserved for `uploadIfChanged`.
107
117
  */
108
118
  export declare function findSkillByName(http: HttpClient, name: string): Promise<Skill | null>;
119
+ /**
120
+ * Upload a workspace AgentsMd file as a markdown string. The BFF
121
+ * canonicalises the content into a deterministic zip with AGENTS.md at
122
+ * root and runs the two-phase pending → ready upload.
123
+ */
124
+ export declare function createAgentsMd(http: HttpClient, args: {
125
+ readonly name: string;
126
+ readonly content: string;
127
+ }): Promise<AgentsMdRecord>;
128
+ export declare function listAgentsMd(http: HttpClient): Promise<readonly AgentsMdRecord[]>;
129
+ export declare function getAgentsMd(http: HttpClient, agentsMdId: string): Promise<AgentsMdRecord>;
130
+ export declare function deleteAgentsMd(http: HttpClient, agentsMdId: string): Promise<void>;
131
+ /**
132
+ * Upload a workspace File as a zip bundle. The BFF canonicalises the
133
+ * content and runs the two-phase pending → ready upload.
134
+ */
135
+ export declare function createFile(http: HttpClient, args: {
136
+ readonly name: string;
137
+ readonly bytes: Uint8Array;
138
+ }): Promise<FileRecord>;
139
+ export declare function listFiles(http: HttpClient): Promise<readonly FileRecord[]>;
140
+ export declare function getFile(http: HttpClient, fileId: string): Promise<FileRecord>;
141
+ export declare function deleteFile(http: HttpClient, fileId: string): Promise<void>;
142
+ /** Payload returned by the BFF's upload-init endpoint. */
143
+ export interface AssetUploadInitResult {
144
+ readonly assetId: string;
145
+ readonly storagePath: string;
146
+ readonly tusUrl: string;
147
+ readonly tusToken: string;
148
+ readonly expiresAt: string;
149
+ readonly uploadHeaders: Readonly<Record<string, string>>;
150
+ }
151
+ /**
152
+ * Initialise a chunked asset upload session. Calls the BFF's
153
+ * `POST /api/assets/upload-init` endpoint, which:
154
+ *
155
+ * 1. Inserts a `state='pending'` row in the appropriate table.
156
+ * 2. Returns a TUS URL + short-lived token the SDK will use to drive
157
+ * `tus-js-client` directly against Supabase Storage.
158
+ *
159
+ * The caller holds the `assetId` and `storagePath` for the subsequent
160
+ * finalize call.
161
+ */
162
+ export declare function initAssetUpload(http: HttpClient, input: {
163
+ readonly kind: "skill" | "file";
164
+ readonly name: string;
165
+ readonly sizeBytes: number;
166
+ readonly hash: string;
167
+ }): Promise<AssetUploadInitResult>;
168
+ /**
169
+ * Finalise a chunked asset upload session. Calls the BFF's
170
+ * `POST /api/assets/finalize` endpoint, which:
171
+ *
172
+ * 1. Downloads the assembled bytes from Supabase Storage.
173
+ * 2. Verifies `sha256(bytes) === hash`.
174
+ * 3. Transitions the row `pending → ready`.
175
+ *
176
+ * Throws if the server returns a non-OK response (e.g. `hash_mismatch`).
177
+ */
178
+ export declare function finalizeAssetUpload(http: HttpClient, input: {
179
+ readonly assetId: string;
180
+ readonly kind: "skill" | "file";
181
+ readonly hash: string;
182
+ readonly storagePath: string;
183
+ }): Promise<void>;
@@ -83,21 +83,26 @@ export async function submitRunFlat(http, request) {
83
83
  }
84
84
  /**
85
85
  * Multipart variant of `submitRunFlat` for runs that carry transient
86
- * (per-run) skill bundles. The JSON submission travels as the
87
- * `submission` part; each `TransientSkillRef.slot` in
88
- * `request.submission.skills` MUST be mirrored by exactly one
89
- * `skill:<slot>` part with the bundle bytes.
86
+ * (per-run) skill bundles and/or transient AgentsMd content.
90
87
  *
91
- * The BFF re-canonicalises and re-hashes each bundle; a `contentHash`
92
- * mismatch between the JSON ref and the recomputed hash of the bytes
93
- * is rejected with a deterministic error.
88
+ * The JSON submission travels as the `submission` part; each
89
+ * `TransientSkillRef.slot` in `request.submission.skills` MUST be
90
+ * mirrored by exactly one `skill:<slot>` part with the bundle bytes.
91
+ * Each `TransientAgentsMdRef.slot` in `request.submission.agentsMd`
92
+ * MUST be mirrored by exactly one `agentsmd:<slot>` part with the
93
+ * markdown text.
94
94
  *
95
- * Bytes never persist on antpath storage; the dashboard BFF uploads
96
- * them straight to Anthropic Files for the lifetime of the run.
95
+ * The BFF re-canonicalises and re-hashes each bundle/file; a
96
+ * `contentHash` mismatch is rejected with a deterministic error.
97
+ *
98
+ * At least one of `bundles` or `agentsMdParts` must be non-empty.
97
99
  */
98
- export async function submitRunFlatMultipart(http, request, bundles) {
99
- if (!Array.isArray(bundles) || bundles.length === 0) {
100
- throw new Error("submitRunFlatMultipart: bundles must be a non-empty array");
100
+ export async function submitRunFlatMultipart(http, request, bundles, agentsMdParts, fileParts) {
101
+ const hasBundles = Array.isArray(bundles) && bundles.length > 0;
102
+ const hasAgentsMd = Array.isArray(agentsMdParts) && agentsMdParts.length > 0;
103
+ const hasFiles = Array.isArray(fileParts) && fileParts.length > 0;
104
+ if (!hasBundles && !hasAgentsMd && !hasFiles) {
105
+ throw new Error("submitRunFlatMultipart: bundles, agentsMdParts, or fileParts must be non-empty");
101
106
  }
102
107
  const form = new FormData();
103
108
  // Submission rides as a typed JSON Blob so the BFF reads
@@ -116,6 +121,30 @@ export async function submitRunFlatMultipart(http, request, bundles) {
116
121
  const blob = toBlob(bundle.bytes, "application/zip");
117
122
  form.append(`skill:${bundle.slot}`, blob, bundle.filename);
118
123
  }
124
+ for (const part of agentsMdParts ?? []) {
125
+ if (typeof part.slot !== "string" || !part.slot) {
126
+ throw new Error("submitRunFlatMultipart: each agentsMd part must have a non-empty slot id");
127
+ }
128
+ const partKey = `agentsmd:${part.slot}`;
129
+ if (seen.has(partKey)) {
130
+ throw new Error(`submitRunFlatMultipart: duplicate agentsMd slot "${part.slot}"`);
131
+ }
132
+ seen.add(partKey);
133
+ const blob = new Blob([part.content], { type: "text/plain" });
134
+ form.append(partKey, blob, part.filename);
135
+ }
136
+ for (const part of fileParts ?? []) {
137
+ if (typeof part.slot !== "string" || !part.slot) {
138
+ throw new Error("submitRunFlatMultipart: each file part must have a non-empty slot id");
139
+ }
140
+ const partKey = `file:${part.slot}`;
141
+ if (seen.has(partKey)) {
142
+ throw new Error(`submitRunFlatMultipart: duplicate file slot "${part.slot}"`);
143
+ }
144
+ seen.add(partKey);
145
+ const blob = toBlob(part.bytes, "application/zip");
146
+ form.append(partKey, blob, part.filename);
147
+ }
119
148
  return http.request("/api/runs", {
120
149
  method: "POST",
121
150
  body: form
@@ -183,6 +212,80 @@ export async function findSkillByName(http, name) {
183
212
  const skills = await listSkills(http);
184
213
  return skills.find((skill) => skill.name === name) ?? null;
185
214
  }
215
+ // ===========================================================================
216
+ // AgentsMd (workspace_files kind='agentsmd') operations
217
+ // ===========================================================================
218
+ /**
219
+ * Upload a workspace AgentsMd file as a markdown string. The BFF
220
+ * canonicalises the content into a deterministic zip with AGENTS.md at
221
+ * root and runs the two-phase pending → ready upload.
222
+ */
223
+ export async function createAgentsMd(http, args) {
224
+ const form = new FormData();
225
+ form.append("name", args.name);
226
+ form.append("content", new Blob([args.content], { type: "text/plain" }), "AGENTS.md");
227
+ const result = await http.request("/api/agentsmd", { method: "POST", body: form });
228
+ return unwrapAgentsMd(result);
229
+ }
230
+ export async function listAgentsMd(http) {
231
+ const result = await http.request("/api/agentsmd");
232
+ if (Array.isArray(result)) {
233
+ return result;
234
+ }
235
+ return result.agentsMd;
236
+ }
237
+ export async function getAgentsMd(http, agentsMdId) {
238
+ const result = await http.request(`/api/agentsmd/${encodeURIComponent(agentsMdId)}`);
239
+ return unwrapAgentsMd(result);
240
+ }
241
+ export async function deleteAgentsMd(http, agentsMdId) {
242
+ await http.request(`/api/agentsmd/${encodeURIComponent(agentsMdId)}`, {
243
+ method: "DELETE"
244
+ });
245
+ }
246
+ function unwrapAgentsMd(result) {
247
+ if (result && typeof result === "object" && "agentsMd" in result) {
248
+ return result.agentsMd;
249
+ }
250
+ return result;
251
+ }
252
+ // ===========================================================================
253
+ // File (workspace_files kind='file') operations
254
+ // ===========================================================================
255
+ /**
256
+ * Upload a workspace File as a zip bundle. The BFF canonicalises the
257
+ * content and runs the two-phase pending → ready upload.
258
+ */
259
+ export async function createFile(http, args) {
260
+ const form = new FormData();
261
+ form.append("name", args.name);
262
+ const blob = toBlob(args.bytes, "application/zip");
263
+ form.append("bundle", blob, `${args.name}.zip`);
264
+ const result = await http.request("/api/files", { method: "POST", body: form });
265
+ return unwrapFile(result);
266
+ }
267
+ export async function listFiles(http) {
268
+ const result = await http.request("/api/files");
269
+ if (Array.isArray(result)) {
270
+ return result;
271
+ }
272
+ return result.files;
273
+ }
274
+ export async function getFile(http, fileId) {
275
+ const result = await http.request(`/api/files/${encodeURIComponent(fileId)}`);
276
+ return unwrapFile(result);
277
+ }
278
+ export async function deleteFile(http, fileId) {
279
+ await http.request(`/api/files/${encodeURIComponent(fileId)}`, {
280
+ method: "DELETE"
281
+ });
282
+ }
283
+ function unwrapFile(result) {
284
+ if (result && typeof result === "object" && "file" in result) {
285
+ return result.file;
286
+ }
287
+ return result;
288
+ }
186
289
  function unwrapSkill(result) {
187
290
  if (result && typeof result === "object" && "skill" in result) {
188
291
  return result.skill;
@@ -206,4 +309,37 @@ function toBlob(input, contentType) {
206
309
  function hasRun(value) {
207
310
  return Boolean(value && typeof value === "object" && "run" in value);
208
311
  }
312
+ /**
313
+ * Initialise a chunked asset upload session. Calls the BFF's
314
+ * `POST /api/assets/upload-init` endpoint, which:
315
+ *
316
+ * 1. Inserts a `state='pending'` row in the appropriate table.
317
+ * 2. Returns a TUS URL + short-lived token the SDK will use to drive
318
+ * `tus-js-client` directly against Supabase Storage.
319
+ *
320
+ * The caller holds the `assetId` and `storagePath` for the subsequent
321
+ * finalize call.
322
+ */
323
+ export async function initAssetUpload(http, input) {
324
+ return http.request("/api/assets/upload-init", {
325
+ method: "POST",
326
+ body: JSON.stringify(input)
327
+ });
328
+ }
329
+ /**
330
+ * Finalise a chunked asset upload session. Calls the BFF's
331
+ * `POST /api/assets/finalize` endpoint, which:
332
+ *
333
+ * 1. Downloads the assembled bytes from Supabase Storage.
334
+ * 2. Verifies `sha256(bytes) === hash`.
335
+ * 3. Transitions the row `pending → ready`.
336
+ *
337
+ * Throws if the server returns a non-OK response (e.g. `hash_mismatch`).
338
+ */
339
+ export async function finalizeAssetUpload(http, input) {
340
+ await http.request("/api/assets/finalize", {
341
+ method: "POST",
342
+ body: JSON.stringify(input)
343
+ });
344
+ }
209
345
  //# sourceMappingURL=operations.js.map
@@ -57,6 +57,8 @@ function parseFlatProjection(value) {
57
57
  ...(typeof submissionRaw.system === "string" ? { system: submissionRaw.system } : {}),
58
58
  prompt: toStringArray(submissionRaw.prompt),
59
59
  skills: toSkillRefArray(submissionRaw.skills),
60
+ agentsMd: [],
61
+ files: [],
60
62
  mcpServers: toMcpServerRefArray(submissionRaw.mcpServers),
61
63
  ...(parseEnvironment(submissionRaw.environment)
62
64
  ? { environment: parseEnvironment(submissionRaw.environment) }
@@ -101,6 +103,8 @@ function fallbackFlat() {
101
103
  model: "",
102
104
  prompt: [],
103
105
  skills: [],
106
+ agentsMd: [],
107
+ files: [],
104
108
  mcpServers: []
105
109
  }
106
110
  };
@@ -122,6 +122,53 @@ export interface Skill {
122
122
  readonly deletedAt?: string | null;
123
123
  readonly [key: string]: unknown;
124
124
  }
125
+ /**
126
+ * Wire-level record for a workspace AgentsMd file as returned by the BFF.
127
+ * Mirrors `PublicWorkspaceFile` from the dashboard service layer.
128
+ */
129
+ export interface AgentsMdRecord {
130
+ readonly id: string;
131
+ readonly kind?: "agentsmd";
132
+ readonly name: string;
133
+ readonly state: "pending" | "ready";
134
+ readonly hash?: string | null;
135
+ readonly sizeBytes?: number | null;
136
+ readonly fileCount?: number | null;
137
+ readonly manifest?: ReadonlyArray<{
138
+ readonly path: string;
139
+ readonly size: number;
140
+ readonly mode: number;
141
+ }>;
142
+ readonly createdAt?: string;
143
+ readonly updatedAt?: string;
144
+ readonly finalizedAt?: string | null;
145
+ readonly deletedAt?: string | null;
146
+ readonly [key: string]: unknown;
147
+ }
148
+ /**
149
+ * Wire-level record for a workspace File as returned by the BFF.
150
+ * Mirrors `PublicWorkspaceFile` from the dashboard service layer
151
+ * with kind='file' and `f_*` ids.
152
+ */
153
+ export interface FileRecord {
154
+ readonly id: string;
155
+ readonly kind?: "file";
156
+ readonly name: string;
157
+ readonly state: "pending" | "ready";
158
+ readonly hash?: string | null;
159
+ readonly sizeBytes?: number | null;
160
+ readonly fileCount?: number | null;
161
+ readonly manifest?: ReadonlyArray<{
162
+ readonly path: string;
163
+ readonly size: number;
164
+ readonly mode: number;
165
+ }>;
166
+ readonly createdAt?: string;
167
+ readonly updatedAt?: string;
168
+ readonly finalizedAt?: string | null;
169
+ readonly deletedAt?: string | null;
170
+ readonly [key: string]: unknown;
171
+ }
125
172
  /**
126
173
  * Full submission as the SDK and CLI assemble it before posting. The
127
174
  * `template` is the SDK-level ResolvedTemplate (or a JSON-encoded one);
@@ -1,5 +1,5 @@
1
1
  import { type ProxyAuthShape, type ProxyMethod, type ProxyResponseMode } from "./proxy-protocol.js";
2
- import type { McpServerRef, SkillRef } from "./blueprint.js";
2
+ import type { AgentsMdRef, FileRef, McpServerRef, SkillRef } from "./blueprint.js";
3
3
  export type JsonPrimitive = string | number | boolean | null;
4
4
  export type JsonValue = JsonPrimitive | JsonValue[] | {
5
5
  readonly [key: string]: JsonValue;
@@ -172,6 +172,8 @@ export interface PlatformFlatSubmission {
172
172
  readonly system?: string;
173
173
  readonly prompt: readonly string[];
174
174
  readonly skills: readonly SkillRef[];
175
+ readonly agentsMd: readonly AgentsMdRef[];
176
+ readonly files: readonly FileRef[];
175
177
  readonly mcpServers: readonly McpServerRef[];
176
178
  readonly environment?: PlatformTemplateEnvironment;
177
179
  readonly metadata?: Record<string, JsonValue>;