antpath 0.2.1 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +55 -40
  2. package/dist/_shared/cleanup-policy.d.ts +8 -0
  3. package/dist/_shared/cleanup-policy.js +24 -0
  4. package/dist/_shared/config.d.ts +47 -0
  5. package/dist/_shared/config.js +150 -0
  6. package/dist/_shared/dev-stack.d.ts +19 -0
  7. package/dist/_shared/dev-stack.js +105 -0
  8. package/dist/_shared/errors.d.ts +8 -0
  9. package/dist/_shared/errors.js +18 -0
  10. package/dist/_shared/http.d.ts +20 -0
  11. package/dist/_shared/http.js +94 -0
  12. package/dist/_shared/index.d.ts +17 -0
  13. package/dist/_shared/index.js +20 -0
  14. package/dist/{providers → _shared}/known-events.d.ts +10 -10
  15. package/dist/{providers → _shared}/known-events.js +9 -9
  16. package/dist/_shared/operations.d.ts +19 -0
  17. package/dist/_shared/operations.js +42 -0
  18. package/dist/_shared/proxy-protocol.d.ts +148 -0
  19. package/dist/_shared/proxy-protocol.js +113 -0
  20. package/dist/_shared/proxy-validation.d.ts +19 -0
  21. package/dist/_shared/proxy-validation.js +51 -0
  22. package/dist/_shared/runtime-types.d.ts +90 -0
  23. package/dist/_shared/runtime-types.js +2 -0
  24. package/dist/{errors.d.ts → _shared/sdk-errors.d.ts} +10 -1
  25. package/dist/{errors.js → _shared/sdk-errors.js} +15 -2
  26. package/dist/{utils/secrets.js → _shared/sdk-secrets.js} +1 -1
  27. package/dist/_shared/secrets.d.ts +7 -0
  28. package/dist/_shared/secrets.js +20 -0
  29. package/dist/_shared/status.d.ts +8 -0
  30. package/dist/_shared/status.js +46 -0
  31. package/dist/_shared/submission.d.ts +142 -0
  32. package/dist/_shared/submission.js +681 -0
  33. package/dist/{template → _shared/template}/compiler.js +3 -3
  34. package/dist/{template/index.d.ts → _shared/template/helpers.d.ts} +0 -2
  35. package/dist/{template/index.js → _shared/template/helpers.js} +1 -2
  36. package/dist/_shared/template/index.d.ts +4 -0
  37. package/dist/_shared/template/index.js +4 -0
  38. package/dist/_shared/template/mapper.d.ts +11 -0
  39. package/dist/_shared/template/mapper.js +70 -0
  40. package/dist/cli.mjs +1234 -64
  41. package/dist/cli.mjs.sha256 +1 -1
  42. package/dist/client.d.ts +93 -8
  43. package/dist/client.js +192 -30
  44. package/dist/client.js.map +1 -1
  45. package/dist/index.d.ts +16 -10
  46. package/dist/index.js +16 -7
  47. package/dist/index.js.map +1 -1
  48. package/docs/cleanup.md +7 -4
  49. package/docs/credentials.md +12 -12
  50. package/docs/events.md +19 -82
  51. package/docs/outputs.md +15 -4
  52. package/docs/quickstart.md +42 -5
  53. package/docs/skills.md +1 -1
  54. package/docs/templates.md +1 -1
  55. package/docs/testing.md +11 -8
  56. package/examples/mcp-static-bearer.ts +14 -9
  57. package/examples/quickstart.ts +8 -6
  58. package/package.json +4 -5
  59. package/references/implementation-plan.md +1 -1
  60. package/dist/credentials.d.ts +0 -3
  61. package/dist/credentials.js +0 -56
  62. package/dist/credentials.js.map +0 -1
  63. package/dist/errors.js.map +0 -1
  64. package/dist/files/downloader.d.ts +0 -3
  65. package/dist/files/downloader.js +0 -43
  66. package/dist/files/downloader.js.map +0 -1
  67. package/dist/platform/client.d.ts +0 -204
  68. package/dist/platform/client.js +0 -203
  69. package/dist/platform/client.js.map +0 -1
  70. package/dist/platform/index.d.ts +0 -1
  71. package/dist/platform/index.js +0 -2
  72. package/dist/platform/index.js.map +0 -1
  73. package/dist/providers/anthropic/provider.d.ts +0 -36
  74. package/dist/providers/anthropic/provider.js +0 -380
  75. package/dist/providers/anthropic/provider.js.map +0 -1
  76. package/dist/providers/known-events.js.map +0 -1
  77. package/dist/providers/types.d.ts +0 -42
  78. package/dist/providers/types.js.map +0 -1
  79. package/dist/run/controller.d.ts +0 -30
  80. package/dist/run/controller.js +0 -314
  81. package/dist/run/controller.js.map +0 -1
  82. package/dist/skills/packager.d.ts +0 -11
  83. package/dist/skills/packager.js +0 -76
  84. package/dist/skills/packager.js.map +0 -1
  85. package/dist/template/compiler.js.map +0 -1
  86. package/dist/template/index.js.map +0 -1
  87. package/dist/template/types.js +0 -2
  88. package/dist/template/types.js.map +0 -1
  89. package/dist/types.d.ts +0 -149
  90. package/dist/types.js +0 -2
  91. package/dist/types.js.map +0 -1
  92. package/dist/utils/events.d.ts +0 -27
  93. package/dist/utils/events.js +0 -120
  94. package/dist/utils/events.js.map +0 -1
  95. package/dist/utils/paths.d.ts +0 -3
  96. package/dist/utils/paths.js +0 -27
  97. package/dist/utils/paths.js.map +0 -1
  98. package/dist/utils/secrets.js.map +0 -1
  99. package/dist/utils/stable.js.map +0 -1
  100. /package/dist/{utils/secrets.d.ts → _shared/sdk-secrets.d.ts} +0 -0
  101. /package/dist/{utils → _shared}/stable.d.ts +0 -0
  102. /package/dist/{utils → _shared}/stable.js +0 -0
  103. /package/dist/{template → _shared/template}/compiler.d.ts +0 -0
  104. /package/dist/{template → _shared/template}/types.d.ts +0 -0
  105. /package/dist/{providers → _shared/template}/types.js +0 -0
package/dist/cli.mjs CHANGED
@@ -1,6 +1,12 @@
1
1
  #!/usr/bin/env node
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, { get: all[name], enumerable: true });
6
+ };
7
+
2
8
  // dist/cli.js
3
- import { readFile } from "node:fs/promises";
9
+ import { readFile, writeFile } from "node:fs/promises";
4
10
 
5
11
  // ../shared/dist/config.js
