antpath 0.10.15 → 0.11.4

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 (75) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +16 -8
  3. package/dist/_shared/blueprint.d.ts +93 -108
  4. package/dist/_shared/blueprint.js +144 -78
  5. package/dist/_shared/cleanup-policy.d.ts +2 -2
  6. package/dist/_shared/cleanup-policy.js +2 -5
  7. package/dist/_shared/http.d.ts +2 -2
  8. package/dist/_shared/index.d.ts +5 -1
  9. package/dist/_shared/index.js +5 -1
  10. package/dist/_shared/mcp-proxy-url.d.ts +55 -0
  11. package/dist/_shared/mcp-proxy-url.js +65 -0
  12. package/dist/_shared/operations.d.ts +7 -8
  13. package/dist/_shared/operations.js +14 -20
  14. package/dist/_shared/provider-proxy-url.d.ts +64 -0
  15. package/dist/_shared/provider-proxy-url.js +73 -0
  16. package/dist/_shared/proxy-validation.d.ts +1 -1
  17. package/dist/_shared/proxy-validation.js +2 -2
  18. package/dist/_shared/run-unit.d.ts +23 -36
  19. package/dist/_shared/run-unit.js +30 -46
  20. package/dist/_shared/runner-event.d.ts +120 -0
  21. package/dist/_shared/runner-event.js +193 -0
  22. package/dist/_shared/runner-job.d.ts +159 -0
  23. package/dist/_shared/runner-job.js +54 -0
  24. package/dist/_shared/runtime-manifest.d.ts +191 -0
  25. package/dist/_shared/runtime-manifest.js +221 -0
  26. package/dist/_shared/runtime-types.d.ts +7 -16
  27. package/dist/_shared/stable.d.ts +15 -10
  28. package/dist/_shared/stable.js +15 -10
  29. package/dist/_shared/submission.d.ts +221 -73
  30. package/dist/_shared/submission.js +442 -212
  31. package/dist/_shared/telemetry.d.ts +2 -2
  32. package/dist/_shared/telemetry.js +2 -2
  33. package/dist/_shared/template/index.d.ts +0 -1
  34. package/dist/_shared/template/index.js +0 -1
  35. package/dist/agents-md.d.ts +25 -67
  36. package/dist/agents-md.js +35 -121
  37. package/dist/agents-md.js.map +1 -1
  38. package/dist/asset-upload.d.ts +34 -0
  39. package/dist/asset-upload.js +34 -0
  40. package/dist/asset-upload.js.map +1 -1
  41. package/dist/blueprint.d.ts +3 -3
  42. package/dist/bundle.d.ts +2 -2
  43. package/dist/bundle.js +1 -1
  44. package/dist/cli.mjs +191 -100
  45. package/dist/cli.mjs.sha256 +1 -1
  46. package/dist/client.d.ts +56 -19
  47. package/dist/client.js +147 -125
  48. package/dist/client.js.map +1 -1
  49. package/dist/file.d.ts +28 -94
  50. package/dist/file.js +35 -175
  51. package/dist/file.js.map +1 -1
  52. package/dist/index.d.ts +5 -5
  53. package/dist/index.js +4 -0
  54. package/dist/index.js.map +1 -1
  55. package/dist/mcp-server.d.ts +10 -2
  56. package/dist/mcp-server.js +17 -2
  57. package/dist/mcp-server.js.map +1 -1
  58. package/dist/skill.d.ts +44 -214
  59. package/dist/skill.js +50 -284
  60. package/dist/skill.js.map +1 -1
  61. package/dist/version.d.ts +1 -1
  62. package/dist/version.js +1 -1
  63. package/dist/version.js.map +1 -1
  64. package/docs/cleanup.md +1 -1
  65. package/docs/credentials.md +2 -2
  66. package/docs/events.md +8 -8
  67. package/docs/outputs.md +2 -0
  68. package/docs/quickstart.md +18 -2
  69. package/docs/skills.md +1 -3
  70. package/docs/templates.md +6 -5
  71. package/package.json +3 -2
  72. package/dist/_shared/secrets.d.ts +0 -7
  73. package/dist/_shared/secrets.js +0 -20
  74. package/dist/_shared/template/mapper.d.ts +0 -11
  75. package/dist/_shared/template/mapper.js +0 -70
