antpath 0.3.1 → 0.4.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.
- package/README.md +13 -14
- package/dist/_shared/blueprint.d.ts +263 -0
- package/dist/_shared/blueprint.js +505 -0
- package/dist/_shared/http.d.ts +6 -1
- package/dist/_shared/http.js +10 -5
- package/dist/_shared/index.d.ts +1 -0
- package/dist/_shared/index.js +1 -0
- package/dist/_shared/operations.d.ts +32 -9
- package/dist/_shared/operations.js +73 -12
- package/dist/_shared/runtime-types.d.ts +30 -0
- package/dist/_shared/stable.d.ts +14 -0
- package/dist/_shared/stable.js +14 -0
- package/dist/_shared/submission.d.ts +55 -0
- package/dist/_shared/submission.js +135 -1
- package/dist/cli.mjs +114 -58
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +13 -6
- package/dist/client.js +17 -16
- package/dist/client.js.map +1 -1
- package/docs/credentials.md +1 -3
- package/docs/quickstart.md +4 -7
- package/docs/release.md +57 -12
- package/examples/mcp-static-bearer.ts +1 -3
- package/examples/quickstart.ts +1 -3
- package/package.json +2 -3
- package/references/architecture-decisions.md +0 -473
- package/references/implementation-plan.md +0 -452
- package/references/research-sources.md +0 -41
- package/references/testing-strategy.md +0 -29
package/dist/cli.mjs
CHANGED
|
@@ -52,6 +52,24 @@ var TERMINAL_RUN_STATUSES = [
|
|
|
52
52
|
];
|
|
53
53
|
var terminalRunStatuses = new Set(TERMINAL_RUN_STATUSES);
|
|
54
54
|
|
|
55
|
+
// ../shared/dist/blueprint.js
|
|
56
|
+
var SKILL_BUNDLE_LIMITS = {
|
|
57
|
+
/** Compressed (.zip) ceiling. */
|
|
58
|
+
maxCompressedBytes: 10 * 1024 * 1024,
|
|
59
|
+
/** Sum of uncompressed file sizes. */
|
|
60
|
+
maxDecompressedBytes: 50 * 1024 * 1024,
|
|
61
|
+
/** Number of regular file entries (directories don't count). */
|
|
62
|
+
maxFiles: 1e3,
|
|
63
|
+
/** Maximum directory nesting depth — `a/b/c/d` has depth 4. */
|
|
64
|
+
maxDepth: 16,
|
|
65
|
+
/** Single-entry path length cap. */
|
|
66
|
+
maxPathLength: 512,
|
|
67
|
+
/** Stored file mode for ordinary files. */
|
|
68
|
+
defaultFileMode: 420,
|
|
69
|
+
/** Stored directory mode. */
|
|
70
|
+
defaultDirMode: 493
|
|
71
|
+
};
|
|
72
|
+
|
|
55
73
|
// ../shared/dist/submission.js
|
|
56
74
|
var PROXY_ENDPOINT_DEFAULTS = {
|
|
57
75
|
allowHeaders: [],
|
|
@@ -65,6 +83,7 @@ var PROXY_ENDPOINT_DEFAULTS = {
|
|
|
65
83
|
|
|
66
84
|
// ../shared/dist/stable.js
|
|
67
85
|
import { createHash } from "node:crypto";
|
|
86
|
+
var ANTPATH_DEFAULT_BASE_URL = "https://antpath.ai";
|
|
68
87
|
function stableStringify(value) {
|
|
69
88
|
return JSON.stringify(sortValue(value));
|
|
70
89
|
}
|
|
@@ -329,13 +348,11 @@ var HttpClient = class {
|
|
|
329
348
|
#apiToken;
|
|
330
349
|
#fetch;
|
|
331
350
|
constructor(options) {
|
|
332
|
-
if (!options.baseUrl) {
|
|
333
|
-
throw new Error("HttpClient: baseUrl is required");
|
|
334
|
-
}
|
|
335
351
|
if (!options.apiToken) {
|
|
336
352
|
throw new Error("HttpClient: apiToken is required");
|
|
337
353
|
}
|
|
338
|
-
const
|
|
354
|
+
const raw = options.baseUrl ?? ANTPATH_DEFAULT_BASE_URL;
|
|
355
|
+
const normalized = raw.endsWith("/") ? raw : `${raw}/`;
|
|
339
356
|
this.#baseUrl = new URL(normalized);
|
|
340
357
|
this.#apiToken = options.apiToken;
|
|
341
358
|
this.#fetch = options.fetch ?? fetch;
|
|
@@ -351,7 +368,9 @@ var HttpClient = class {
|
|
|
351
368
|
...normalizeHeaders(init.headers)
|
|
352
369
|
};
|
|
353
370
|
if (init.body !== void 0 && init.body !== null && !headers["content-type"]) {
|
|
354
|
-
|
|
371
|
+
if (typeof init.body === "string") {
|
|
372
|
+
headers["content-type"] = "application/json";
|
|
373
|
+
}
|
|
355
374
|
}
|
|
356
375
|
const response = await this.#fetch(url, { ...init, headers });
|
|
357
376
|
const body = await readJson(response);
|
|
@@ -415,11 +434,16 @@ var operations_exports = {};
|
|
|
415
434
|
__export(operations_exports, {
|
|
416
435
|
cancelRun: () => cancelRun,
|
|
417
436
|
createOutputLink: () => createOutputLink,
|
|
437
|
+
createSkillBundle: () => createSkillBundle,
|
|
418
438
|
deleteRun: () => deleteRun,
|
|
439
|
+
deleteSkill: () => deleteSkill,
|
|
419
440
|
getRun: () => getRun,
|
|
441
|
+
getSkill: () => getSkill,
|
|
420
442
|
listOutputs: () => listOutputs,
|
|
421
443
|
listRunEvents: () => listRunEvents,
|
|
444
|
+
listSkills: () => listSkills,
|
|
422
445
|
submitRun: () => submitRun,
|
|
446
|
+
submitRunFlat: () => submitRunFlat,
|
|
423
447
|
whoami: () => whoami
|
|
424
448
|
});
|
|
425
449
|
async function submitRun(http, request) {
|
|
@@ -428,30 +452,72 @@ async function submitRun(http, request) {
|
|
|
428
452
|
body: JSON.stringify(request)
|
|
429
453
|
});
|
|
430
454
|
}
|
|
431
|
-
async function getRun(http,
|
|
432
|
-
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}
|
|
455
|
+
async function getRun(http, runId) {
|
|
456
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}`);
|
|
433
457
|
return hasRun(result) ? result.run : result;
|
|
434
458
|
}
|
|
435
|
-
async function listRunEvents(http,
|
|
436
|
-
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events
|
|
459
|
+
async function listRunEvents(http, runId) {
|
|
460
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events`);
|
|
437
461
|
return result.events;
|
|
438
462
|
}
|
|
439
|
-
async function listOutputs(http,
|
|
440
|
-
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs
|
|
463
|
+
async function listOutputs(http, runId) {
|
|
464
|
+
const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`);
|
|
441
465
|
return result.outputs;
|
|
442
466
|
}
|
|
443
|
-
async function createOutputLink(http,
|
|
444
|
-
return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" }
|
|
467
|
+
async function createOutputLink(http, runId, outputId) {
|
|
468
|
+
return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" });
|
|
445
469
|
}
|
|
446
|
-
async function cancelRun(http,
|
|
447
|
-
await http.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" }
|
|
470
|
+
async function cancelRun(http, runId) {
|
|
471
|
+
await http.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" });
|
|
448
472
|
}
|
|
449
|
-
async function deleteRun(http,
|
|
450
|
-
await http.request(`/api/runs/${encodeURIComponent(runId)}`, { method: "DELETE" }
|
|
473
|
+
async function deleteRun(http, runId) {
|
|
474
|
+
await http.request(`/api/runs/${encodeURIComponent(runId)}`, { method: "DELETE" });
|
|
451
475
|
}
|
|
452
476
|
async function whoami(http) {
|
|
453
477
|
return http.request("/api/whoami");
|
|
454
478
|
}
|
|
479
|
+
async function submitRunFlat(http, request) {
|
|
480
|
+
return http.request("/api/runs", {
|
|
481
|
+
method: "POST",
|
|
482
|
+
body: JSON.stringify(request)
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
async function createSkillBundle(http, args) {
|
|
486
|
+
const form = new FormData();
|
|
487
|
+
form.append("name", args.name);
|
|
488
|
+
const blobBody = toBlob(args.body, args.contentType ?? "application/zip");
|
|
489
|
+
form.append("bundle", blobBody, args.filename ?? `${args.name}.zip`);
|
|
490
|
+
return http.request("/api/skills", {
|
|
491
|
+
method: "POST",
|
|
492
|
+
body: form
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
async function listSkills(http) {
|
|
496
|
+
const result = await http.request("/api/skills");
|
|
497
|
+
if (Array.isArray(result)) {
|
|
498
|
+
return result;
|
|
499
|
+
}
|
|
500
|
+
return result.skills;
|
|
501
|
+
}
|
|
502
|
+
async function getSkill(http, skillId) {
|
|
503
|
+
return http.request(`/api/skills/${encodeURIComponent(skillId)}`);
|
|
504
|
+
}
|
|
505
|
+
async function deleteSkill(http, skillId) {
|
|
506
|
+
await http.request(`/api/skills/${encodeURIComponent(skillId)}`, {
|
|
507
|
+
method: "DELETE"
|
|
508
|
+
});
|
|
509
|
+
}
|
|
510
|
+
function toBlob(input, contentType) {
|
|
511
|
+
if (input instanceof Blob) {
|
|
512
|
+
return input;
|
|
513
|
+
}
|
|
514
|
+
if (input instanceof Uint8Array) {
|
|
515
|
+
const copy = new Uint8Array(input.byteLength);
|
|
516
|
+
copy.set(input);
|
|
517
|
+
return new Blob([copy.buffer], { type: contentType });
|
|
518
|
+
}
|
|
519
|
+
return new Blob([input], { type: contentType });
|
|
520
|
+
}
|
|
455
521
|
function hasRun(value) {
|
|
456
522
|
return Boolean(value && typeof value === "object" && "run" in value);
|
|
457
523
|
}
|
|
@@ -489,10 +555,8 @@ var ANTPATH_RUN_TOKEN_PATH = "/antpath/run-token";
|
|
|
489
555
|
var SUCCESS = { code: 0 };
|
|
490
556
|
var USAGE_ERR = { code: 2 };
|
|
491
557
|
var RUNTIME_ERR = { code: 1 };
|
|
492
|
-
function parseCommonHostFlags(argv
|
|
493
|
-
const requireWorkspace = options.requireWorkspace ?? true;
|
|
558
|
+
function parseCommonHostFlags(argv) {
|
|
494
559
|
let apiToken = null;
|
|
495
|
-
let workspaceId = null;
|
|
496
560
|
let dashboardUrl = null;
|
|
497
561
|
const rest = [];
|
|
498
562
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -504,13 +568,6 @@ function parseCommonHostFlags(argv, options = {}) {
|
|
|
504
568
|
apiToken = v;
|
|
505
569
|
continue;
|
|
506
570
|
}
|
|
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
571
|
if (arg === "--dashboard-url") {
|
|
515
572
|
const v = argv[++i];
|
|
516
573
|
if (v === void 0)
|
|
@@ -518,18 +575,19 @@ function parseCommonHostFlags(argv, options = {}) {
|
|
|
518
575
|
dashboardUrl = v;
|
|
519
576
|
continue;
|
|
520
577
|
}
|
|
578
|
+
if (arg === "--workspace" || arg === "--workspace-id") {
|
|
579
|
+
return {
|
|
580
|
+
ok: false,
|
|
581
|
+
reason: `unknown flag ${arg}: workspace is derived from --api-token on the server; drop this flag`
|
|
582
|
+
};
|
|
583
|
+
}
|
|
521
584
|
rest.push(arg);
|
|
522
585
|
}
|
|
523
586
|
if (!apiToken)
|
|
524
587
|
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
588
|
return {
|
|
531
589
|
ok: true,
|
|
532
|
-
flags: { apiToken,
|
|
590
|
+
flags: { apiToken, dashboardUrl: dashboardUrl ?? ANTPATH_DEFAULT_BASE_URL },
|
|
533
591
|
rest
|
|
534
592
|
};
|
|
535
593
|
}
|
|
@@ -1050,7 +1108,6 @@ async function runRunCmd(io2, argv) {
|
|
|
1050
1108
|
...proxyAuth.length ? { proxyEndpointAuth: proxyAuth } : {}
|
|
1051
1109
|
};
|
|
1052
1110
|
const submission = {
|
|
1053
|
-
workspaceId: common.flags.workspaceId,
|
|
1054
1111
|
idempotencyKey: idempotency.value ?? generateIdempotencyKey(),
|
|
1055
1112
|
template: toPlatformSubmissionTemplate(resolved),
|
|
1056
1113
|
secrets,
|
|
@@ -1072,7 +1129,7 @@ async function runRunCmd(io2, argv) {
|
|
|
1072
1129
|
while (!TERMINAL_STATUSES.has(currentStatus)) {
|
|
1073
1130
|
await sleep(2e3);
|
|
1074
1131
|
try {
|
|
1075
|
-
const events = await operations_exports.listRunEvents(http,
|
|
1132
|
+
const events = await operations_exports.listRunEvents(http, run.id);
|
|
1076
1133
|
for (let i = emittedEventCount; i < events.length; i++) {
|
|
1077
1134
|
io2.stdout(JSON.stringify(events[i]) + "\n");
|
|
1078
1135
|
}
|
|
@@ -1082,7 +1139,7 @@ async function runRunCmd(io2, argv) {
|
|
|
1082
1139
|
`);
|
|
1083
1140
|
}
|
|
1084
1141
|
try {
|
|
1085
|
-
const updated = await operations_exports.getRun(http,
|
|
1142
|
+
const updated = await operations_exports.getRun(http, run.id);
|
|
1086
1143
|
currentStatus = updated.status;
|
|
1087
1144
|
} catch (err) {
|
|
1088
1145
|
io2.stderr(`(transient) status poll failed: ${err.message}
|
|
@@ -1090,7 +1147,7 @@ async function runRunCmd(io2, argv) {
|
|
|
1090
1147
|
}
|
|
1091
1148
|
}
|
|
1092
1149
|
try {
|
|
1093
|
-
const final = await operations_exports.getRun(http,
|
|
1150
|
+
const final = await operations_exports.getRun(http, run.id);
|
|
1094
1151
|
io2.stdout(JSON.stringify(final) + "\n");
|
|
1095
1152
|
return final.status === "succeeded" ? SUCCESS : RUNTIME_ERR;
|
|
1096
1153
|
} catch (err) {
|
|
@@ -1183,7 +1240,7 @@ async function runStatusCmd(io2, argv) {
|
|
|
1183
1240
|
const runId = positional[0];
|
|
1184
1241
|
const http = makeHttpClient(io2, common.flags);
|
|
1185
1242
|
try {
|
|
1186
|
-
const run = await operations_exports.getRun(http,
|
|
1243
|
+
const run = await operations_exports.getRun(http, runId);
|
|
1187
1244
|
io2.stdout(JSON.stringify(run) + "\n");
|
|
1188
1245
|
return SUCCESS;
|
|
1189
1246
|
} catch (err) {
|
|
@@ -1219,7 +1276,7 @@ async function runEventsCmd(io2, argv) {
|
|
|
1219
1276
|
const http = makeHttpClient(io2, common.flags);
|
|
1220
1277
|
if (!followResult.present) {
|
|
1221
1278
|
try {
|
|
1222
|
-
const events = await operations_exports.listRunEvents(http,
|
|
1279
|
+
const events = await operations_exports.listRunEvents(http, runId);
|
|
1223
1280
|
for (const event of events) {
|
|
1224
1281
|
io2.stdout(JSON.stringify(event) + "\n");
|
|
1225
1282
|
}
|
|
@@ -1232,7 +1289,7 @@ async function runEventsCmd(io2, argv) {
|
|
|
1232
1289
|
while (true) {
|
|
1233
1290
|
let events;
|
|
1234
1291
|
try {
|
|
1235
|
-
events = await operations_exports.listRunEvents(http,
|
|
1292
|
+
events = await operations_exports.listRunEvents(http, runId);
|
|
1236
1293
|
} catch (err) {
|
|
1237
1294
|
io2.stderr(`(transient) event poll failed: ${err.message}
|
|
1238
1295
|
`);
|
|
@@ -1244,7 +1301,7 @@ async function runEventsCmd(io2, argv) {
|
|
|
1244
1301
|
}
|
|
1245
1302
|
emittedCount = events.length;
|
|
1246
1303
|
try {
|
|
1247
|
-
const run = await operations_exports.getRun(http,
|
|
1304
|
+
const run = await operations_exports.getRun(http, runId);
|
|
1248
1305
|
if (TERMINAL_STATUSES2.has(run.status)) {
|
|
1249
1306
|
return SUCCESS;
|
|
1250
1307
|
}
|
|
@@ -1277,7 +1334,7 @@ async function runOutputsCmd(io2, argv) {
|
|
|
1277
1334
|
const runId = positional[0];
|
|
1278
1335
|
const http = makeHttpClient(io2, common.flags);
|
|
1279
1336
|
try {
|
|
1280
|
-
const outputs = await operations_exports.listOutputs(http,
|
|
1337
|
+
const outputs = await operations_exports.listOutputs(http, runId);
|
|
1281
1338
|
for (const out of outputs) {
|
|
1282
1339
|
io2.stdout(JSON.stringify(out) + "\n");
|
|
1283
1340
|
}
|
|
@@ -1314,7 +1371,7 @@ async function runDownloadCmd(io2, argv) {
|
|
|
1314
1371
|
const http = makeHttpClient(io2, common.flags);
|
|
1315
1372
|
let link;
|
|
1316
1373
|
try {
|
|
1317
|
-
link = await operations_exports.createOutputLink(http,
|
|
1374
|
+
link = await operations_exports.createOutputLink(http, runId, outputId);
|
|
1318
1375
|
} catch (err) {
|
|
1319
1376
|
return emitJsonError(io2, "link_failed", err.message ?? "create link failed", { runId, outputId });
|
|
1320
1377
|
}
|
|
@@ -1370,7 +1427,7 @@ async function runCancelCmd(io2, argv) {
|
|
|
1370
1427
|
const runId = positional[0];
|
|
1371
1428
|
const http = makeHttpClient(io2, common.flags);
|
|
1372
1429
|
try {
|
|
1373
|
-
await operations_exports.cancelRun(http,
|
|
1430
|
+
await operations_exports.cancelRun(http, runId);
|
|
1374
1431
|
io2.stdout(JSON.stringify({ runId, status: "cancel_requested" }) + "\n");
|
|
1375
1432
|
return SUCCESS;
|
|
1376
1433
|
} catch (err) {
|
|
@@ -1396,7 +1453,7 @@ async function runDeleteCmd(io2, argv) {
|
|
|
1396
1453
|
const runId = positional[0];
|
|
1397
1454
|
const http = makeHttpClient(io2, common.flags);
|
|
1398
1455
|
try {
|
|
1399
|
-
await operations_exports.deleteRun(http,
|
|
1456
|
+
await operations_exports.deleteRun(http, runId);
|
|
1400
1457
|
io2.stdout(JSON.stringify({ runId, deleted: true }) + "\n");
|
|
1401
1458
|
return SUCCESS;
|
|
1402
1459
|
} catch (err) {
|
|
@@ -1408,7 +1465,7 @@ async function runDeleteCmd(io2, argv) {
|
|
|
1408
1465
|
async function runWhoamiCmd(io2, argv) {
|
|
1409
1466
|
if (await refuseInsideManagedRun(io2, "whoami"))
|
|
1410
1467
|
return USAGE_ERR;
|
|
1411
|
-
const common = parseCommonHostFlags(argv
|
|
1468
|
+
const common = parseCommonHostFlags(argv);
|
|
1412
1469
|
if (!common.ok) {
|
|
1413
1470
|
io2.stderr(`${common.reason}
|
|
1414
1471
|
`);
|
|
@@ -1496,19 +1553,18 @@ Protocol version: ${manifest.protocolVersion}
|
|
|
1496
1553
|
}
|
|
1497
1554
|
io2.stdout("antpath \u2014 unified CLI for the antpath platform (mirrors the SDK 1:1)\n\n");
|
|
1498
1555
|
io2.stdout("Usage:\n");
|
|
1499
|
-
io2.stdout(" antpath run <template-path> --api-token T
|
|
1500
|
-
io2.stdout(" antpath status <run-id> --api-token T
|
|
1501
|
-
io2.stdout(" antpath events <run-id> [--follow] --api-token T
|
|
1502
|
-
io2.stdout(" antpath outputs <run-id> --api-token T
|
|
1503
|
-
io2.stdout(" antpath download <run-id> <output-id> [--out path] --api-token T
|
|
1504
|
-
io2.stdout(" antpath cancel <run-id> --api-token T
|
|
1505
|
-
io2.stdout(" antpath delete <run-id> --api-token T
|
|
1506
|
-
io2.stdout(" antpath whoami --api-token T
|
|
1556
|
+
io2.stdout(" antpath run <template-path> --api-token T [flags]\n");
|
|
1557
|
+
io2.stdout(" antpath status <run-id> --api-token T\n");
|
|
1558
|
+
io2.stdout(" antpath events <run-id> [--follow] --api-token T\n");
|
|
1559
|
+
io2.stdout(" antpath outputs <run-id> --api-token T\n");
|
|
1560
|
+
io2.stdout(" antpath download <run-id> <output-id> [--out path] --api-token T\n");
|
|
1561
|
+
io2.stdout(" antpath cancel <run-id> --api-token T\n");
|
|
1562
|
+
io2.stdout(" antpath delete <run-id> --api-token T\n");
|
|
1563
|
+
io2.stdout(" antpath whoami --api-token T\n");
|
|
1507
1564
|
io2.stdout(" antpath --help\n\n");
|
|
1508
|
-
io2.stdout("
|
|
1509
|
-
io2.stdout(" --api-token <token>
|
|
1510
|
-
io2.stdout(" --
|
|
1511
|
-
io2.stdout(" --dashboard-url <url> Dashboard BFF root, e.g. https://antpath.example.com\n\n");
|
|
1565
|
+
io2.stdout("Common flags on every host subcommand:\n");
|
|
1566
|
+
io2.stdout(" --api-token <token> REQUIRED \u2014 antpath SDK API token (workspace is derived from it)\n");
|
|
1567
|
+
io2.stdout(" --dashboard-url <url> Optional; defaults to https://antpath.ai (set for self-hosted)\n\n");
|
|
1512
1568
|
io2.stdout("Submit flags (antpath run):\n");
|
|
1513
1569
|
io2.stdout(" --anthropic-api-key <key> REQUIRED \u2014 provider key (never stored)\n");
|
|
1514
1570
|
io2.stdout(" --var name=value Template variable (repeatable)\n");
|
package/dist/cli.mjs.sha256
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
2d4fdd070358ffea5d49c62d5cca10863da0fc6279a88fe78fa7f11eb6eb18d7 cli.mjs
|
package/dist/client.d.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import { type FetchLike, type Output, type PlatformInlineSecrets, type PlatformProxyEndpoint, type ResolvedTemplate, type Run, type RunEvent, type SignedOutputLink, type TemplateDefinition, type WhoAmI } from "./_shared/index.js";
|
|
2
2
|
export interface AntpathClientOptions {
|
|
3
|
-
/** Dashboard BFF root, e.g. `https://antpath.example.com`. */
|
|
4
|
-
readonly baseUrl: string;
|
|
5
3
|
/** Workspace-scoped SDK API token. */
|
|
6
4
|
readonly apiToken: string;
|
|
7
|
-
/**
|
|
8
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Dashboard BFF root, e.g. `https://antpath.example.com`. Optional —
|
|
7
|
+
* defaults to the canonical hosted URL (`https://antpath.ai`).
|
|
8
|
+
* Self-hosted deployments override; the default lives in source so
|
|
9
|
+
* the agent reading the SDK call site can see exactly where the call
|
|
10
|
+
* goes.
|
|
11
|
+
*/
|
|
12
|
+
readonly baseUrl?: string;
|
|
9
13
|
/** Optional `fetch` override for testing. */
|
|
10
14
|
readonly fetch?: FetchLike;
|
|
11
15
|
}
|
|
@@ -56,12 +60,15 @@ export declare class RunRef {
|
|
|
56
60
|
* powers the published `antpath` SDK and (under the hood) every host-side
|
|
57
61
|
* subcommand of the in-container `antpath` CLI. All operations talk to
|
|
58
62
|
* the dashboard BFF and operate on durable run records.
|
|
63
|
+
*
|
|
64
|
+
* The SDK never asks the caller for a workspace id — workspace identity
|
|
65
|
+
* is derived server-side from the API token on every request. Use
|
|
66
|
+
* `client.whoami()` if you want to introspect which workspace the
|
|
67
|
+
* token resolves to.
|
|
59
68
|
*/
|
|
60
69
|
export declare class AntpathClient {
|
|
61
70
|
#private;
|
|
62
71
|
constructor(options: AntpathClientOptions);
|
|
63
|
-
/** Workspace id this client is bound to (read-only). */
|
|
64
|
-
get workspaceId(): string;
|
|
65
72
|
/**
|
|
66
73
|
* Submit a run and wait for it to reach a terminal state. Returns the
|
|
67
74
|
* final `Run` record. For long-running flows, prefer `submitRun` +
|
package/dist/client.js
CHANGED
|
@@ -38,24 +38,23 @@ export class RunRef {
|
|
|
38
38
|
* powers the published `antpath` SDK and (under the hood) every host-side
|
|
39
39
|
* subcommand of the in-container `antpath` CLI. All operations talk to
|
|
40
40
|
* the dashboard BFF and operate on durable run records.
|
|
41
|
+
*
|
|
42
|
+
* The SDK never asks the caller for a workspace id — workspace identity
|
|
43
|
+
* is derived server-side from the API token on every request. Use
|
|
44
|
+
* `client.whoami()` if you want to introspect which workspace the
|
|
45
|
+
* token resolves to.
|
|
41
46
|
*/
|
|
42
47
|
export class AntpathClient {
|
|
43
48
|
#http;
|
|
44
|
-
#workspaceId;
|
|
45
49
|
constructor(options) {
|
|
46
|
-
if (!options.
|
|
47
|
-
throw new Error("AntpathClient:
|
|
50
|
+
if (!options.apiToken) {
|
|
51
|
+
throw new Error("AntpathClient: apiToken is required");
|
|
48
52
|
}
|
|
49
53
|
this.#http = new HttpClient({
|
|
50
|
-
baseUrl: options.baseUrl,
|
|
54
|
+
...(options.baseUrl ? { baseUrl: options.baseUrl } : {}),
|
|
51
55
|
apiToken: options.apiToken,
|
|
52
56
|
...(options.fetch ? { fetch: options.fetch } : {})
|
|
53
57
|
});
|
|
54
|
-
this.#workspaceId = options.workspaceId;
|
|
55
|
-
}
|
|
56
|
-
/** Workspace id this client is bound to (read-only). */
|
|
57
|
-
get workspaceId() {
|
|
58
|
-
return this.#workspaceId;
|
|
59
58
|
}
|
|
60
59
|
/**
|
|
61
60
|
* Submit a run and wait for it to reach a terminal state. Returns the
|
|
@@ -85,8 +84,10 @@ export class AntpathClient {
|
|
|
85
84
|
if (options.proxyEndpoints && options.proxyEndpoints.length > 0) {
|
|
86
85
|
validateProxyAuth(options.proxyEndpoints, options.secrets.proxyEndpointAuth);
|
|
87
86
|
}
|
|
87
|
+
// The BFF derives `workspaceId` from the API token; the SDK never
|
|
88
|
+
// names it. See `references/development-principles.md`
|
|
89
|
+
// (Agent-first surface design, Concrete rule 3).
|
|
88
90
|
const submission = {
|
|
89
|
-
workspaceId: this.#workspaceId,
|
|
90
91
|
idempotencyKey: options.idempotencyKey ?? generateIdempotencyKey(),
|
|
91
92
|
template: toPlatformSubmissionTemplate(template),
|
|
92
93
|
...(options.variables ? { variables: options.variables } : {}),
|
|
@@ -100,10 +101,10 @@ export class AntpathClient {
|
|
|
100
101
|
return new RunRef(this, run.id);
|
|
101
102
|
}
|
|
102
103
|
getRun(runId) {
|
|
103
|
-
return operations.getRun(this.#http,
|
|
104
|
+
return operations.getRun(this.#http, runId);
|
|
104
105
|
}
|
|
105
106
|
listEvents(runId) {
|
|
106
|
-
return operations.listRunEvents(this.#http,
|
|
107
|
+
return operations.listRunEvents(this.#http, runId);
|
|
107
108
|
}
|
|
108
109
|
/**
|
|
109
110
|
* Poll the events endpoint and yield new events as they arrive. Stops
|
|
@@ -149,16 +150,16 @@ export class AntpathClient {
|
|
|
149
150
|
throw new Error("AntpathClient.waitForRun: aborted");
|
|
150
151
|
}
|
|
151
152
|
listOutputs(runId) {
|
|
152
|
-
return operations.listOutputs(this.#http,
|
|
153
|
+
return operations.listOutputs(this.#http, runId);
|
|
153
154
|
}
|
|
154
155
|
createOutputLink(runId, outputId) {
|
|
155
|
-
return operations.createOutputLink(this.#http,
|
|
156
|
+
return operations.createOutputLink(this.#http, runId, outputId);
|
|
156
157
|
}
|
|
157
158
|
cancelRun(runId) {
|
|
158
|
-
return operations.cancelRun(this.#http,
|
|
159
|
+
return operations.cancelRun(this.#http, runId);
|
|
159
160
|
}
|
|
160
161
|
deleteRun(runId) {
|
|
161
|
-
return operations.deleteRun(this.#http,
|
|
162
|
+
return operations.deleteRun(this.#http, runId);
|
|
162
163
|
}
|
|
163
164
|
whoami() {
|
|
164
165
|
return operations.whoami(this.#http);
|
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,UAAU,EACV,UAAU,EACV,4BAA4B,EAC5B,iBAAiB,EACjB,eAAe,EAYhB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/docs/credentials.md
CHANGED
package/docs/quickstart.md
CHANGED
|
@@ -4,18 +4,17 @@ title: antpath quickstart
|
|
|
4
4
|
|
|
5
5
|
# Quickstart
|
|
6
6
|
|
|
7
|
-
1. Get an antpath
|
|
7
|
+
1. Get an antpath SDK API token (`ant_…`).
|
|
8
8
|
2. Define a secret-free Template in TypeScript (or JSON / a `.mjs` default export).
|
|
9
|
-
3. Create `AntpathClient
|
|
9
|
+
3. Create `AntpathClient` — the workspace is derived server-side from the token.
|
|
10
10
|
4. Submit the run with an inline `secrets` bundle. Wait for terminal status. Fetch outputs.
|
|
11
11
|
|
|
12
12
|
```ts
|
|
13
13
|
import { AntpathClient, defineTemplate, string } from "antpath";
|
|
14
14
|
|
|
15
15
|
const client = new AntpathClient({
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
workspaceId: process.env.ANTPATH_WORKSPACE_ID!
|
|
16
|
+
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
17
|
+
// baseUrl defaults to https://antpath.ai — set it for self-hosted deployments.
|
|
19
18
|
});
|
|
20
19
|
|
|
21
20
|
const template = defineTemplate({
|
|
@@ -40,8 +39,6 @@ Or from the shell:
|
|
|
40
39
|
```bash
|
|
41
40
|
antpath run ./template.json \
|
|
42
41
|
--api-token "$ANTPATH_API_TOKEN" \
|
|
43
|
-
--workspace "$ANTPATH_WORKSPACE_ID" \
|
|
44
|
-
--dashboard-url https://antpath.example.com \
|
|
45
42
|
--anthropic-api-key "$ANTHROPIC_API_KEY" \
|
|
46
43
|
--var topic="agent-first SDK design" \
|
|
47
44
|
--follow
|
package/docs/release.md
CHANGED
|
@@ -4,19 +4,64 @@ title: Release
|
|
|
4
4
|
|
|
5
5
|
# Release
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Releasing is **atomic** and **driven by `packages/sdk/package.json#version`**: bump the SDK version on `main` and the publish pipeline carries that exact version through npm → git tag → GitHub Release in one job. Any push to `main` that does not bump the version is a publish no-op.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## How to ship a release
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
1. On a branch, bump `packages/sdk/package.json#version` to the next semver. Land any companion code/doc changes in the same PR.
|
|
12
|
+
2. Merge into `main` (or push directly if you have the right). The pre-push hook (see [Local guard rails](#local-guard-rails)) refuses the push if the local version still matches what's on npm or has already been git-tagged.
|
|
13
|
+
3. CI (`.github/workflows/ci.yml`) runs the `version-gate` job on every PR and direct push to `main`. It diffs against the base ref using [`scripts/check-version-drift.mjs --strict`](../../scripts/check-version-drift.mjs) and fails fast if anything under `packages/{sdk,cli,shared}/src/` or the listed exact paths changed without a fresh version. **`--strict` treats unreachable npm as a hard failure** so we never publish on top of an existing version.
|
|
14
|
+
4. After merge, the `Publish package` workflow (`.github/workflows/publish.yml`) is triggered automatically on push to `main` and decides whether to ship.
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
2. Add a Trusted Publisher for this GitHub repository.
|
|
15
|
-
3. Set **Organization or user** to `weilueluo`.
|
|
16
|
-
4. Set **Repository** to `antpath`.
|
|
17
|
-
5. Set **Workflow filename** to `publish.yml`.
|
|
18
|
-
6. Leave **Environment name** empty unless the workflow uses a matching GitHub Actions environment.
|
|
19
|
-
7. Update `packages/sdk/package.json` version before publishing a release.
|
|
20
|
-
8. Publish a GitHub release for that version.
|
|
16
|
+
You don't tag locally and you don't open a GitHub Release manually — the workflow does both. If the workflow ends red after a successful `npm publish`, the npm version is the source of truth and a human can tag/release retroactively.
|
|
21
17
|
|
|
22
|
-
|
|
18
|
+
## Publish pipeline
|
|
19
|
+
|
|
20
|
+
The workflow has three jobs, in this order:
|
|
21
|
+
|
|
22
|
+
1. **`decide`** — compares the local `packages/sdk/package.json#version` with `npm view antpath@latest version`.
|
|
23
|
+
- If they match → output `proceed=false` and the rest of the pipeline no-ops. Documentation-only commits, refactors that ride along with a previous version, and any other non-publishable change pass through cleanly.
|
|
24
|
+
- If they differ → `proceed=true`, with the local version flowing forward as the canonical `v<version>` for tagging and release notes.
|
|
25
|
+
2. **`publish`** (gated on `proceed=true`) — single linear job:
|
|
26
|
+
- `pnpm install --frozen-lockfile`, `pnpm lint`, `pnpm test`, `pnpm build`.
|
|
27
|
+
- `pnpm --filter antpath pack` into `$RUNNER_TEMP`.
|
|
28
|
+
- **Pre-publish user-tests gate**: runs `apps/user-tests` `user-test:offline` against the packed tarball. A broken artifact (missing `bin`, broken shebang, leaked workspace dep, ESM-only contract violation, …) never reaches npm.
|
|
29
|
+
- **Final freshness check**: `npm view antpath@${VERSION} version` — guards the rare race where someone else publishes the same version between `decide` and here.
|
|
30
|
+
- `pnpm publish --provenance --no-git-checks` from `packages/sdk`. Auth is GitHub OIDC via `id-token: write` plus npm Trusted Publishers — there is no `NPM_TOKEN` secret.
|
|
31
|
+
- `git tag -a v${VERSION}` signed as the canonical commit identity, then `git push origin v${VERSION}`.
|
|
32
|
+
- `gh release create v${VERSION} --generate-notes`.
|
|
33
|
+
3. **`user-tests-post-publish`** (matrix `ubuntu-latest, windows-latest`) — waits for registry visibility with `scripts/wait-for-npm.mjs antpath <version>` (catches the "metadata says yes but CDN tarball 404s" case), then runs `user-test:offline` against the published version on both runners.
|
|
34
|
+
|
|
35
|
+
Atomicity boundary: **publish + tag + GitHub Release happen in the same job**. Until that job goes green, the release is not done — even if `npm publish` already succeeded. Post-publish user-tests are a follow-on signal, not part of the atomic act.
|
|
36
|
+
|
|
37
|
+
## What ships in the tarball
|
|
38
|
+
|
|
39
|
+
The published tarball is **self-contained**. It declares **zero `@antpath/*` runtime dependencies** and is installable from a clean `npm install antpath` with no workspace access:
|
|
40
|
+
|
|
41
|
+
- `@antpath/shared` lives in `packages/sdk/package.json#devDependencies` only. At build time, [`packages/sdk/scripts/inline-shared.mjs`](../scripts/inline-shared.mjs) copies `packages/shared/dist/**` (minus the test-only `testing/` directory and sourcemaps) into `packages/sdk/dist/_shared/` and rewrites `from "@antpath/shared"` to `from "./_shared/index.js"` across the SDK dist tree. A sanity check at the end of that script refuses to finish if any bare `@antpath/shared` specifier survives.
|
|
42
|
+
- `@antpath/cli` is bundled at build time by [`packages/sdk/scripts/bundle-cli.mjs`](../scripts/bundle-cli.mjs) into a single `dist/cli.mjs`, which is the `bin: antpath` entry in `packages/sdk/package.json`.
|
|
43
|
+
- This invariant is mechanically enforced by `apps/user-tests/test/offline/install.test.ts` ("declares no @antpath/* runtime dependencies") — the pre-publish gate fails before npm if any workspace dep leaks back into `dependencies`/`peerDependencies`/`optionalDependencies`.
|
|
44
|
+
|
|
45
|
+
## Local guard rails
|
|
46
|
+
|
|
47
|
+
Every contributor who pushes is expected to install the tracked pre-push hook from the repo root once:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
pnpm hooks:install
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
The hook runs lint, tests, build, an SDK pack dry-run, and `check-version-drift.mjs` (advisory mode — unreachable npm is a warning so offline development still works). It catches "I bumped a runtime file but forgot to bump the version" or "the new version is already on npm" before the push leaves the laptop.
|
|
54
|
+
|
|
55
|
+
## Repository setup (one-time)
|
|
56
|
+
|
|
57
|
+
1. Reserve `antpath` on npm.
|
|
58
|
+
2. Add a Trusted Publisher for this repository (`npmjs.com` → *Settings* → *Publishing access*):
|
|
59
|
+
- **Organization or user**: `weilueluo`
|
|
60
|
+
- **Repository**: `antpath`
|
|
61
|
+
- **Workflow filename**: `publish.yml`
|
|
62
|
+
- **Environment name**: leave empty.
|
|
63
|
+
3. No `NPM_TOKEN` secret is required — OIDC handles auth.
|
|
64
|
+
|
|
65
|
+
## Rollback
|
|
66
|
+
|
|
67
|
+
There is no "unpublish" path: npm prevents reuse of a published version, and a bad release is fixed by publishing a higher version. If the atomic publish job dies between `npm publish` and `gh release create`, retag manually (`git tag -a v<version>`, push, `gh release create`); npm is already truthful.
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { AntpathClient, defineTemplate, requiredStaticBearer } from "antpath";
|
|
2
2
|
|
|
3
3
|
const client = new AntpathClient({
|
|
4
|
-
|
|
5
|
-
apiToken: process.env.ANTPATH_API_TOKEN!,
|
|
6
|
-
workspaceId: process.env.ANTPATH_WORKSPACE_ID!
|
|
4
|
+
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
7
5
|
});
|
|
8
6
|
|
|
9
7
|
const template = defineTemplate({
|
package/examples/quickstart.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import { AntpathClient, defineTemplate, string } from "antpath";
|
|
2
2
|
|
|
3
3
|
const client = new AntpathClient({
|
|
4
|
-
|
|
5
|
-
apiToken: process.env.ANTPATH_API_TOKEN!,
|
|
6
|
-
workspaceId: process.env.ANTPATH_WORKSPACE_ID!
|
|
4
|
+
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
7
5
|
});
|
|
8
6
|
|
|
9
7
|
const template = defineTemplate({
|