6
12
  var DEFAULT_CAPS = {
@@ -57,88 +63,567 @@ var PROXY_ENDPOINT_DEFAULTS = {
57
63
  responseByteBudget: 1024 * 1024
58
64
  };
59
65
 
66
+ // ../shared/dist/stable.js
67
+ import { createHash } from "node:crypto";
68
+ function stableStringify(value) {
69
+ return JSON.stringify(sortValue(value));
70
+ }
71
+ function sha256(value) {
72
+ return createHash("sha256").update(typeof value === "string" ? value : stableStringify(value)).digest("hex");
73
+ }
74
+ function sortValue(value) {
75
+ if (Array.isArray(value)) {
76
+ return value.map(sortValue);
77
+ }
78
+ if (value && typeof value === "object") {
79
+ return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== void 0).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => [key, sortValue(item)]));
80
+ }
81
+ return value;
82
+ }
83
+
84
+ // ../shared/dist/sdk-secrets.js
85
+ var SECRET_PATTERNS = [
86
+ /sk-ant-[A-Za-z0-9_\-]{16,}/g,
87
+ /sk-[A-Za-z0-9_\-]{20,}/g,
88
+ /xox[pbar]-[A-Za-z0-9\-]{10,}/g,
89
+ /(?:bearer|token|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret)["'\s:=]+[A-Za-z0-9_\-./+=]{12,}/gi
90
+ ];
91
+ var REDACTED = "[REDACTED]";
92
+ function redactSecrets(value) {
93
+ if (typeof value === "string") {
94
+ return redactString(value);
95
+ }
96
+ if (Array.isArray(value)) {
97
+ return value.map((item) => redactSecrets(item));
98
+ }
99
+ if (value && typeof value === "object") {
100
+ const out = {};
101
+ for (const [key, item] of Object.entries(value)) {
102
+ if (isSecretKey(key)) {
103
+ out[key] = REDACTED;
104
+ } else {
105
+ out[key] = redactSecrets(item);
106
+ }
107
+ }
108
+ return out;
109
+ }
110
+ return value;
111
+ }
112
+ function redactString(input) {
113
+ return SECRET_PATTERNS.reduce((current, pattern) => current.replace(pattern, REDACTED), input);
114
+ }
115
+ function containsSecretLikeValue(input) {
116
+ return SECRET_PATTERNS.some((pattern) => {
117
+ pattern.lastIndex = 0;
118
+ return pattern.test(input);
119
+ });
120
+ }
121
+ function isSecretKey(key) {
122
+ return /(?:api[_-]?key|authorization|token|secret|password|credential)/i.test(key);
123
+ }
124
+
125
+ // ../shared/dist/sdk-errors.js
126
+ var AntpathError = class extends Error {
127
+ code;
128
+ details;
129
+ constructor(code, message, details) {
130
+ super(redactSecrets(message));
131
+ this.name = this.constructor.name;
132
+ this.code = code;
133
+ this.details = details === void 0 ? void 0 : redactSecrets(details);
134
+ }
135
+ };
136
+ var TemplateValidationError = class extends AntpathError {
137
+ constructor(message, details) {
138
+ super("TEMPLATE_INVALID", message, details);
139
+ }
140
+ };
141
+ var AntpathApiError = class extends AntpathError {
142
+ status;
143
+ body;
144
+ constructor(status, message, body) {
145
+ super("API_ERROR", message, body);
146
+ this.status = status;
147
+ this.body = redactSecrets(body);
148
+ }
149
+ };
150
+
151
+ // ../shared/dist/template/compiler.js
152
+ var ESCAPED_OPEN = "\0ANTPATH_ESCAPED_OPEN\0";
153
+ var VARIABLE_PATTERN = /{{\s*([A-Za-z_][A-Za-z0-9_]*)\s*}}/g;
154
+ function compileTemplate(template, variables = {}) {
155
+ assertTemplateShape(template);
156
+ const values = resolveVariableValues(template, variables);
157
+ const resolved = {
158
+ name: template.name,
159
+ model: resolveValue(template.model, values, template.variables ?? {}),
160
+ system: template.system === void 0 ? void 0 : resolveValue(template.system, values, template.variables ?? {}),
161
+ messages: template.messages.map((message) => resolveValue(message, values, template.variables ?? {})),
162
+ mcpServers: resolveMcpServers(template.mcpServers ?? {}, values, template.variables ?? {}),
163
+ environment: resolveValue(template.environment ?? {}, values, template.variables ?? {}),
164
+ skills: resolveValue(template.skills ?? [], values, template.variables ?? {}),
165
+ outputs: {
166
+ recommendedPath: "/antpath/outputs",
167
+ ...resolveValue(template.outputs ?? {}, values, template.variables ?? {})
168
+ },
169
+ metadata: resolveValue(template.metadata ?? {}, values, template.variables ?? {}),
170
+ credentialRequirements: {}
171
+ };
172
+ resolved.credentialRequirements = Object.fromEntries(resolved.mcpServers.filter((server) => server.auth).map((server) => [server.key, server.auth]));
173
+ scanForSecrets(resolved);
174
+ return {
175
+ ...resolved,
176
+ hash: sha256(stableStringify(resolved))
177
+ };
178
+ }
179
+ function assertTemplateShape(template) {
180
+ if (!template.name?.trim()) {
181
+ throw new TemplateValidationError("Template name is required");
182
+ }
183
+ if (!template.model) {
184
+ throw new TemplateValidationError("Template model is required");
185
+ }
186
+ if (!Array.isArray(template.messages) || template.messages.length === 0) {
187
+ throw new TemplateValidationError("Template must define at least one user message");
188
+ }
189
+ for (const [key, server] of Object.entries(template.mcpServers ?? {})) {
190
+ if (!/^[A-Za-z0-9_-]+$/.test(key)) {
191
+ throw new TemplateValidationError(`MCP server key '${key}' must use letters, numbers, underscores, or hyphens`);
192
+ }
193
+ if (server.tools?.allow && server.tools.deny) {
194
+ throw new TemplateValidationError(`MCP server '${key}' cannot define both allow and deny tool policies`);
195
+ }
196
+ }
197
+ }
198
+ function resolveVariableValues(template, variables) {
199
+ const definitions = template.variables ?? {};
200
+ const resolved = {};
201
+ for (const [key, definition] of Object.entries(definitions)) {
202
+ const value = variables[key] ?? definition.default;
203
+ if (value === void 0) {
204
+ continue;
205
+ }
206
+ if (typeof value !== "string") {
207
+ throw new TemplateValidationError(`Variable '${key}' must resolve to a string`);
208
+ }
209
+ resolved[key] = value;
210
+ }
211
+ for (const key of Object.keys(variables)) {
212
+ if (!definitions[key]) {
213
+ throw new TemplateValidationError(`Unknown Template variable '${key}'`);
214
+ }
215
+ }
216
+ return resolved;
217
+ }
218
+ function resolveMcpServers(servers, values, definitions) {
219
+ return Object.entries(servers).map(([key, server]) => {
220
+ const resolved = {
221
+ key,
222
+ name: key,
223
+ url: resolveValue(server.url, values, definitions ?? {})
224
+ };
225
+ if (server.auth)
226
+ resolved.auth = server.auth;
227
+ if (server.tools)
228
+ resolved.tools = resolveValue(server.tools, values, definitions ?? {});
229
+ return resolved;
230
+ });
231
+ }
232
+ function resolveValue(value, variables, definitions) {
233
+ if (typeof value === "string") {
234
+ return resolveString(value, variables, definitions);
235
+ }
236
+ if (Array.isArray(value)) {
237
+ return value.map((item) => resolveValue(item, variables, definitions));
238
+ }
239
+ if (value && typeof value === "object") {
240
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, resolveValue(item, variables, definitions)]));
241
+ }
242
+ return value;
243
+ }
244
+ function resolveString(input, variables, definitions) {
245
+ const protectedInput = input.replace(/\\{{/g, ESCAPED_OPEN);
246
+ const resolved = protectedInput.replace(VARIABLE_PATTERN, (_match, name) => {
247
+ if (!definitions[name]) {
248
+ throw new TemplateValidationError(`Unresolved Template variable '${name}'`);
249
+ }
250
+ const value = variables[name];
251
+ if (value === void 0) {
252
+ throw new TemplateValidationError(`Missing value for Template variable '${name}'`);
253
+ }
254
+ return value;
255
+ });
256
+ return resolved.replace(new RegExp(ESCAPED_OPEN, "g"), "{{");
257
+ }
258
+ function scanForSecrets(value) {
259
+ const serialized = stableStringify(value);
260
+ if (containsSecretLikeValue(serialized)) {
261
+ throw new TemplateValidationError("Template contains a secret-like value; pass secrets through typed credentials instead");
262
+ }
263
+ }
264
+
265
+ // ../shared/dist/template/mapper.js
266
+ function toPlatformSubmissionTemplate(resolved) {
267
+ const modelId = typeof resolved.model === "string" ? resolved.model : resolved.model.id;
268
+ const environment = mapEnvironment(resolved.environment);
269
+ const metadata = filterMetadata(resolved.metadata);
270
+ const submission = {
271
+ name: resolved.name,
272
+ model: modelId,
273
+ templateHash: resolved.hash,
274
+ messages: resolved.messages
275
+ };
276
+ return {
277
+ ...submission,
278
+ ...resolved.system ? { system: resolved.system } : {},
279
+ ...metadata ? { metadata } : {},
280
+ ...environment ? { environment } : {}
281
+ };
282
+ }
283
+ function mapEnvironment(env) {
284
+ if (!env)
285
+ return void 0;
286
+ let networking;
287
+ if (env.network) {
288
+ if (env.network === "restricted") {
289
+ networking = { mode: "limited", allowedHosts: [] };
290
+ } else if (env.network === "unrestricted") {
291
+ networking = { mode: "open" };
292
+ } else if (typeof env.network === "object" && env.network.type === "limited") {
293
+ const allowedHosts = env.network.allowedHosts ?? [];
294
+ networking = { mode: "limited", allowedHosts };
295
+ }
296
+ }
297
+ let packages;
298
+ if (env.packages) {
299
+ const collected = [];
300
+ for (const [manager, list] of Object.entries(env.packages)) {
301
+ if (!list)
302
+ continue;
303
+ for (const item of list) {
304
+ collected.push({ name: `${manager}:${item}` });
305
+ }
306
+ }
307
+ if (collected.length > 0)
308
+ packages = collected;
309
+ }
310
+ if (!networking && !packages)
311
+ return void 0;
312
+ return {
313
+ ...networking ? { networking } : {},
314
+ ...packages ? { packages } : {}
315
+ };
316
+ }
317
+ function filterMetadata(metadata) {
318
+ if (!metadata)
319
+ return void 0;
320
+ const entries = Object.entries(metadata);
321
+ if (entries.length === 0)
322
+ return void 0;
323
+ return Object.fromEntries(entries);
324
+ }
325
+
326
+ // ../shared/dist/http.js
327
+ var HttpClient = class {
328
+ #baseUrl;
329
+ #apiToken;
330
+ #fetch;
331
+ constructor(options) {
332
+ if (!options.baseUrl) {
333
+ throw new Error("HttpClient: baseUrl is required");
334
+ }
335
+ if (!options.apiToken) {
336
+ throw new Error("HttpClient: apiToken is required");
337
+ }
338
+ const normalized = options.baseUrl.endsWith("/") ? options.baseUrl : `${options.baseUrl}/`;
339
+ this.#baseUrl = new URL(normalized);
340
+ this.#apiToken = options.apiToken;
341
+ this.#fetch = options.fetch ?? fetch;
342
+ }
343
+ async request(path, init = {}, query = {}) {
344
+ const url = new URL(path.replace(/^\//, ""), this.#baseUrl);
345
+ for (const [key, value] of Object.entries(query)) {
346
+ url.searchParams.set(key, value);
347
+ }
348
+ const headers = {
349
+ accept: "application/json",
350
+ authorization: `Bearer ${this.#apiToken}`,
351
+ ...normalizeHeaders(init.headers)
352
+ };
353
+ if (init.body !== void 0 && init.body !== null && !headers["content-type"]) {
354
+ headers["content-type"] = "application/json";
355
+ }
356
+ const response = await this.#fetch(url, { ...init, headers });
357
+ const body = await readJson(response);
358
+ if (!response.ok) {
359
+ throw new AntpathApiError(response.status, extractErrorMessage(body), body);
360
+ }
361
+ return body;
362
+ }
363
+ async download(path, init = {}, query = {}) {
364
+ const url = new URL(path.replace(/^\//, ""), this.#baseUrl);
365
+ for (const [key, value] of Object.entries(query)) {
366
+ url.searchParams.set(key, value);
367
+ }
368
+ const headers = {
369
+ authorization: `Bearer ${this.#apiToken}`,
370
+ ...normalizeHeaders(init.headers)
371
+ };
372
+ const response = await this.#fetch(url, { ...init, headers });
373
+ if (!response.ok) {
374
+ const body = await readJson(response);
375
+ throw new AntpathApiError(response.status, extractErrorMessage(body), body);
376
+ }
377
+ return { response };
378
+ }
379
+ };
380
+ function normalizeHeaders(headers) {
381
+ if (!headers)
382
+ return {};
383
+ if (headers instanceof Headers)
384
+ return Object.fromEntries(headers.entries());
385
+ if (Array.isArray(headers))
386
+ return Object.fromEntries(headers);
387
+ return headers;
388
+ }
389
+ async function readJson(response) {
390
+ const text = await response.text();
391
+ if (text.length === 0)
392
+ return {};
393
+ try {
394
+ return JSON.parse(text);
395
+ } catch {
396
+ return { raw: text };
397
+ }
398
+ }
399
+ function extractErrorMessage(body) {
400
+ if (body && typeof body === "object" && "error" in body) {
401
+ const error = body.error;
402
+ if (typeof error === "string")
403
+ return error;
404
+ if (error && typeof error === "object" && "message" in error) {
405
+ const message = error.message;
406
+ if (typeof message === "string")
407
+ return message;
408
+ }
409
+ }
410
+ return "antpath API request failed";
411
+ }
412
+
413
+ // ../shared/dist/operations.js
414
+ var operations_exports = {};
415
+ __export(operations_exports, {
416
+ cancelRun: () => cancelRun,
417
+ createOutputLink: () => createOutputLink,
418
+ deleteRun: () => deleteRun,
419
+ getRun: () => getRun,
420
+ listOutputs: () => listOutputs,
421
+ listRunEvents: () => listRunEvents,
422
+ submitRun: () => submitRun,
423
+ whoami: () => whoami
424
+ });
425
+ async function submitRun(http, request) {
426
+ return http.request("/api/runs", {
427
+ method: "POST",
428
+ body: JSON.stringify(request)
429
+ });
430
+ }
431
+ async function getRun(http, workspaceId, runId) {
432
+ const result = await http.request(`/api/runs/${encodeURIComponent(runId)}`, {}, { workspaceId });
433
+ return hasRun(result) ? result.run : result;
434
+ }
435
+ async function listRunEvents(http, workspaceId, runId) {
436
+ const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events`, {}, { workspaceId });
437
+ return result.events;
438
+ }
439
+ async function listOutputs(http, workspaceId, runId) {
440
+ const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`, {}, { workspaceId });
441
+ return result.outputs;
442
+ }
443
+ async function createOutputLink(http, workspaceId, runId, outputId) {
444
+ return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" }, { workspaceId });
445
+ }
446
+ async function cancelRun(http, workspaceId, runId) {
447
+ await http.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" }, { workspaceId });
448
+ }
449
+ async function deleteRun(http, workspaceId, runId) {
450
+ await http.request(`/api/runs/${encodeURIComponent(runId)}`, { method: "DELETE" }, { workspaceId });
451
+ }
452
+ async function whoami(http) {
453
+ return http.request("/api/whoami");
454
+ }
455
+ function hasRun(value) {
456
+ return Boolean(value && typeof value === "object" && "run" in value);
457
+ }
458
+
459
+ // ../shared/dist/proxy-validation.js
460
+ function validateProxyAuth(endpoints, auth) {
461
+ const authList = auth ?? [];
462
+ const endpointNames = new Set(endpoints.map((e) => e.name));
463
+ const authNames = /* @__PURE__ */ new Set();
464
+ for (const entry of authList) {
465
+ if (authNames.has(entry.name)) {
466
+ throw new Error(`secrets.proxyEndpointAuth contains duplicate name '${entry.name}'`);
467
+ }
468
+ authNames.add(entry.name);
469
+ if (!endpointNames.has(entry.name)) {
470
+ throw new Error(`secrets.proxyEndpointAuth[].name='${entry.name}' has no matching proxyEndpoints[].name`);
471
+ }
472
+ }
473
+ for (const endpoint of endpoints) {
474
+ const match = authList.find((a) => a.name === endpoint.name);
475
+ if (!match) {
476
+ throw new Error(`proxyEndpoints[].name='${endpoint.name}' is missing a matching secrets.proxyEndpointAuth entry`);
477
+ }
478
+ if (match.value.type !== endpoint.authShape.type) {
479
+ throw new Error(`secrets.proxyEndpointAuth[name='${endpoint.name}'].value.type='${match.value.type}' does not match proxyEndpoints[name='${endpoint.name}'].authShape.type='${endpoint.authShape.type}'`);
480
+ }
481
+ }
482
+ }
483
+
60
484
  // dist/internal.js
61
485
  var ANTPATH_INDEX_PATH = "/antpath/index.json";
62
486
  var ANTPATH_RUN_TOKEN_PATH = "/antpath/run-token";
63
487
 
64
- // dist/run.js
488
+ // dist/host/common.js
65
489
  var SUCCESS = { code: 0 };
66
490
  var USAGE_ERR = { code: 2 };
67
491
  var RUNTIME_ERR = { code: 1 };
68
- async function runCli(io2) {
69
- const args = io2.argv.slice(2);
492
+ function parseCommonHostFlags(argv, options = {}) {
493
+ const requireWorkspace = options.requireWorkspace ?? true;
494
+ let apiToken = null;
495
+ let workspaceId = null;
496
+ let dashboardUrl = null;
497
+ const rest = [];
498
+ for (let i = 0; i < argv.length; i++) {
499
+ const arg = argv[i];
500
+ if (arg === "--api-token") {
501
+ const v = argv[++i];
502
+ if (v === void 0)
503
+ return { ok: false, reason: "--api-token requires a value" };
504
+ apiToken = v;
505
+ continue;
506
+ }
507
+ if (arg === "--workspace") {
508
+ const v = argv[++i];
509
+ if (v === void 0)
510
+ return { ok: false, reason: "--workspace requires a value" };
511
+ workspaceId = v;
512
+ continue;
513
+ }
514
+ if (arg === "--dashboard-url") {
515
+ const v = argv[++i];
516
+ if (v === void 0)
517
+ return { ok: false, reason: "--dashboard-url requires a value" };
518
+ dashboardUrl = v;
519
+ continue;
520
+ }
521
+ rest.push(arg);
522
+ }
523
+ if (!apiToken)
524
+ return { ok: false, reason: "--api-token is required" };
525
+ if (!dashboardUrl)
526
+ return { ok: false, reason: "--dashboard-url is required" };
527
+ if (requireWorkspace && !workspaceId) {
528
+ return { ok: false, reason: "--workspace is required" };
529
+ }
530
+ return {
531
+ ok: true,
532
+ flags: { apiToken, workspaceId: workspaceId ?? "", dashboardUrl },
533
+ rest
534
+ };
535
+ }
536
+ function makeHttpClient(io2, flags) {
537
+ return new HttpClient({
538
+ baseUrl: flags.dashboardUrl,
539
+ apiToken: flags.apiToken,
540
+ fetch: io2.fetchImpl
541
+ });
542
+ }
543
+ async function refuseInsideManagedRun(io2, verb) {
70
544
  try {
71
- const exit = await dispatch(io2, args);
72
- io2.exit(exit.code);
73
- } catch (err) {
74
- const body = { error: "internal_error", message: err.message ?? "unknown error" };
75
- io2.stderr(JSON.stringify(body) + "\n");
76
- io2.exit(RUNTIME_ERR.code);
545
+ await io2.readFile(ANTPATH_INDEX_PATH);
546
+ io2.stderr(`\`antpath ${verb}\` is a host command and cannot run inside a managed run container.
547
+ Use \`antpath proxy ...\` to call your declared upstream endpoints from inside the run.
548
+ `);
549
+ return true;
550
+ } catch {
551
+ return false;
77
552
  }
78
553
  }
79
- async function dispatch(io2, args) {
80
- if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
81
- return await printGlobalHelp(io2);
554
+ function emitJsonError(io2, code, message, extra = {}) {
555
+ io2.stderr(JSON.stringify({ error: code, message, ...extra }) + "\n");
556
+ return RUNTIME_ERR;
557
+ }
558
+ function collectRepeatedKv(rest, flag) {
559
+ const entries = {};
560
+ const remaining = [];
561
+ for (let i = 0; i < rest.length; i++) {
562
+ const arg = rest[i];
563
+ if (arg === flag) {
564
+ const kv = rest[++i];
565
+ if (kv === void 0) {
566
+ return { entries, remaining, error: `${flag} requires a KEY=VALUE argument` };
567
+ }
568
+ const eq = kv.indexOf("=");
569
+ if (eq <= 0) {
570
+ return { entries, remaining, error: `${flag} must be in the form KEY=VALUE (got: ${kv})` };
571
+ }
572
+ entries[kv.slice(0, eq)] = kv.slice(eq + 1);
573
+ continue;
574
+ }
575
+ remaining.push(arg);
82
576
  }
83
- const sub = args[0];
84
- const rest = args.slice(1);
85
- switch (sub) {
86
- case "proxy":
87
- return await runProxy(io2, rest);
88
- default:
89
- io2.stderr(`unknown subcommand: ${sub}
90
- `);
91
- io2.stderr("run `antpath --help` for usage\n");
92
- return USAGE_ERR;
577
+ return { entries, remaining, error: null };
578
+ }
579
+ function collectRepeated(rest, flag) {
580
+ const values = [];
581
+ const remaining = [];
582
+ for (let i = 0; i < rest.length; i++) {
583
+ const arg = rest[i];
584
+ if (arg === flag) {
585
+ const v = rest[++i];
586
+ if (v === void 0) {
587
+ return { values, remaining, error: `${flag} requires a value` };
588
+ }
589
+ values.push(v);
590
+ continue;
591
+ }
592
+ remaining.push(arg);
93
593
  }
594
+ return { values, remaining, error: null };
94
595
  }
95
- async function printGlobalHelp(io2) {
96
- const manifest = await tryReadManifest(io2);
97
- io2.stdout("antpath \u2014 managed proxy CLI for skill scripts\n\n");
98
- io2.stdout("Usage:\n");
99
- io2.stdout(" antpath proxy <endpoint-name> [flags]\n");
100
- io2.stdout(" antpath --help\n\n");
101
- if (manifest) {
102
- if (manifest.endpoints.length === 0) {
103
- io2.stdout("This run declared no proxy endpoints.\n");
104
- } else {
105
- io2.stdout("Declared proxy endpoints for this run:\n");
106
- for (const ep of manifest.endpoints) {
107
- io2.stdout(` \u2022 ${ep.name} (${ep.allowMethods.join("/")} ${ep.allowPathPrefixes.join(",")}, mode=${ep.responseMode})
108
- `);
596
+ function takeFlagValue(rest, flag) {
597
+ let value = null;
598
+ const remaining = [];
599
+ for (let i = 0; i < rest.length; i++) {
600
+ const arg = rest[i];
601
+ if (arg === flag) {
602
+ const v = rest[++i];
603
+ if (v === void 0) {
604
+ return { value, remaining, error: `${flag} requires a value` };
109
605
  }
606
+ value = v;
607
+ continue;
110
608
  }
111
- io2.stdout(`
112
- Protocol version: ${manifest.protocolVersion}
113
- `);
114
- } else {
115
- io2.stdout("(no manifest mounted \u2014 run `antpath proxy --help` for details)\n");
609
+ remaining.push(arg);
116
610
  }
117
- return SUCCESS;
611
+ return { value, remaining, error: null };
118
612
  }
119
- async function printProxyHelp(io2) {
120
- io2.stdout("antpath proxy \u2014 call an upstream HTTP endpoint via the managed proxy.\n\n");
121
- io2.stdout("Usage:\n");
122
- io2.stdout(" antpath proxy <endpoint-name> [flags]\n\n");
123
- io2.stdout("Flags:\n");
124
- io2.stdout(" --method <verb> HTTP method (default: GET)\n");
125
- io2.stdout(" --path <path> Caller-supplied path; must match policy prefixes\n");
126
- io2.stdout(` --query <json> JSON object of query parameters (e.g. '{"q":"x"}')
127
- `);
128
- io2.stdout(" --header K=V Add a caller header (repeatable)\n");
129
- io2.stdout(" --data <value> Request body. Use '-' for stdin, '@<file>' for file content\n");
130
- io2.stdout(" --response-mode <mode> status_only | headers_only | full (may only narrow policy)\n");
131
- io2.stdout(" --help Show this message\n\n");
132
- const manifest = await tryReadManifest(io2);
133
- if (manifest && manifest.endpoints.length > 0) {
134
- io2.stdout("Declared endpoints:\n");
135
- for (const ep of manifest.endpoints) {
136
- io2.stdout(` \u2022 ${ep.name}: ${ep.allowMethods.join(",")} ${ep.allowPathPrefixes.join(",")} (mode=${ep.responseMode}, budget=${ep.perCallBudget}/run)
137
- `);
613
+ function takeBooleanFlag(rest, flag) {
614
+ const remaining = [];
615
+ let present = false;
616
+ for (const arg of rest) {
617
+ if (arg === flag) {
618
+ present = true;
619
+ continue;
138
620
  }
621
+ remaining.push(arg);
139
622
  }
140
- return SUCCESS;
623
+ return { present, remaining };
141
624
  }
625
+
626
+ // dist/proxy.js
142
627
  function parseProxyFlags(rest) {
143
628
  let endpointName = null;
144
629
  let method = "GET";
@@ -202,6 +687,29 @@ function expect(arr, idx, flag) {
202
687
  }
203
688
  var CliUsageError = class extends Error {
204
689
  };
690
+ async function printProxyHelp(io2) {
691
+ io2.stdout("antpath proxy \u2014 call an upstream HTTP endpoint via the managed proxy.\n\n");
692
+ io2.stdout("Usage:\n");
693
+ io2.stdout(" antpath proxy <endpoint-name> [flags]\n\n");
694
+ io2.stdout("Flags:\n");
695
+ io2.stdout(" --method <verb> HTTP method (default: GET)\n");
696
+ io2.stdout(" --path <path> Caller-supplied path; must match policy prefixes\n");
697
+ io2.stdout(` --query <json> JSON object of query parameters (e.g. '{"q":"x"}')
698
+ `);
699
+ io2.stdout(" --header K=V Add a caller header (repeatable)\n");
700
+ io2.stdout(" --data <value> Request body. Use '-' for stdin, '@<file>' for file content\n");
701
+ io2.stdout(" --response-mode <mode> status_only | headers_only | full (may only narrow policy)\n");
702
+ io2.stdout(" --help Show this message\n\n");
703
+ const manifest = await tryReadManifest(io2);
704
+ if (manifest && manifest.endpoints.length > 0) {
705
+ io2.stdout("Declared endpoints:\n");
706
+ for (const ep of manifest.endpoints) {
707
+ io2.stdout(` \u2022 ${ep.name}: ${ep.allowMethods.join(",")} ${ep.allowPathPrefixes.join(",")} (mode=${ep.responseMode}, budget=${ep.perCallBudget}/run)
708
+ `);
709
+ }
710
+ }
711
+ return SUCCESS;
712
+ }
205
713
  async function runProxy(io2, rest) {
206
714
  let parsed;
207
715
  try {
@@ -355,13 +863,675 @@ async function tryReadManifest(io2) {
355
863
  }
356
864
  }
357
865
 
866
+ // dist/host/template.js
867
+ import { resolve as resolvePath } from "node:path";
868
+ import { pathToFileURL } from "node:url";
869
+ async function loadTemplate(io2, filePath, variables) {
870
+ const absPath = resolvePath(io2.cwd(), filePath);
871
+ const lower = absPath.toLowerCase();
872
+ if (lower.endsWith(".json")) {
873
+ const text = await io2.readFile(absPath);
874
+ const parsed = JSON.parse(text);
875
+ return { resolved: ensureResolved(parsed, variables) };
876
+ }
877
+ if (lower.endsWith(".js") || lower.endsWith(".mjs") || lower.endsWith(".ts")) {
878
+ const mod = await import(pathToFileURL(absPath).href);
879
+ if (!mod.default) {
880
+ throw new Error(`template module ${filePath} must export a default TemplateDefinition`);
881
+ }
882
+ return { resolved: ensureResolved(mod.default, variables) };
883
+ }
884
+ throw new Error(`unsupported template extension: ${filePath}. Use .json, .js, .mjs, or .ts.`);
885
+ }
886
+ function ensureResolved(value, variables) {
887
+ if (!value || typeof value !== "object") {
888
+ throw new Error("template must be an object");
889
+ }
890
+ const obj = value;
891
+ if (typeof obj.hash === "string" && obj.hash.length > 0) {
892
+ return value;
893
+ }
894
+ return compileTemplate(value, variables);
895
+ }
896
+
897
+ // dist/host/run-cmd.js
898
+ var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
899
+ "succeeded",
900
+ "failed",
901
+ "terminated",
902
+ "cancelled",
903
+ "canceled",
904
+ "cleaned_up"
905
+ ]);
906
+ async function runRunCmd(io2, argv) {
907
+ if (await refuseInsideManagedRun(io2, "run"))
908
+ return USAGE_ERR;
909
+ const common = parseCommonHostFlags(argv);
910
+ if (!common.ok) {
911
+ io2.stderr(`${common.reason}
912
+ `);
913
+ return USAGE_ERR;
914
+ }
915
+ let rest = common.rest;
916
+ const anthropicKey = takeFlagValue(rest, "--anthropic-api-key");
917
+ if (anthropicKey.error) {
918
+ io2.stderr(`${anthropicKey.error}
919
+ `);
920
+ return USAGE_ERR;
921
+ }
922
+ rest = anthropicKey.remaining;
923
+ if (!anthropicKey.value) {
924
+ io2.stderr("--anthropic-api-key is required (the platform does not store provider keys on your behalf)\n");
925
+ return USAGE_ERR;
926
+ }
927
+ const idempotency = takeFlagValue(rest, "--idempotency-key");
928
+ if (idempotency.error) {
929
+ io2.stderr(`${idempotency.error}
930
+ `);
931
+ return USAGE_ERR;
932
+ }
933
+ rest = idempotency.remaining;
934
+ const cleanup = takeFlagValue(rest, "--cleanup");
935
+ if (cleanup.error) {
936
+ io2.stderr(`${cleanup.error}
937
+ `);
938
+ return USAGE_ERR;
939
+ }
940
+ rest = cleanup.remaining;
941
+ if (cleanup.value && cleanup.value !== "retain" && cleanup.value !== "delete") {
942
+ io2.stderr("--cleanup must be one of: retain, delete\n");
943
+ return USAGE_ERR;
944
+ }
945
+ const follow = takeBooleanFlag(rest, "--follow");
946
+ rest = follow.remaining;
947
+ const variables = collectRepeatedKv(rest, "--var");
948
+ if (variables.error) {
949
+ io2.stderr(`${variables.error}
950
+ `);
951
+ return USAGE_ERR;
952
+ }
953
+ rest = variables.remaining;
954
+ const mcpServerEntries = collectRepeated(rest, "--mcp-server");
955
+ if (mcpServerEntries.error) {
956
+ io2.stderr(`${mcpServerEntries.error}
957
+ `);
958
+ return USAGE_ERR;
959
+ }
960
+ rest = mcpServerEntries.remaining;
961
+ const skillEntries = collectRepeated(rest, "--skill");
962
+ if (skillEntries.error) {
963
+ io2.stderr(`${skillEntries.error}
964
+ `);
965
+ return USAGE_ERR;
966
+ }
967
+ rest = skillEntries.remaining;
968
+ const proxyEndpointEntries = collectRepeated(rest, "--proxy-endpoint");
969
+ if (proxyEndpointEntries.error) {
970
+ io2.stderr(`${proxyEndpointEntries.error}
971
+ `);
972
+ return USAGE_ERR;
973
+ }
974
+ rest = proxyEndpointEntries.remaining;
975
+ const proxyAuthEntries = collectRepeatedKv(rest, "--proxy-auth");
976
+ if (proxyAuthEntries.error) {
977
+ io2.stderr(`${proxyAuthEntries.error}
978
+ `);
979
+ return USAGE_ERR;
980
+ }
981
+ rest = proxyAuthEntries.remaining;
982
+ const positional = rest.filter((a) => !a.startsWith("--"));
983
+ const unknownFlags = rest.filter((a) => a.startsWith("--"));
984
+ if (unknownFlags.length > 0) {
985
+ io2.stderr(`unknown flag: ${unknownFlags[0]}
986
+ `);
987
+ return USAGE_ERR;
988
+ }
989
+ if (positional.length !== 1) {
990
+ io2.stderr("usage: antpath run <template-path> [flags]\n");
991
+ return USAGE_ERR;
992
+ }
993
+ const templatePath = positional[0];
994
+ let resolved;
995
+ try {
996
+ const load = await loadTemplate(io2, templatePath, variables.entries);
997
+ resolved = load.resolved;
998
+ } catch (err) {
999
+ io2.stderr(`failed to load template: ${err.message}
1000
+ `);
1001
+ return USAGE_ERR;
1002
+ }
1003
+ let mcpServers;
1004
+ try {
1005
+ mcpServers = mcpServerEntries.values.map((raw, i) => parseJsonOrThrow(raw, `--mcp-server[${i}]`));
1006
+ } catch (err) {
1007
+ io2.stderr(`${err.message}
1008
+ `);
1009
+ return USAGE_ERR;
1010
+ }
1011
+ let skills;
1012
+ try {
1013
+ skills = skillEntries.values.map((raw, i) => parseSkillFlag(raw, i));
1014
+ } catch (err) {
1015
+ io2.stderr(`${err.message}
1016
+ `);
1017
+ return USAGE_ERR;
1018
+ }
1019
+ let proxyEndpoints;
1020
+ try {
1021
+ proxyEndpoints = proxyEndpointEntries.values.map((raw, i) => parseJsonOrThrow(raw, `--proxy-endpoint[${i}]`));
1022
+ } catch (err) {
1023
+ io2.stderr(`${err.message}
1024
+ `);
1025
+ return USAGE_ERR;
1026
+ }
1027
+ const proxyAuth = [];
1028
+ for (const [name, spec] of Object.entries(proxyAuthEntries.entries)) {
1029
+ const parsed = parseProxyAuth(spec);
1030
+ if (!parsed.ok) {
1031
+ io2.stderr(`--proxy-auth ${name}: ${parsed.reason}
1032
+ `);
1033
+ return USAGE_ERR;
1034
+ }
1035
+ proxyAuth.push({ name, value: parsed.value });
1036
+ }
1037
+ if (proxyEndpoints.length > 0) {
1038
+ try {
1039
+ validateProxyAuth(proxyEndpoints, proxyAuth);
1040
+ } catch (err) {
1041
+ io2.stderr(`proxy auth validation failed: ${err.message}
1042
+ `);
1043
+ return USAGE_ERR;
1044
+ }
1045
+ }
1046
+ const secrets = {
1047
+ anthropic: { apiKey: anthropicKey.value },
1048
+ ...mcpServers.length ? { mcpServers } : {},
1049
+ ...skills.length ? { skills } : {},
1050
+ ...proxyAuth.length ? { proxyEndpointAuth: proxyAuth } : {}
1051
+ };
1052
+ const submission = {
1053
+ workspaceId: common.flags.workspaceId,
1054
+ idempotencyKey: idempotency.value ?? generateIdempotencyKey(),
1055
+ template: toPlatformSubmissionTemplate(resolved),
1056
+ secrets,
1057
+ ...cleanup.value ? { cleanup: { session: cleanup.value } } : {},
1058
+ ...proxyEndpoints.length ? { proxyEndpoints } : {}
1059
+ };
1060
+ const http = makeHttpClient(io2, common.flags);
1061
+ let run;
1062
+ try {
1063
+ run = await operations_exports.submitRun(http, submission);
1064
+ } catch (err) {
1065
+ return emitJsonError(io2, "submit_failed", err.message ?? "submission failed");
1066
+ }
1067
+ io2.stdout(JSON.stringify(run) + "\n");
1068
+ if (!follow.present)
1069
+ return SUCCESS;
1070
+ let emittedEventCount = 0;
1071
+ let currentStatus = run.status;
1072
+ while (!TERMINAL_STATUSES.has(currentStatus)) {
1073
+ await sleep(2e3);
1074
+ try {
1075
+ const events = await operations_exports.listRunEvents(http, common.flags.workspaceId, run.id);
1076
+ for (let i = emittedEventCount; i < events.length; i++) {
1077
+ io2.stdout(JSON.stringify(events[i]) + "\n");
1078
+ }
1079
+ emittedEventCount = events.length;
1080
+ } catch (err) {
1081
+ io2.stderr(`(transient) event poll failed: ${err.message}
1082
+ `);
1083
+ }
1084
+ try {
1085
+ const updated = await operations_exports.getRun(http, common.flags.workspaceId, run.id);
1086
+ currentStatus = updated.status;
1087
+ } catch (err) {
1088
+ io2.stderr(`(transient) status poll failed: ${err.message}
1089
+ `);
1090
+ }
1091
+ }
1092
+ try {
1093
+ const final = await operations_exports.getRun(http, common.flags.workspaceId, run.id);
1094
+ io2.stdout(JSON.stringify(final) + "\n");
1095
+ return final.status === "succeeded" ? SUCCESS : RUNTIME_ERR;
1096
+ } catch (err) {
1097
+ io2.stderr(`final status fetch failed: ${err.message}
1098
+ `);
1099
+ return RUNTIME_ERR;
1100
+ }
1101
+ }
1102
+ function parseProxyAuth(spec) {
1103
+ const idx = spec.indexOf(":");
1104
+ if (idx <= 0) {
1105
+ return { ok: false, reason: `expected '<type>:<value>' (got: ${spec})` };
1106
+ }
1107
+ const type = spec.slice(0, idx);
1108
+ const rest = spec.slice(idx + 1);
1109
+ switch (type) {
1110
+ case "bearer":
1111
+ if (!rest)
1112
+ return { ok: false, reason: "bearer requires a token value" };
1113
+ return { ok: true, value: { type: "bearer", token: rest } };
1114
+ case "header":
1115
+ if (!rest)
1116
+ return { ok: false, reason: "header requires a value" };
1117
+ return { ok: true, value: { type: "header", value: rest } };
1118
+ case "query":
1119
+ if (!rest)
1120
+ return { ok: false, reason: "query requires a value" };
1121
+ return { ok: true, value: { type: "query", value: rest } };
1122
+ case "basic": {
1123
+ const sep = rest.indexOf(":");
1124
+ if (sep <= 0 || sep >= rest.length - 1) {
1125
+ return { ok: false, reason: "basic requires <username>:<password>" };
1126
+ }
1127
+ return {
1128
+ ok: true,
1129
+ value: { type: "basic", username: rest.slice(0, sep), password: rest.slice(sep + 1) }
1130
+ };
1131
+ }
1132
+ default:
1133
+ return { ok: false, reason: `unknown auth type '${type}' (expected bearer|basic|header|query)` };
1134
+ }
1135
+ }
1136
+ function parseSkillFlag(raw, idx) {
1137
+ if (raw.trim().startsWith("{")) {
1138
+ return parseJsonOrThrow(raw, `--skill[${idx}]`);
1139
+ }
1140
+ const sep = raw.indexOf(":");
1141
+ if (sep === -1) {
1142
+ return { skillId: raw };
1143
+ }
1144
+ const skillId = raw.slice(0, sep);
1145
+ const version = raw.slice(sep + 1);
1146
+ if (!skillId || !version) {
1147
+ throw new Error(`--skill[${idx}] must be 'skillId' or 'skillId:version' (got: ${raw})`);
1148
+ }
1149
+ return { skillId, version };
1150
+ }
1151
+ function parseJsonOrThrow(raw, label) {
1152
+ try {
1153
+ return JSON.parse(raw);
1154
+ } catch (err) {
1155
+ throw new Error(`${label} is not valid JSON: ${err.message}`);
1156
+ }
1157
+ }
1158
+ function generateIdempotencyKey() {
1159
+ const c = globalThis.crypto;
1160
+ if (c?.randomUUID)
1161
+ return c.randomUUID();
1162
+ return `idem-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
1163
+ }
1164
+ function sleep(ms) {
1165
+ return new Promise((resolve) => setTimeout(resolve, ms));
1166
+ }
1167
+
1168
+ // dist/host/status.js
1169
+ async function runStatusCmd(io2, argv) {
1170
+ if (await refuseInsideManagedRun(io2, "status"))
1171
+ return USAGE_ERR;
1172
+ const common = parseCommonHostFlags(argv);
1173
+ if (!common.ok) {
1174
+ io2.stderr(`${common.reason}
1175
+ `);
1176
+ return USAGE_ERR;
1177
+ }
1178
+ const positional = common.rest.filter((arg) => !arg.startsWith("--"));
1179
+ if (positional.length !== 1) {
1180
+ io2.stderr("usage: antpath status <run-id> [common flags]\n");
1181
+ return USAGE_ERR;
1182
+ }
1183
+ const runId = positional[0];
1184
+ const http = makeHttpClient(io2, common.flags);
1185
+ try {
1186
+ const run = await operations_exports.getRun(http, common.flags.workspaceId, runId);
1187
+ io2.stdout(JSON.stringify(run) + "\n");
1188
+ return SUCCESS;
1189
+ } catch (err) {
1190
+ return emitJsonError(io2, "status_failed", err.message ?? "status fetch failed", { runId });
1191
+ }
1192
+ }
1193
+
1194
+ // dist/host/events.js
1195
+ var TERMINAL_STATUSES2 = /* @__PURE__ */ new Set([
1196
+ "succeeded",
1197
+ "failed",
1198
+ "terminated",
1199
+ "cancelled",
1200
+ "canceled",
1201
+ "cleaned_up"
1202
+ ]);
1203
+ async function runEventsCmd(io2, argv) {
1204
+ if (await refuseInsideManagedRun(io2, "events"))
1205
+ return USAGE_ERR;
1206
+ const common = parseCommonHostFlags(argv);
1207
+ if (!common.ok) {
1208
+ io2.stderr(`${common.reason}
1209
+ `);
1210
+ return USAGE_ERR;
1211
+ }
1212
+ const followResult = takeBooleanFlag(common.rest, "--follow");
1213
+ const positional = followResult.remaining.filter((arg) => !arg.startsWith("--"));
1214
+ if (positional.length !== 1) {
1215
+ io2.stderr("usage: antpath events <run-id> [--follow] [common flags]\n");
1216
+ return USAGE_ERR;
1217
+ }
1218
+ const runId = positional[0];
1219
+ const http = makeHttpClient(io2, common.flags);
1220
+ if (!followResult.present) {
1221
+ try {
1222
+ const events = await operations_exports.listRunEvents(http, common.flags.workspaceId, runId);
1223
+ for (const event of events) {
1224
+ io2.stdout(JSON.stringify(event) + "\n");
1225
+ }
1226
+ return SUCCESS;
1227
+ } catch (err) {
1228
+ return emitJsonError(io2, "events_failed", err.message ?? "event fetch failed", { runId });
1229
+ }
1230
+ }
1231
+ let emittedCount = 0;
1232
+ while (true) {
1233
+ let events;
1234
+ try {
1235
+ events = await operations_exports.listRunEvents(http, common.flags.workspaceId, runId);
1236
+ } catch (err) {
1237
+ io2.stderr(`(transient) event poll failed: ${err.message}
1238
+ `);
1239
+ await sleep2(2e3);
1240
+ continue;
1241
+ }
1242
+ for (let i = emittedCount; i < events.length; i++) {
1243
+ io2.stdout(JSON.stringify(events[i]) + "\n");
1244
+ }
1245
+ emittedCount = events.length;
1246
+ try {
1247
+ const run = await operations_exports.getRun(http, common.flags.workspaceId, runId);
1248
+ if (TERMINAL_STATUSES2.has(run.status)) {
1249
+ return SUCCESS;
1250
+ }
1251
+ } catch (err) {
1252
+ io2.stderr(`(transient) status poll failed: ${err.message}
1253
+ `);
1254
+ }
1255
+ await sleep2(2e3);
1256
+ }
1257
+ }
1258
+ function sleep2(ms) {
1259
+ return new Promise((resolve) => setTimeout(resolve, ms));
1260
+ }
1261
+
1262
+ // dist/host/outputs.js
1263
+ async function runOutputsCmd(io2, argv) {
1264
+ if (await refuseInsideManagedRun(io2, "outputs"))
1265
+ return USAGE_ERR;
1266
+ const common = parseCommonHostFlags(argv);
1267
+ if (!common.ok) {
1268
+ io2.stderr(`${common.reason}
1269
+ `);
1270
+ return USAGE_ERR;
1271
+ }
1272
+ const positional = common.rest.filter((arg) => !arg.startsWith("--"));
1273
+ if (positional.length !== 1) {
1274
+ io2.stderr("usage: antpath outputs <run-id> [common flags]\n");
1275
+ return USAGE_ERR;
1276
+ }
1277
+ const runId = positional[0];
1278
+ const http = makeHttpClient(io2, common.flags);
1279
+ try {
1280
+ const outputs = await operations_exports.listOutputs(http, common.flags.workspaceId, runId);
1281
+ for (const out of outputs) {
1282
+ io2.stdout(JSON.stringify(out) + "\n");
1283
+ }
1284
+ return SUCCESS;
1285
+ } catch (err) {
1286
+ return emitJsonError(io2, "outputs_failed", err.message ?? "outputs fetch failed", { runId });
1287
+ }
1288
+ }
1289
+
1290
+ // dist/host/download.js
1291
+ import { resolve as resolvePath2, basename } from "node:path";
1292
+ async function runDownloadCmd(io2, argv) {
1293
+ if (await refuseInsideManagedRun(io2, "download"))
1294
+ return USAGE_ERR;
1295
+ const common = parseCommonHostFlags(argv);
1296
+ if (!common.ok) {
1297
+ io2.stderr(`${common.reason}
1298
+ `);
1299
+ return USAGE_ERR;
1300
+ }
1301
+ const outFlag = takeFlagValue(common.rest, "--out");
1302
+ if (outFlag.error) {
1303
+ io2.stderr(`${outFlag.error}
1304
+ `);
1305
+ return USAGE_ERR;
1306
+ }
1307
+ const positional = outFlag.remaining.filter((arg) => !arg.startsWith("--"));
1308
+ if (positional.length !== 2) {
1309
+ io2.stderr("usage: antpath download <run-id> <output-id> [--out path] [common flags]\n");
1310
+ return USAGE_ERR;
1311
+ }
1312
+ const runId = positional[0];
1313
+ const outputId = positional[1];
1314
+ const http = makeHttpClient(io2, common.flags);
1315
+ let link;
1316
+ try {
1317
+ link = await operations_exports.createOutputLink(http, common.flags.workspaceId, runId, outputId);
1318
+ } catch (err) {
1319
+ return emitJsonError(io2, "link_failed", err.message ?? "create link failed", { runId, outputId });
1320
+ }
1321
+ let response;
1322
+ try {
1323
+ response = await io2.fetchImpl(link.url, { method: "GET", redirect: "follow" });
1324
+ } catch (err) {
1325
+ return emitJsonError(io2, "download_failed", `download fetch failed: ${err.message}`, { runId, outputId });
1326
+ }
1327
+ if (!response.ok) {
1328
+ return emitJsonError(io2, "download_failed", `download HTTP ${response.status}`, { runId, outputId });
1329
+ }
1330
+ const buffer = new Uint8Array(await response.arrayBuffer());
1331
+ const destination = resolveDestination(io2, outFlag.value, outputId, link.url);
1332
+ try {
1333
+ await io2.writeFile(destination, buffer);
1334
+ } catch (err) {
1335
+ return emitJsonError(io2, "write_failed", `failed to write output: ${err.message}`, { destination });
1336
+ }
1337
+ io2.stdout(JSON.stringify({ runId, outputId, path: destination, bytes: buffer.byteLength }) + "\n");
1338
+ return SUCCESS;
1339
+ }
1340
+ function resolveDestination(io2, out, outputId, signedUrl) {
1341
+ if (out) {
1342
+ return resolvePath2(io2.cwd(), out);
1343
+ }
1344
+ let fileName = `${outputId}`;
1345
+ try {
1346
+ const url = new URL(signedUrl);
1347
+ const tail = basename(url.pathname);
1348
+ if (tail)
1349
+ fileName = tail;
1350
+ } catch {
1351
+ }
1352
+ return resolvePath2(io2.cwd(), fileName);
1353
+ }
1354
+
1355
+ // dist/host/cancel.js
1356
+ async function runCancelCmd(io2, argv) {
1357
+ if (await refuseInsideManagedRun(io2, "cancel"))
1358
+ return USAGE_ERR;
1359
+ const common = parseCommonHostFlags(argv);
1360
+ if (!common.ok) {
1361
+ io2.stderr(`${common.reason}
1362
+ `);
1363
+ return USAGE_ERR;
1364
+ }
1365
+ const positional = common.rest.filter((arg) => !arg.startsWith("--"));
1366
+ if (positional.length !== 1) {
1367
+ io2.stderr("usage: antpath cancel <run-id> [common flags]\n");
1368
+ return USAGE_ERR;
1369
+ }
1370
+ const runId = positional[0];
1371
+ const http = makeHttpClient(io2, common.flags);
1372
+ try {
1373
+ await operations_exports.cancelRun(http, common.flags.workspaceId, runId);
1374
+ io2.stdout(JSON.stringify({ runId, status: "cancel_requested" }) + "\n");
1375
+ return SUCCESS;
1376
+ } catch (err) {
1377
+ return emitJsonError(io2, "cancel_failed", err.message ?? "cancel failed", { runId });
1378
+ }
1379
+ }
1380
+
1381
+ // dist/host/delete.js
1382
+ async function runDeleteCmd(io2, argv) {
1383
+ if (await refuseInsideManagedRun(io2, "delete"))
1384
+ return USAGE_ERR;
1385
+ const common = parseCommonHostFlags(argv);
1386
+ if (!common.ok) {
1387
+ io2.stderr(`${common.reason}
1388
+ `);
1389
+ return USAGE_ERR;
1390
+ }
1391
+ const positional = common.rest.filter((arg) => !arg.startsWith("--"));
1392
+ if (positional.length !== 1) {
1393
+ io2.stderr("usage: antpath delete <run-id> [common flags]\n");
1394
+ return USAGE_ERR;
1395
+ }
1396
+ const runId = positional[0];
1397
+ const http = makeHttpClient(io2, common.flags);
1398
+ try {
1399
+ await operations_exports.deleteRun(http, common.flags.workspaceId, runId);
1400
+ io2.stdout(JSON.stringify({ runId, deleted: true }) + "\n");
1401
+ return SUCCESS;
1402
+ } catch (err) {
1403
+ return emitJsonError(io2, "delete_failed", err.message ?? "delete failed", { runId });
1404
+ }
1405
+ }
1406
+
1407
+ // dist/host/whoami.js
1408
+ async function runWhoamiCmd(io2, argv) {
1409
+ if (await refuseInsideManagedRun(io2, "whoami"))
1410
+ return USAGE_ERR;
1411
+ const common = parseCommonHostFlags(argv, { requireWorkspace: false });
1412
+ if (!common.ok) {
1413
+ io2.stderr(`${common.reason}
1414
+ `);
1415
+ return USAGE_ERR;
1416
+ }
1417
+ if (common.rest.length > 0) {
1418
+ io2.stderr(`unexpected arguments: ${common.rest.join(" ")}
1419
+ `);
1420
+ return USAGE_ERR;
1421
+ }
1422
+ const http = makeHttpClient(io2, common.flags);
1423
+ try {
1424
+ const me = await operations_exports.whoami(http);
1425
+ io2.stdout(JSON.stringify(me) + "\n");
1426
+ return SUCCESS;
1427
+ } catch (err) {
1428
+ return emitJsonError(io2, "whoami_failed", err.message ?? "whoami failed");
1429
+ }
1430
+ }
1431
+
1432
+ // dist/run.js
1433
+ async function runCli(io2) {
1434
+ const args = io2.argv.slice(2);
1435
+ try {
1436
+ const exit = await dispatch(io2, args);
1437
+ io2.exit(exit.code);
1438
+ } catch (err) {
1439
+ const body = { error: "internal_error", message: err.message ?? "unknown error" };
1440
+ io2.stderr(JSON.stringify(body) + "\n");
1441
+ io2.exit(RUNTIME_ERR.code);
1442
+ }
1443
+ }
1444
+ async function dispatch(io2, args) {
1445
+ if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
1446
+ return printGlobalHelp(io2);
1447
+ }
1448
+ const sub = args[0];
1449
+ const rest = args.slice(1);
1450
+ switch (sub) {
1451
+ case "proxy":
1452
+ return runProxy(io2, rest);
1453
+ case "run":
1454
+ return runRunCmd(io2, rest);
1455
+ case "status":
1456
+ return runStatusCmd(io2, rest);
1457
+ case "events":
1458
+ return runEventsCmd(io2, rest);
1459
+ case "outputs":
1460
+ return runOutputsCmd(io2, rest);
1461
+ case "download":
1462
+ return runDownloadCmd(io2, rest);
1463
+ case "cancel":
1464
+ return runCancelCmd(io2, rest);
1465
+ case "delete":
1466
+ return runDeleteCmd(io2, rest);
1467
+ case "whoami":
1468
+ return runWhoamiCmd(io2, rest);
1469
+ default:
1470
+ io2.stderr(`unknown subcommand: ${sub}
1471
+ `);
1472
+ io2.stderr("run `antpath --help` for usage\n");
1473
+ return USAGE_ERR;
1474
+ }
1475
+ }
1476
+ async function printGlobalHelp(io2) {
1477
+ const manifest = await tryReadManifest(io2);
1478
+ if (manifest) {
1479
+ io2.stdout("antpath \u2014 in-container CLI for managed run sessions\n\n");
1480
+ io2.stdout("Usage:\n");
1481
+ io2.stdout(" antpath proxy <endpoint-name> [flags]\n");
1482
+ io2.stdout(" antpath proxy --help\n\n");
1483
+ if (manifest.endpoints.length === 0) {
1484
+ io2.stdout("This run declared no proxy endpoints.\n");
1485
+ } else {
1486
+ io2.stdout("Declared proxy endpoints for this run:\n");
1487
+ for (const ep of manifest.endpoints) {
1488
+ io2.stdout(` \u2022 ${ep.name} (${ep.allowMethods.join("/")} ${ep.allowPathPrefixes.join(",")}, mode=${ep.responseMode})
1489
+ `);
1490
+ }
1491
+ }
1492
+ io2.stdout(`
1493
+ Protocol version: ${manifest.protocolVersion}
1494
+ `);
1495
+ return SUCCESS;
1496
+ }
1497
+ io2.stdout("antpath \u2014 unified CLI for the antpath platform (mirrors the SDK 1:1)\n\n");
1498
+ io2.stdout("Usage:\n");
1499
+ io2.stdout(" antpath run <template-path> --api-token T --workspace W --dashboard-url U [flags]\n");
1500
+ io2.stdout(" antpath status <run-id> --api-token T --workspace W --dashboard-url U\n");
1501
+ io2.stdout(" antpath events <run-id> [--follow] --api-token T --workspace W --dashboard-url U\n");
1502
+ io2.stdout(" antpath outputs <run-id> --api-token T --workspace W --dashboard-url U\n");
1503
+ io2.stdout(" antpath download <run-id> <output-id> [--out path] --api-token T --workspace W --dashboard-url U\n");
1504
+ io2.stdout(" antpath cancel <run-id> --api-token T --workspace W --dashboard-url U\n");
1505
+ io2.stdout(" antpath delete <run-id> --api-token T --workspace W --dashboard-url U\n");
1506
+ io2.stdout(" antpath whoami --api-token T --dashboard-url U\n");
1507
+ io2.stdout(" antpath --help\n\n");
1508
+ io2.stdout("Required flags on every host subcommand:\n");
1509
+ io2.stdout(" --api-token <token> Workspace-scoped antpath SDK API token\n");
1510
+ io2.stdout(" --workspace <id-or-slug> Workspace this call targets (omit for whoami)\n");
1511
+ io2.stdout(" --dashboard-url <url> Dashboard BFF root, e.g. https://antpath.example.com\n\n");
1512
+ io2.stdout("Submit flags (antpath run):\n");
1513
+ io2.stdout(" --anthropic-api-key <key> REQUIRED \u2014 provider key (never stored)\n");
1514
+ io2.stdout(" --var name=value Template variable (repeatable)\n");
1515
+ io2.stdout(" --mcp-server '<json>' PlatformMcpServerSecret JSON (repeatable)\n");
1516
+ io2.stdout(" --skill <skillId>[:<ver>] Skill reference (repeatable)\n");
1517
+ io2.stdout(" --proxy-endpoint '<json>' PlatformProxyEndpoint JSON (repeatable)\n");
1518
+ io2.stdout(" --proxy-auth name=<spec> bearer:tok | basic:u:p | header:v | query:v (repeatable)\n");
1519
+ io2.stdout(" --cleanup retain|delete Session cleanup policy\n");
1520
+ io2.stdout(" --idempotency-key <key> Optional; defaults to a fresh UUID\n");
1521
+ io2.stdout(" --follow Poll events to stdout until the run terminates\n\n");
1522
+ io2.stdout("Template formats: .json, .js, .mjs, .ts (default export must be a TemplateDefinition).\n");
1523
+ return SUCCESS;
1524
+ }
1525
+
358
1526
  // dist/cli.js
359
1527
  var io = {
360
1528
  readFile: (path) => readFile(path, "utf8"),
1529
+ writeFile: (path, data) => writeFile(path, data),
361
1530
  fetchImpl: fetch,
362
1531
  stdout: (chunk) => process.stdout.write(chunk),
363
1532
  stderr: (chunk) => process.stderr.write(chunk),
364
1533
  exit: (code) => process.exit(code),
365
- argv: process.argv
1534
+ argv: process.argv,
1535
+ cwd: () => process.cwd()
366
1536
  };
367
1537
  await runCli(io);