package/dist/cli.mjs CHANGED
@@ -58,8 +58,6 @@ var TERMINAL_RUN_STATUSES = [
58
58
  var terminalRunStatuses = new Set(TERMINAL_RUN_STATUSES);
59
59
 
60
60
  // ../shared/dist/blueprint.js
61
- var SKILL_ID_PATTERN = /^skl_[A-Za-z0-9_-]{8,128}$/;
62
- var SKILL_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,127}$/;
63
61
  var SKILL_BUNDLE_LIMITS = {
64
62
  /** Compressed (.zip) ceiling. */
65
63
  maxCompressedBytes: 10 * 1024 * 1024,
@@ -76,26 +74,14 @@ var SKILL_BUNDLE_LIMITS = {
76
74
  /** Stored directory mode. */
77
75
  defaultDirMode: 493
78
76
  };
79
- var TRANSIENT_SLOT_PATTERN = /^[a-z][a-z0-9_-]{0,63}$/;
80
- var TRANSIENT_CONTENT_HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;
81
- function parseSkillRef(input, path, options = {}) {
77
+ var INLINE_CONTENT_HASH_PATTERN = /^sha256:[0-9a-f]{64}$/;
78
+ var R2_ASSET_PATH_PATTERN = /^assets\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\/[0-9a-f]{64}$/;
79
+ function parseSkillRef(input, path) {
82
80
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
83
81
  throw new Error(`${path} must be a SkillRef object`);
84
82
  }
85
83
  const record = input;
86
84
  const kind = record.kind;
87
- if (kind === "workspace") {
88
- for (const key of Object.keys(record)) {
89
- if (key !== "kind" && key !== "id") {
90
- throw new Error(`${path} contains unexpected field for workspace SkillRef: ${key}`);
91
- }
92
- }
93
- const id = record.id;
94
- if (typeof id !== "string" || !SKILL_ID_PATTERN.test(id)) {
95
- throw new Error(`${path}.id must match ${SKILL_ID_PATTERN.source}`);
96
- }
97
- return { kind: "workspace", id };
98
- }
99
85
  if (kind === "provider") {
100
86
  for (const key of Object.keys(record)) {
101
87
  if (key !== "kind" && key !== "vendor" && key !== "skillId" && key !== "version") {
@@ -121,30 +107,50 @@ function parseSkillRef(input, path, options = {}) {
121
107
  ...version !== void 0 ? { version } : {}
122
108
  };
123
109
  }
124
- if (kind === "transient") {
125
- if (options.allowTransient === false) {
126
- throw new Error(`${path} carries a transient SkillRef, which cannot round-trip through JSON \u2014 transient skills must be supplied at submitRun time with their bytes attached`);
127
- }
128
- for (const key of Object.keys(record)) {
129
- if (key !== "kind" && key !== "slot" && key !== "name" && key !== "contentHash") {
130
- throw new Error(`${path} contains unexpected field for transient SkillRef: ${key}`);
131
- }
132
- }
133
- const slot = record.slot;
134
- if (typeof slot !== "string" || !TRANSIENT_SLOT_PATTERN.test(slot)) {
135
- throw new Error(`${path}.slot must match ${TRANSIENT_SLOT_PATTERN.source}`);
136
- }
137
- const name = record.name;
138
- if (typeof name !== "string" || !SKILL_NAME_PATTERN.test(name)) {
139
- throw new Error(`${path}.name must match ${SKILL_NAME_PATTERN.source}`);
140
- }
141
- const contentHash = record.contentHash;
142
- if (typeof contentHash !== "string" || !TRANSIENT_CONTENT_HASH_PATTERN.test(contentHash)) {
143
- throw new Error(`${path}.contentHash must match ${TRANSIENT_CONTENT_HASH_PATTERN.source}`);
110
+ if (kind === "r2") {
111
+ return parseR2RefFields(record, path);
112
+ }
113
+ throw new Error(`${path}.kind must be 'provider' or 'r2'`);
114
+ }
115
+ function parseR2RefFields(record, path) {
116
+ for (const key of Object.keys(record)) {
117
+ if (key !== "kind" && key !== "path" && key !== "hash" && key !== "sizeBytes" && key !== "name" && key !== "mountPath") {
118
+ throw new Error(`${path} contains unexpected field for r2 ref: ${key}`);
144
119
  }
145
- return { kind: "transient", slot, name, contentHash };
146
120
  }
147
- throw new Error(`${path}.kind must be 'workspace', 'provider', or 'transient'`);
121
+ const r2Path = record.path;
122
+ if (typeof r2Path !== "string" || !R2_ASSET_PATH_PATTERN.test(r2Path)) {
123
+ throw new Error(`${path}.path must match ${R2_ASSET_PATH_PATTERN.source}`);
124
+ }
125
+ const hash = record.hash;
126
+ if (typeof hash !== "string" || !INLINE_CONTENT_HASH_PATTERN.test(hash)) {
127
+ throw new Error(`${path}.hash must match ${INLINE_CONTENT_HASH_PATTERN.source}`);
128
+ }
129
+ const pathHash = r2Path.slice(r2Path.length - 64);
130
+ const hashHex = hash.slice("sha256:".length);
131
+ if (pathHash !== hashHex) {
132
+ throw new Error(`${path}.path hash segment does not match ${path}.hash`);
133
+ }
134
+ const sizeBytes = record.sizeBytes;
135
+ if (typeof sizeBytes !== "number" || !Number.isInteger(sizeBytes) || sizeBytes <= 0) {
136
+ throw new Error(`${path}.sizeBytes must be a positive integer`);
137
+ }
138
+ const name = record.name;
139
+ if (typeof name !== "string" || name.length === 0 || name.length > 128) {
140
+ throw new Error(`${path}.name must be a non-empty string (<= 128 chars)`);
141
+ }
142
+ const mountPath = record.mountPath;
143
+ if (mountPath !== void 0 && (typeof mountPath !== "string" || mountPath.length === 0)) {
144
+ throw new Error(`${path}.mountPath, when provided, must be a non-empty string`);
145
+ }
146
+ return {
147
+ kind: "r2",
148
+ path: r2Path,
149
+ hash,
150
+ sizeBytes,
151
+ name,
152
+ ...mountPath !== void 0 ? { mountPath } : {}
153
+ };
148
154
  }
149
155
  var SkillBundleValidationError = class extends Error {
150
156
  constructor(message) {
@@ -205,15 +211,19 @@ function validateSkillBundleEntry(input) {
205
211
  }
206
212
  return { path, size: input.size, mode };
207
213
  }
214
+ var REMOTE_MCP_TRANSPORTS = ["http", "sse"];
215
+ var REMOTE_MCP_STDIO_REJECTED_MESSAGE = "stdio MCP servers are not supported by Antpath. Antpath supports remote MCP servers over HTTP/SSE only.";
216
+ var STDIO_ONLY_FIELDS = ["command", "args", "env"];
208
217
  var MCP_SERVER_NAME_PATTERN = /^[a-z][a-z0-9_-]{0,62}$/;
209
218
  function parseMcpServerRef(input, path) {
210
219
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
211
220
  throw new Error(`${path} must be an object`);
212
221
  }
213
222
  const record = input;
223
+ rejectStdioMcpShape(record);
214
224
  for (const key of Object.keys(record)) {
215
- if (key !== "name" && key !== "url") {
216
- throw new Error(`${path}.${key} is not an allowed field for McpServerRef; permitted: name, url`);
225
+ if (key !== "name" && key !== "url" && key !== "transport") {
226
+ throw new Error(`${path}.${key} is not an allowed field for McpServerRef; permitted: name, url, transport`);
217
227
  }
218
228
  }
219
229
  const name = record.name;
@@ -238,19 +248,42 @@ function parseMcpServerRef(input, path) {
238
248
  }
239
249
  throw new Error(`${path}.url is not a valid URL: ${url}`);
240
250
  }
241
- return { name, url };
251
+ const transport = parseRemoteMcpTransport(record.transport, `${path}.transport`);
252
+ return transport ? { name, url, transport } : { name, url };
253
+ }
254
+ function rejectStdioMcpShape(record) {
255
+ if (record.transport === "stdio") {
256
+ throw new Error(REMOTE_MCP_STDIO_REJECTED_MESSAGE);
257
+ }
258
+ for (const field of STDIO_ONLY_FIELDS) {
259
+ if (record[field] !== void 0) {
260
+ throw new Error(REMOTE_MCP_STDIO_REJECTED_MESSAGE);
261
+ }
262
+ }
263
+ }
264
+ function parseRemoteMcpTransport(input, field) {
265
+ if (input === void 0) {
266
+ return void 0;
267
+ }
268
+ if (typeof input !== "string" || !REMOTE_MCP_TRANSPORTS.includes(input)) {
269
+ throw new Error(`${field} must be one of: ${REMOTE_MCP_TRANSPORTS.join(", ")} (got ${JSON.stringify(input)})`);
270
+ }
271
+ return input;
242
272
  }
243
273
  function parseBlueprintMcpServerRef(input, path) {
244
274
  if (input === null || typeof input !== "object" || Array.isArray(input)) {
245
275
  throw new Error(`${path} must be an object`);
246
276
  }
247
277
  const record = input;
278
+ rejectStdioMcpShape(record);
248
279
  for (const key of Object.keys(record)) {
249
- if (key !== "name" && key !== "url" && key !== "headers") {
250
- throw new Error(`${path}.${key} is not an allowed field for BlueprintMcpServer; permitted: name, url, headers`);
280
+ if (key !== "name" && key !== "url" && key !== "headers" && key !== "transport") {
281
+ throw new Error(`${path}.${key} is not an allowed field for BlueprintMcpServer; permitted: name, url, transport, headers`);
251
282
  }
252
283
  }
253
284
  const stripped = { name: record.name, url: record.url };
285
+ if (record.transport !== void 0)
286
+ stripped.transport = record.transport;
254
287
  const ref = parseMcpServerRef(stripped, path);
255
288
  const rawHeaders = record.headers;
256
289
  if (rawHeaders === void 0) {
@@ -307,7 +340,7 @@ function parseBlueprint(input) {
307
340
  ...skills !== void 0 ? { skills } : {},
308
341
  ...mcpServers !== void 0 ? { mcpServers } : {},
309
342
  // environment / cleanup / proxyEndpoints / metadata: passed through
310
- // as-is — the BFF revalidates them via `parseFlatRunSubmissionRequest`,
343
+ // as-is — the BFF revalidates them via `parseRunSubmissionRequest`,
311
344
  // so duplicating the heavyweight parsers here would mean two sources
312
345
  // of truth. The CLI surfaces structural errors at submission time.
313
346
  ...record.environment !== void 0 ? { environment: record.environment } : {},
@@ -346,7 +379,7 @@ function parseBlueprintSkills(value) {
346
379
  if (!Array.isArray(value)) {
347
380
  throw new Error("Blueprint.skills must be an array");
348
381
  }
349
- return value.map((item, index) => parseSkillRef(item, `Blueprint.skills[${index}]`, { allowTransient: false }));
382
+ return value.map((item, index) => parseSkillRef(item, `Blueprint.skills[${index}]`));
350
383
  }
351
384
  function parseBlueprintMcpServers(value) {
352
385
  if (value === void 0) {
@@ -367,6 +400,15 @@ function parseBlueprintMcpServers(value) {
367
400
  }
368
401
 
369
402
  // ../shared/dist/submission.js
403
+ var RUN_PROVIDERS = [
404
+ "anthropic",
405
+ "deepseek",
406
+ "openai",
407
+ "gemini",
408
+ "mistral"
409
+ ];
410
+ var DEFAULT_RUN_PROVIDER = "anthropic";
411
+ var RUNTIME_KINDS = ["native", "managed"];
370
412
  var PROXY_ENDPOINT_DEFAULTS = {
371
413
  allowHeaders: [],
372
414
  responseMode: "headers_only",
@@ -377,9 +419,22 @@ var PROXY_ENDPOINT_DEFAULTS = {
377
419
  responseByteBudget: 1024 * 1024
378
420
  };
379
421
 
422
+ // ../shared/dist/runtime-manifest.js
423
+ var ANTHROPIC_PATHS = Object.freeze({
424
+ skillsRoot: "/workspace/skills",
425
+ filesRoot: "/mnt/session/uploads/antpath/files",
426
+ assetsRoot: "/mnt/session/uploads/antpath/assets",
427
+ outputsRoot: "/mnt/session/outputs",
428
+ antpathCli: "/mnt/session/uploads/antpath/antpath",
429
+ indexJson: "/mnt/session/uploads/antpath/index.json",
430
+ readme: "/mnt/session/uploads/antpath/SKILLS.md",
431
+ runtimeJson: "/mnt/session/uploads/antpath/RUNTIME.json",
432
+ runtimeEnv: "/mnt/session/uploads/antpath/RUNTIME.env"
433
+ });
434
+
380
435
  // ../shared/dist/stable.js
381
436
  import { createHash } from "node:crypto";
382
- var ANTPATH_DEFAULT_BASE_URL = "https://www.antpath.ai";
437
+ var ANTPATH_DEFAULT_BASE_URL = "https://api.antpath.ai";
383
438
 
384
439
  // ../shared/dist/sdk-secrets.js
385
440
  var SECRET_PATTERNS = [
@@ -553,8 +608,7 @@ __export(operations_exports, {
553
608
  listSkills: () => listSkills,
554
609
  streamRunEventsSse: () => streamRunEventsSse,
555
610
  submitRun: () => submitRun,
556
- submitRunFlat: () => submitRunFlat,
557
- submitRunFlatMultipart: () => submitRunFlatMultipart,
611
+ submitRunMultipart: () => submitRunMultipart,
558
612
  whoami: () => whoami
559
613
  });
560
614
 
@@ -727,12 +781,6 @@ function findLineBreak(buffer) {
727
781
  }
728
782
 
729
783
  // ../shared/dist/operations.js
730
- async function submitRun(http, request) {
731
- return http.request("/api/runs", {
732
- method: "POST",
733
- body: JSON.stringify(request)
734
- });
735
- }
736
784
  async function getRun(http, runId) {
737
785
  const result = await http.request(`/api/runs/${encodeURIComponent(runId)}`);
738
786
  return hasRun(result) ? result.run : result;
@@ -883,28 +931,28 @@ async function downloadRunArchive(http, runId) {
883
931
  const { response } = await http.download(`/api/runs/${encodeURIComponent(runId)}/download`);
884
932
  return response;
885
933
  }
886
- async function submitRunFlat(http, request) {
934
+ async function submitRun(http, request) {
887
935
  return http.request("/api/runs", {
888
936
  method: "POST",
889
937
  body: JSON.stringify(request)
890
938
  });
891
939
  }
892
- async function submitRunFlatMultipart(http, request, bundles, agentsMdParts, fileParts) {
940
+ async function submitRunMultipart(http, request, bundles, agentsMdParts, fileParts) {
893
941
  const hasBundles = Array.isArray(bundles) && bundles.length > 0;
894
942
  const hasAgentsMd = Array.isArray(agentsMdParts) && agentsMdParts.length > 0;
895
943
  const hasFiles = Array.isArray(fileParts) && fileParts.length > 0;
896
944
  if (!hasBundles && !hasAgentsMd && !hasFiles) {
897
- throw new Error("submitRunFlatMultipart: bundles, agentsMdParts, or fileParts must be non-empty");
945
+ throw new Error("submitRunMultipart: bundles, agentsMdParts, or fileParts must be non-empty");
898
946
  }
899
947
  const form = new FormData();
900
948
  form.append("submission", new Blob([JSON.stringify(request)], { type: "application/json" }), "submission.json");
901
949
  const seen = /* @__PURE__ */ new Set();
902
950
  for (const bundle of bundles) {
903
951
  if (typeof bundle.slot !== "string" || !bundle.slot) {
904
- throw new Error("submitRunFlatMultipart: each bundle must have a non-empty slot id");
952
+ throw new Error("submitRunMultipart: each bundle must have a non-empty slot id");
905
953
  }
906
954
  if (seen.has(bundle.slot)) {
907
- throw new Error(`submitRunFlatMultipart: duplicate transient skill slot "${bundle.slot}"`);
955
+ throw new Error(`submitRunMultipart: duplicate inline skill slot "${bundle.slot}"`);
908
956
  }
909
957
  seen.add(bundle.slot);
910
958
  const blob = toBlob(bundle.bytes, "application/zip");
@@ -912,11 +960,11 @@ async function submitRunFlatMultipart(http, request, bundles, agentsMdParts, fil
912
960
  }
913
961
  for (const part of agentsMdParts ?? []) {
914
962
  if (typeof part.slot !== "string" || !part.slot) {
915
- throw new Error("submitRunFlatMultipart: each agentsMd part must have a non-empty slot id");
963
+ throw new Error("submitRunMultipart: each agentsMd part must have a non-empty slot id");
916
964
  }
917
965
  const partKey = `agentsmd:${part.slot}`;
918
966
  if (seen.has(partKey)) {
919
- throw new Error(`submitRunFlatMultipart: duplicate agentsMd slot "${part.slot}"`);
967
+ throw new Error(`submitRunMultipart: duplicate agentsMd slot "${part.slot}"`);
920
968
  }
921
969
  seen.add(partKey);
922
970
  const blob = new Blob([part.content], { type: "text/plain" });
@@ -924,11 +972,11 @@ async function submitRunFlatMultipart(http, request, bundles, agentsMdParts, fil
924
972
  }
925
973
  for (const part of fileParts ?? []) {
926
974
  if (typeof part.slot !== "string" || !part.slot) {
927
- throw new Error("submitRunFlatMultipart: each file part must have a non-empty slot id");
975
+ throw new Error("submitRunMultipart: each file part must have a non-empty slot id");
928
976
  }
929
977
  const partKey = `file:${part.slot}`;
930
978
  if (seen.has(partKey)) {
931
- throw new Error(`submitRunFlatMultipart: duplicate file slot "${part.slot}"`);
979
+ throw new Error(`submitRunMultipart: duplicate file slot "${part.slot}"`);
932
980
  }
933
981
  seen.add(partKey);
934
982
  const blob = toBlob(part.bytes, "application/zip");
@@ -1104,7 +1152,7 @@ var USAGE_ERR = { code: 2 };
1104
1152
  var RUNTIME_ERR = { code: 1 };
1105
1153
  function parseCommonHostFlags(argv) {
1106
1154
  let apiToken = null;
1107
- let dashboardUrl = null;
1155
+ let antpathUrl = null;
1108
1156
  const rest = [];
1109
1157
  for (let i = 0; i < argv.length; i++) {
1110
1158
  const arg = argv[i];
@@ -1115,11 +1163,11 @@ function parseCommonHostFlags(argv) {
1115
1163
  apiToken = v;
1116
1164
  continue;
1117
1165
  }
1118
- if (arg === "--dashboard-url") {
1166
+ if (arg === "--antpath-url") {
1119
1167
  const v = argv[++i];
1120
1168
  if (v === void 0)
1121
- return { ok: false, reason: "--dashboard-url requires a value" };
1122
- dashboardUrl = v;
1169
+ return { ok: false, reason: "--antpath-url requires a value" };
1170
+ antpathUrl = v;
1123
1171
  continue;
1124
1172
  }
1125
1173
  if (arg === "--workspace" || arg === "--workspace-id") {
@@ -1134,13 +1182,13 @@ function parseCommonHostFlags(argv) {
1134
1182
  return { ok: false, reason: "--api-token is required" };
1135
1183
  return {
1136
1184
  ok: true,
1137
- flags: { apiToken, dashboardUrl: dashboardUrl ?? ANTPATH_DEFAULT_BASE_URL },
1185
+ flags: { apiToken, antpathUrl: antpathUrl ?? ANTPATH_DEFAULT_BASE_URL },
1138
1186
  rest
1139
1187
  };
1140
1188
  }
1141
1189
  function makeHttpClient(io2, flags) {
1142
1190
  return new HttpClient({
1143
- baseUrl: flags.dashboardUrl,
1191
+ baseUrl: flags.antpathUrl,
1144
1192
  apiToken: flags.apiToken,
1145
1193
  fetch: io2.fetchImpl
1146
1194
  });
@@ -1593,17 +1641,69 @@ async function runRunCmd(io2, argv) {
1593
1641
  return USAGE_ERR;
1594
1642
  }
1595
1643
  let rest = common.rest;
1596
- const anthropicKey = takeFlagValue(rest, "--anthropic-api-key");
1597
- if (anthropicKey.error) {
1598
- io2.stderr(`${anthropicKey.error}
1644
+ const providerFlag = takeFlagValue(rest, "--provider");
1645
+ if (providerFlag.error) {
1646
+ io2.stderr(`${providerFlag.error}
1647
+ `);
1648
+ return USAGE_ERR;
1649
+ }
1650
+ rest = providerFlag.remaining;
1651
+ let provider = DEFAULT_RUN_PROVIDER;
1652
+ if (providerFlag.value !== null) {
1653
+ if (!RUN_PROVIDERS.includes(providerFlag.value)) {
1654
+ io2.stderr(`--provider must be one of: ${RUN_PROVIDERS.join(", ")} (got: ${providerFlag.value})
1655
+ `);
1656
+ return USAGE_ERR;
1657
+ }
1658
+ provider = providerFlag.value;
1659
+ }
1660
+ const providerKeyValues = {};
1661
+ for (const p of RUN_PROVIDERS) {
1662
+ const flag = takeFlagValue(rest, `--${p}-api-key`);
1663
+ if (flag.error) {
1664
+ io2.stderr(`${flag.error}
1665
+ `);
1666
+ return USAGE_ERR;
1667
+ }
1668
+ rest = flag.remaining;
1669
+ if (flag.value !== null)
1670
+ providerKeyValues[p] = flag.value;
1671
+ }
1672
+ if (!providerKeyValues[provider]) {
1673
+ io2.stderr(`--${provider}-api-key is required when --provider is ${provider} (the platform does not store provider keys on your behalf)
1599
1674
  `);
1600
1675
  return USAGE_ERR;
1601
1676
  }
1602
- rest = anthropicKey.remaining;
1603
- if (!anthropicKey.value) {
1604
- io2.stderr("--anthropic-api-key is required (the platform does not store provider keys on your behalf)\n");
1677
+ for (const p of RUN_PROVIDERS) {
1678
+ if (p === provider)
1679
+ continue;
1680
+ if (providerKeyValues[p] !== void 0) {
1681
+ io2.stderr(`--${p}-api-key is not allowed when --provider is ${provider}
1682
+ `);
1683
+ return USAGE_ERR;
1684
+ }
1685
+ }
1686
+ const runtimeFlag = takeFlagValue(rest, "--runtime");
1687
+ if (runtimeFlag.error) {
1688
+ io2.stderr(`${runtimeFlag.error}
1689
+ `);
1605
1690
  return USAGE_ERR;
1606
1691
  }
1692
+ rest = runtimeFlag.remaining;
1693
+ let runtime;
1694
+ if (runtimeFlag.value !== null) {
1695
+ if (!RUNTIME_KINDS.includes(runtimeFlag.value)) {
1696
+ io2.stderr(`--runtime must be one of: ${RUNTIME_KINDS.join(", ")} (got: ${runtimeFlag.value})
1697
+ `);
1698
+ return USAGE_ERR;
1699
+ }
1700
+ runtime = runtimeFlag.value;
1701
+ if (runtime === "native" && provider !== "anthropic") {
1702
+ io2.stderr(`--runtime native is only supported for --provider anthropic (got: ${provider})
1703
+ `);
1704
+ return USAGE_ERR;
1705
+ }
1706
+ }
1607
1707
  const idempotency = takeFlagValue(rest, "--idempotency-key");
1608
1708
  if (idempotency.error) {
1609
1709
  io2.stderr(`${idempotency.error}
@@ -1652,13 +1752,6 @@ async function runRunCmd(io2, argv) {
1652
1752
  return USAGE_ERR;
1653
1753
  }
1654
1754
  rest = promptFlags.remaining;
1655
- const skillFlags = collectRepeated(rest, "--skill");
1656
- if (skillFlags.error) {
1657
- io2.stderr(`${skillFlags.error}
1658
- `);
1659
- return USAGE_ERR;
1660
- }
1661
- rest = skillFlags.remaining;
1662
1755
  const providerSkillFlags = collectRepeated(rest, "--provider-skill");
1663
1756
  if (providerSkillFlags.error) {
1664
1757
  io2.stderr(`${providerSkillFlags.error}
@@ -1716,8 +1809,8 @@ async function runRunCmd(io2, argv) {
1716
1809
  let blueprint;
1717
1810
  let mcpHeadersFromConfig = /* @__PURE__ */ new Map();
1718
1811
  if (config.value) {
1719
- if (modelFlag.value || systemFlag.value || promptFlags.values.length || skillFlags.values.length || providerSkillFlags.values.length || Object.keys(mcpFlags.entries).length || Object.keys(metadataFlags.entries).length) {
1720
- io2.stderr("--config cannot be combined with --model/--system/--prompt/--skill/--provider-skill/--mcp/--metadata\n");
1812
+ if (modelFlag.value || systemFlag.value || promptFlags.values.length || providerSkillFlags.values.length || Object.keys(mcpFlags.entries).length || Object.keys(metadataFlags.entries).length) {
1813
+ io2.stderr("--config cannot be combined with --model/--system/--prompt/--provider-skill/--mcp/--metadata\n");
1721
1814
  return USAGE_ERR;
1722
1815
  }
1723
1816
  try {
@@ -1759,10 +1852,8 @@ async function runRunCmd(io2, argv) {
1759
1852
  return USAGE_ERR;
1760
1853
  }
1761
1854
  }
1762
- let workspaceSkills;
1763
1855
  let providerSkills;
1764
1856
  try {
1765
- workspaceSkills = skillFlags.values.map((v, i) => parseWorkspaceSkillFlag(v, i));
1766
1857
  providerSkills = providerSkillFlags.values.map((v, i) => parseProviderSkillFlag(v, i));
1767
1858
  } catch (err2) {
1768
1859
  io2.stderr(`${err2.message}
@@ -1777,7 +1868,7 @@ async function runRunCmd(io2, argv) {
1777
1868
  model: modelFlag.value,
1778
1869
  ...resolvedSystem ? { system: resolvedSystem } : {},
1779
1870
  prompt: resolvedPrompt,
1780
- ...workspaceSkills.length + providerSkills.length > 0 ? { skills: [...workspaceSkills, ...providerSkills] } : {},
1871
+ ...providerSkills.length > 0 ? { skills: providerSkills } : {},
1781
1872
  ...mcpRefs.length > 0 ? { mcpServers: mcpRefs } : {},
1782
1873
  ...Object.keys(metadataFlags.entries).length > 0 ? { metadata: { ...metadataFlags.entries } } : {}
1783
1874
  };
@@ -1863,13 +1954,18 @@ async function runRunCmd(io2, argv) {
1863
1954
  ...blueprint.environment ? { environment: blueprint.environment } : {},
1864
1955
  ...blueprint.metadata ? { metadata: blueprint.metadata } : {}
1865
1956
  };
1957
+ const providerSecrets = {
1958
+ [provider]: { apiKey: providerKeyValues[provider] }
1959
+ };
1866
1960
  const secrets = {
1867
- anthropic: { apiKey: anthropicKey.value },
1961
+ ...providerSecrets,
1868
1962
  ...mcpServerSecrets.length > 0 ? { mcpServers: mcpServerSecrets } : {},
1869
1963
  ...proxyAuth.length > 0 ? { proxyEndpointAuth: proxyAuth } : {}
1870
1964
  };
1871
1965
  const request = {
1872
1966
  idempotencyKey: idempotency.value ?? generateIdempotencyKey(),
1967
+ provider,
1968
+ ...runtime ? { runtime } : {},
1873
1969
  submission,
1874
1970
  secrets,
1875
1971
  ...cleanup.value ? { cleanup: { session: cleanup.value } } : {},
@@ -1879,7 +1975,7 @@ async function runRunCmd(io2, argv) {
1879
1975
  const http = makeHttpClient(io2, common.flags);
1880
1976
  let run;
1881
1977
  try {
1882
- run = await operations_exports.submitRunFlat(http, request);
1978
+ run = await operations_exports.submitRun(http, request);
1883
1979
  } catch (err2) {
1884
1980
  return emitJsonError(io2, "submit_failed", err2.message ?? "submission failed");
1885
1981
  }
@@ -1959,12 +2055,6 @@ function parseJsonOrThrow(raw, label) {
1959
2055
  throw new Error(`${label} is not valid JSON: ${err2.message}`);
1960
2056
  }
1961
2057
  }
1962
- function parseWorkspaceSkillFlag(raw, idx) {
1963
- if (!raw) {
1964
- throw new Error(`--skill[${idx}] must be a non-empty skill id`);
1965
- }
1966
- return { kind: "workspace", id: raw };
1967
- }
1968
2058
  function parseProviderSkillFlag(raw, idx) {
1969
2059
  const parts = raw.split(":");
1970
2060
  if (parts.length < 2 || parts.length > 3) {
@@ -3403,7 +3493,7 @@ Protocol version: ${manifest.protocolVersion}
3403
3493
  io2.stdout("antpath \u2014 unified CLI for the antpath platform (mirrors the SDK 1:1)\n\n");
3404
3494
  io2.stdout("Usage:\n");
3405
3495
  io2.stdout(" antpath run --config <run.json> --anthropic-api-key K --api-token T [flags]\n");
3406
- io2.stdout(" antpath run --model M --prompt P [--system S] [--skill ID ...] [--mcp name=url ...] --anthropic-api-key K --api-token T [flags]\n");
3496
+ io2.stdout(" antpath run --model M --prompt P [--system S] [--provider-skill v:s ...] [--mcp name=url ...] --anthropic-api-key K --api-token T [flags]\n");
3407
3497
  io2.stdout(" antpath skills upload --name N --from-path <dir> --api-token T\n");
3408
3498
  io2.stdout(" antpath skills upload --name N --file <path> [--file <path> ...] --api-token T\n");
3409
3499
  io2.stdout(" antpath skills list --api-token T\n");
@@ -3419,14 +3509,15 @@ Protocol version: ${manifest.protocolVersion}
3419
3509
  io2.stdout(" antpath --help\n\n");
3420
3510
  io2.stdout("Common flags on every host subcommand:\n");
3421
3511
  io2.stdout(" --api-token <token> REQUIRED \u2014 antpath SDK API token (workspace is derived from it)\n");
3422
- io2.stdout(" --dashboard-url <url> Optional; defaults to https://www.antpath.ai (set for self-hosted)\n\n");
3512
+ io2.stdout(" --antpath-url <url> Optional; defaults to https://api.antpath.ai (set for self-hosted)\n\n");
3423
3513
  io2.stdout("antpath run flags:\n");
3424
- io2.stdout(" --anthropic-api-key <key> REQUIRED \u2014 provider key (never stored)\n");
3514
+ io2.stdout(" --provider <name> Optional; one of: anthropic (default), deepseek\n");
3515
+ io2.stdout(" --anthropic-api-key <key> REQUIRED when --provider anthropic (default); never stored\n");
3516
+ io2.stdout(" --deepseek-api-key <key> REQUIRED when --provider deepseek; never stored\n");
3425
3517
  io2.stdout(" --config <path> JSON Blueprint (mutually exclusive with the flat --model/--prompt flags)\n");
3426
3518
  io2.stdout(" --model <model-id> Anthropic model id (required in flat mode)\n");
3427
3519
  io2.stdout(" --system @file | <text> System message; @-prefix reads from file\n");
3428
3520
  io2.stdout(" --prompt @file | <text> User message; @-prefix reads from file (repeatable)\n");
3429
- io2.stdout(" --skill <skl_id> Workspace skill (repeatable)\n");
3430
3521
  io2.stdout(" --provider-skill v:s[:ver] Provider built-in skill (vendor:skillId[:version], repeatable)\n");
3431
3522
  io2.stdout(" --mcp name=url MCP server entry (repeatable)\n");
3432
3523
  io2.stdout(" --mcp-auth name=Hdr:Val Auth header on the matching --mcp; routed into vaulted secrets (repeatable)\n");
@@ -1 +1 @@
1
- 80d5b8acd38d2604064106537102276eed37305fe2eedce375c0c8dee0d1b141 cli.mjs
1
+ ba35805b91e9b19eeeead9f80278140797287bc4d14e6618b842354cb2cb3208 cli.mjs