antpath 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +67 -0
  2. package/dist/client.d.ts +14 -0
  3. package/dist/client.js +36 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/credentials.d.ts +3 -0
  6. package/dist/credentials.js +27 -0
  7. package/dist/credentials.js.map +1 -0
  8. package/dist/errors.d.ts +25 -0
  9. package/dist/errors.js +39 -0
  10. package/dist/errors.js.map +1 -0
  11. package/dist/files/downloader.d.ts +3 -0
  12. package/dist/files/downloader.js +35 -0
  13. package/dist/files/downloader.js.map +1 -0
  14. package/dist/index.d.ts +5 -0
  15. package/dist/index.js +5 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/providers/anthropic/provider.d.ts +30 -0
  18. package/dist/providers/anthropic/provider.js +302 -0
  19. package/dist/providers/anthropic/provider.js.map +1 -0
  20. package/dist/providers/types.d.ts +42 -0
  21. package/dist/providers/types.js +2 -0
  22. package/dist/providers/types.js.map +1 -0
  23. package/dist/run/controller.d.ts +27 -0
  24. package/dist/run/controller.js +224 -0
  25. package/dist/run/controller.js.map +1 -0
  26. package/dist/skills/packager.d.ts +11 -0
  27. package/dist/skills/packager.js +76 -0
  28. package/dist/skills/packager.js.map +1 -0
  29. package/dist/template/compiler.d.ts +28 -0
  30. package/dist/template/compiler.js +116 -0
  31. package/dist/template/compiler.js.map +1 -0
  32. package/dist/template/index.d.ts +10 -0
  33. package/dist/template/index.js +14 -0
  34. package/dist/template/index.js.map +1 -0
  35. package/dist/template/types.d.ts +67 -0
  36. package/dist/template/types.js +2 -0
  37. package/dist/template/types.js.map +1 -0
  38. package/dist/types.d.ts +129 -0
  39. package/dist/types.js +2 -0
  40. package/dist/types.js.map +1 -0
  41. package/dist/utils/events.d.ts +6 -0
  42. package/dist/utils/events.js +41 -0
  43. package/dist/utils/events.js.map +1 -0
  44. package/dist/utils/paths.d.ts +3 -0
  45. package/dist/utils/paths.js +21 -0
  46. package/dist/utils/paths.js.map +1 -0
  47. package/dist/utils/secrets.d.ts +10 -0
  48. package/dist/utils/secrets.js +59 -0
  49. package/dist/utils/secrets.js.map +1 -0
  50. package/dist/utils/stable.d.ts +2 -0
  51. package/dist/utils/stable.js +20 -0
  52. package/dist/utils/stable.js.map +1 -0
  53. package/docs/cleanup.md +15 -0
  54. package/docs/credentials.md +23 -0
  55. package/docs/mcp.md +18 -0
  56. package/docs/outputs.md +16 -0
  57. package/docs/quickstart.md +13 -0
  58. package/docs/release.md +22 -0
  59. package/docs/skills.md +16 -0
  60. package/docs/templates.md +24 -0
  61. package/docs/testing.md +27 -0
  62. package/examples/mcp-static-bearer.ts +30 -0
  63. package/examples/quickstart.ts +23 -0
  64. package/package.json +51 -0
  65. package/references/architecture-decisions.md +203 -0
  66. package/references/implementation-plan.md +527 -0
  67. package/references/research-sources.md +30 -0
  68. package/references/testing-strategy.md +108 -0
@@ -0,0 +1,67 @@
1
+ export interface TemplateVariableDefinition {
2
+ type: "string";
3
+ default?: string | undefined;
4
+ description?: string | undefined;
5
+ }
6
+ export type CredentialRequirement = {
7
+ type: "static_bearer";
8
+ required: true;
9
+ } | {
10
+ type: "oauth_access_token";
11
+ required: true;
12
+ };
13
+ export interface McpServerDefinition {
14
+ url: string;
15
+ auth?: CredentialRequirement;
16
+ tools?: {
17
+ allow?: string[] | undefined;
18
+ deny?: string[] | undefined;
19
+ };
20
+ }
21
+ export interface EnvironmentDefinition {
22
+ network?: "restricted" | "unrestricted" | {
23
+ type: "limited";
24
+ allowedHosts?: string[] | undefined;
25
+ allowMcpServers?: boolean | undefined;
26
+ allowPackageManagers?: boolean | undefined;
27
+ };
28
+ packages?: Partial<Record<"apt" | "cargo" | "gem" | "go" | "npm" | "pip", string[]>> | undefined;
29
+ }
30
+ export type SkillDefinition = {
31
+ type: "anthropic";
32
+ skillId: string;
33
+ version?: string | undefined;
34
+ } | {
35
+ type: "custom";
36
+ skillId: string;
37
+ version?: string | undefined;
38
+ } | {
39
+ type: "local";
40
+ name: string;
41
+ path: string;
42
+ mountPath?: string | undefined;
43
+ } | {
44
+ type: "inline";
45
+ name: string;
46
+ content: string;
47
+ mountPath?: string | undefined;
48
+ };
49
+ export interface OutputDefinition {
50
+ recommendedPath?: string | undefined;
51
+ include?: string[] | undefined;
52
+ }
53
+ export interface TemplateDefinition<TVariables extends Record<string, TemplateVariableDefinition> = Record<string, TemplateVariableDefinition>> {
54
+ name: string;
55
+ model: string | {
56
+ id: string;
57
+ speed?: "standard" | "fast";
58
+ };
59
+ system?: string | undefined;
60
+ messages: string[];
61
+ variables?: TVariables | undefined;
62
+ mcpServers?: Record<string, McpServerDefinition> | undefined;
63
+ environment?: EnvironmentDefinition | undefined;
64
+ skills?: SkillDefinition[] | undefined;
65
+ outputs?: OutputDefinition | undefined;
66
+ metadata?: Record<string, string> | undefined;
67
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/template/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,129 @@
1
+ import type { ResolvedTemplate } from "./template/compiler.js";
2
+ export type CleanupPolicy = "manual" | "after-output-download" | "on-success" | "always" | "credentials-only";
3
+ export type CredentialInput = {
4
+ type: "static_bearer";
5
+ token: string;
6
+ } | {
7
+ type: "oauth_access_token";
8
+ accessToken: string;
9
+ expiresAt?: string | undefined;
10
+ };
11
+ export interface RunOptions {
12
+ variables?: Record<string, string> | undefined;
13
+ credentials?: Record<string, CredentialInput> | undefined;
14
+ timeoutMs?: number | undefined;
15
+ cleanupPolicy?: CleanupPolicy | undefined;
16
+ signal?: AbortSignal | undefined;
17
+ logger?: Logger | undefined;
18
+ }
19
+ export type RunStatus = "initializing" | "creating_provider_resources" | "running" | "idle_waiting_to_send_next_message" | "downloading_outputs" | "succeeded" | "failed" | "terminating" | "terminated" | "cleanup_pending" | "cleaned_up";
20
+ export interface UsageSummary {
21
+ inputTokens?: number | undefined;
22
+ outputTokens?: number | undefined;
23
+ cacheReadInputTokens?: number | undefined;
24
+ cacheCreationInputTokens?: number | undefined;
25
+ totalTokens?: number | undefined;
26
+ estimatedCostUsd?: number | undefined;
27
+ }
28
+ export interface OutputManifestFile {
29
+ providerFileId: string;
30
+ filename: string;
31
+ localPath: string;
32
+ sizeBytes?: number | undefined;
33
+ }
34
+ export interface OutputManifest {
35
+ files: OutputManifestFile[];
36
+ directory: string;
37
+ }
38
+ export interface DownloadOutputsOptions {
39
+ directory: string;
40
+ include?: RegExp | ((file: ProviderFile) => boolean);
41
+ maxFiles?: number;
42
+ maxTotalBytes?: number;
43
+ }
44
+ export interface DownloadOutputsResult {
45
+ manifest: OutputManifest;
46
+ }
47
+ export interface RunResult {
48
+ status: Exclude<RunStatus, "initializing" | "creating_provider_resources" | "running" | "idle_waiting_to_send_next_message" | "downloading_outputs" | "cleanup_pending">;
49
+ templateHash: string;
50
+ providerIds: ProviderResourceIds;
51
+ usage?: UsageSummary | undefined;
52
+ error?: string | undefined;
53
+ outputManifest?: OutputManifest | undefined;
54
+ cleanupState: CleanupState;
55
+ startedAt: string;
56
+ endedAt: string;
57
+ }
58
+ export type RunEvent = {
59
+ type: "sdk.status";
60
+ status: RunStatus;
61
+ at: string;
62
+ } | {
63
+ type: "sdk.message_sent";
64
+ index: number;
65
+ at: string;
66
+ } | {
67
+ type: "sdk.cleanup";
68
+ operation: string;
69
+ status: "success" | "failed" | "skipped";
70
+ at: string;
71
+ error?: string | undefined;
72
+ } | {
73
+ type: "provider.event";
74
+ event: ProviderEvent;
75
+ at: string;
76
+ };
77
+ export interface RunHandle {
78
+ status(): RunStatus;
79
+ streamEvents(): AsyncIterable<RunEvent>;
80
+ wait(): Promise<RunResult>;
81
+ listFiles(): Promise<ProviderFile[]>;
82
+ downloadFile(fileId: string, destination: string): Promise<void>;
83
+ downloadOutputs(options: DownloadOutputsOptions | string): Promise<DownloadOutputsResult>;
84
+ cleanup(policy?: CleanupPolicy | undefined): Promise<CleanupResult>;
85
+ terminate(reason?: string | undefined): Promise<void>;
86
+ usage(): Promise<UsageSummary | undefined>;
87
+ result(): Promise<RunResult>;
88
+ }
89
+ export interface Logger {
90
+ debug?(message: string, fields?: Record<string, unknown> | undefined): void;
91
+ info?(message: string, fields?: Record<string, unknown> | undefined): void;
92
+ warn?(message: string, fields?: Record<string, unknown> | undefined): void;
93
+ error?(message: string, fields?: Record<string, unknown> | undefined): void;
94
+ }
95
+ export interface ProviderResourceIds {
96
+ environmentId?: string | undefined;
97
+ agentId?: string | undefined;
98
+ vaultId?: string | undefined;
99
+ credentialIds: string[];
100
+ sessionId?: string | undefined;
101
+ uploadedFileIds: string[];
102
+ }
103
+ export interface ProviderFile {
104
+ id: string;
105
+ filename: string;
106
+ sizeBytes?: number | undefined;
107
+ downloadable?: boolean | undefined;
108
+ }
109
+ export interface ProviderEvent {
110
+ type: string;
111
+ id?: string | undefined;
112
+ created_at?: string | undefined;
113
+ [key: string]: unknown;
114
+ }
115
+ export interface CleanupOperation {
116
+ operation: string;
117
+ id?: string | undefined;
118
+ status: "success" | "failed" | "skipped";
119
+ error?: string | undefined;
120
+ }
121
+ export interface CleanupResult {
122
+ operations: CleanupOperation[];
123
+ state: CleanupState;
124
+ }
125
+ export type CleanupState = "not_started" | "pending" | "partial" | "cleaned_up";
126
+ export interface ProviderRunResources {
127
+ ids: ProviderResourceIds;
128
+ template: ResolvedTemplate;
129
+ }
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ export declare class AsyncEventBus<T> {
2
+ #private;
3
+ emit(event: T): void;
4
+ close(): void;
5
+ stream(): AsyncIterable<T>;
6
+ }
@@ -0,0 +1,41 @@
1
+ export class AsyncEventBus {
2
+ #history = [];
3
+ #waiters = [];
4
+ #closed = false;
5
+ emit(event) {
6
+ if (this.#closed) {
7
+ return;
8
+ }
9
+ this.#history.push(event);
10
+ const waiter = this.#waiters.shift();
11
+ if (waiter) {
12
+ waiter({ value: event, done: false });
13
+ }
14
+ }
15
+ close() {
16
+ this.#closed = true;
17
+ for (const waiter of this.#waiters.splice(0)) {
18
+ waiter({ value: undefined, done: true });
19
+ }
20
+ }
21
+ stream() {
22
+ const self = this;
23
+ return {
24
+ async *[Symbol.asyncIterator]() {
25
+ let index = 0;
26
+ while (index < self.#history.length) {
27
+ yield self.#history[index++];
28
+ }
29
+ while (!self.#closed) {
30
+ const next = await new Promise((resolve) => self.#waiters.push(resolve));
31
+ if (next.done) {
32
+ return;
33
+ }
34
+ index++;
35
+ yield next.value;
36
+ }
37
+ }
38
+ };
39
+ }
40
+ }
41
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/utils/events.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAa;IACf,QAAQ,GAAQ,EAAE,CAAC;IACnB,QAAQ,GAA8C,EAAE,CAAC;IAClE,OAAO,GAAG,KAAK,CAAC;IAEhB,IAAI,CAAC,KAAQ;QACX,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QACrC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACxC,CAAC;IACH,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7C,MAAM,CAAC,EAAE,KAAK,EAAE,SAAc,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED,MAAM;QACJ,MAAM,IAAI,GAAG,IAAI,CAAC;QAClB,OAAO;YACL,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC;gBAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;gBACd,OAAO,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;oBACpC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAM,CAAC;gBACpC,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;oBACrB,MAAM,IAAI,GAAG,MAAM,IAAI,OAAO,CAAoB,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;oBAC5F,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;wBACd,OAAO;oBACT,CAAC;oBACD,KAAK,EAAE,CAAC;oBACR,MAAM,IAAI,CAAC,KAAK,CAAC;gBACnB,CAAC;YACH,CAAC;SACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export declare function sanitizeFilename(filename: string): string;
2
+ export declare function safeDestination(directory: string, filename: string): string;
3
+ export declare function writeFileSafe(directory: string, filename: string, content: Uint8Array): Promise<string>;
@@ -0,0 +1,21 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import { basename, join, resolve } from "node:path";
3
+ export function sanitizeFilename(filename) {
4
+ const base = basename(filename).replace(/[\u0000-\u001f<>:"/\\|?*]+/g, "_").trim();
5
+ return base.length === 0 || base === "." || base === ".." ? "download" : base;
6
+ }
7
+ export function safeDestination(directory, filename) {
8
+ const root = resolve(directory);
9
+ const destination = resolve(join(root, sanitizeFilename(filename)));
10
+ if (!destination.startsWith(root)) {
11
+ throw new Error(`Unsafe output path for ${filename}`);
12
+ }
13
+ return destination;
14
+ }
15
+ export async function writeFileSafe(directory, filename, content) {
16
+ await mkdir(directory, { recursive: true });
17
+ const destination = safeDestination(directory, filename);
18
+ await writeFile(destination, content);
19
+ return destination;
20
+ }
21
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpD,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACnF,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,SAAiB,EAAE,QAAgB;IACjE,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpE,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAClC,MAAM,IAAI,KAAK,CAAC,0BAA0B,QAAQ,EAAE,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,QAAgB,EAAE,OAAmB;IAC1F,MAAM,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,WAAW,GAAG,eAAe,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,SAAS,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,WAAW,CAAC;AACrB,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare class SecretString {
2
+ #private;
3
+ constructor(value: string, label?: string);
4
+ unwrap(): string;
5
+ toString(): string;
6
+ toJSON(): string;
7
+ }
8
+ export declare function redactSecrets<T>(value: T): T;
9
+ export declare function redactString(input: string): string;
10
+ export declare function containsSecretLikeValue(input: string): boolean;
@@ -0,0 +1,59 @@
1
+ const SECRET_PATTERNS = [
2
+ /sk-ant-[A-Za-z0-9_\-]{16,}/g,
3
+ /sk-[A-Za-z0-9_\-]{20,}/g,
4
+ /xox[pbar]-[A-Za-z0-9\-]{10,}/g,
5
+ /(?:bearer|token|api[_-]?key|access[_-]?token|refresh[_-]?token|client[_-]?secret)["'\s:=]+[A-Za-z0-9_\-./+=]{12,}/gi
6
+ ];
7
+ const REDACTED = "[REDACTED]";
8
+ export class SecretString {
9
+ #value;
10
+ constructor(value, label = "secret") {
11
+ if (!value) {
12
+ throw new Error(`${label} is required`);
13
+ }
14
+ this.#value = value;
15
+ }
16
+ unwrap() {
17
+ return this.#value;
18
+ }
19
+ toString() {
20
+ return REDACTED;
21
+ }
22
+ toJSON() {
23
+ return REDACTED;
24
+ }
25
+ }
26
+ export function redactSecrets(value) {
27
+ if (typeof value === "string") {
28
+ return redactString(value);
29
+ }
30
+ if (Array.isArray(value)) {
31
+ return value.map((item) => redactSecrets(item));
32
+ }
33
+ if (value && typeof value === "object") {
34
+ const out = {};
35
+ for (const [key, item] of Object.entries(value)) {
36
+ if (isSecretKey(key)) {
37
+ out[key] = REDACTED;
38
+ }
39
+ else {
40
+ out[key] = redactSecrets(item);
41
+ }
42
+ }
43
+ return out;
44
+ }
45
+ return value;
46
+ }
47
+ export function redactString(input) {
48
+ return SECRET_PATTERNS.reduce((current, pattern) => current.replace(pattern, REDACTED), input);
49
+ }
50
+ export function containsSecretLikeValue(input) {
51
+ return SECRET_PATTERNS.some((pattern) => {
52
+ pattern.lastIndex = 0;
53
+ return pattern.test(input);
54
+ });
55
+ }
56
+ function isSecretKey(key) {
57
+ return /(?:api[_-]?key|authorization|token|secret|password|credential)/i.test(key);
58
+ }
59
+ //# sourceMappingURL=secrets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/utils/secrets.ts"],"names":[],"mappings":"AAAA,MAAM,eAAe,GAAG;IACtB,6BAA6B;IAC7B,yBAAyB;IACzB,+BAA+B;IAC/B,qHAAqH;CACtH,CAAC;AAEF,MAAM,QAAQ,GAAG,YAAY,CAAC;AAE9B,MAAM,OAAO,YAAY;IACd,MAAM,CAAS;IAExB,YAAY,KAAa,EAAE,KAAK,GAAG,QAAQ;QACzC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,GAAG,KAAK,cAAc,CAAC,CAAC;QAC1C,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,MAAM;QACJ,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,QAAQ;QACN,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM;QACJ,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAI,KAAQ;IACvC,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,YAAY,CAAC,KAAK,CAAM,CAAC;IAClC,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAM,CAAC;IACvD,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,GAAG,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,GAAG,CAAC,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QACD,OAAO,GAAQ,CAAC;IAClB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,KAAa;IACxC,OAAO,eAAe,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC;AACjG,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;QACtC,OAAO,CAAC,SAAS,GAAG,CAAC,CAAC;QACtB,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,WAAW,CAAC,GAAW;IAC9B,OAAO,iEAAiE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACrF,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function stableStringify(value: unknown): string;
2
+ export declare function sha256(value: unknown): string;
@@ -0,0 +1,20 @@
1
+ import { createHash } from "node:crypto";
2
+ export function stableStringify(value) {
3
+ return JSON.stringify(sortValue(value));
4
+ }
5
+ export function sha256(value) {
6
+ return createHash("sha256").update(typeof value === "string" ? value : stableStringify(value)).digest("hex");
7
+ }
8
+ function sortValue(value) {
9
+ if (Array.isArray(value)) {
10
+ return value.map(sortValue);
11
+ }
12
+ if (value && typeof value === "object") {
13
+ return Object.fromEntries(Object.entries(value)
14
+ .filter(([, item]) => item !== undefined)
15
+ .sort(([a], [b]) => a.localeCompare(b))
16
+ .map(([key, item]) => [key, sortValue(item)]));
17
+ }
18
+ return value;
19
+ }
20
+ //# sourceMappingURL=stable.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable.js","sourceRoot":"","sources":["../../src/utils/stable.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,eAAe,CAAC,KAAc;IAC5C,OAAO,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC/G,CAAC;AAED,SAAS,SAAS,CAAC,KAAc;IAC/B,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,OAAO,MAAM,CAAC,WAAW,CACvB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,KAAK,SAAS,CAAC;aACxC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;aACtC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAChD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: Cleanup
3
+ ---
4
+
5
+ # Cleanup
6
+
7
+ Cleanup is manual by default:
8
+
9
+ ```ts
10
+ await handle.cleanup();
11
+ ```
12
+
13
+ This preserves provider-side files/events for inspection and avoids deleting outputs before users download them.
14
+
15
+ If the SDK process exits before cleanup, provider resources may remain in the user's provider workspace. The result includes provider IDs so a future cleanup helper can recover orphaned resources when the caller recreates a Client with the same key.
@@ -0,0 +1,23 @@
1
+ ---
2
+ title: Credentials
3
+ ---
4
+
5
+ # Credentials
6
+
7
+ antpath does not store provider keys or MCP credential values.
8
+
9
+ The caller creates `AntpathClient` with a provider key. MCP credentials are passed at run time and validated against Template requirements.
10
+
11
+ MVP credential types:
12
+
13
+ - `static_bearer`;
14
+ - `oauth_access_token`.
15
+
16
+ Unsupported in MVP:
17
+
18
+ - arbitrary headers;
19
+ - OAuth refresh;
20
+ - persisted antpath vault;
21
+ - antpath MCP proxy.
22
+
23
+ For Claude Managed Agents, the SDK creates per-run provider vault credentials and tracks provider IDs for cleanup.
package/docs/mcp.md ADDED
@@ -0,0 +1,18 @@
1
+ ---
2
+ title: MCP
3
+ ---
4
+
5
+ # MCP
6
+
7
+ MVP MCP support is provider-native remote HTTPS MCP only.
8
+
9
+ Rules:
10
+
11
+ - MCP servers are declared in Templates.
12
+ - Runtime HITL is disabled.
13
+ - Tool policy must be configured before session start.
14
+ - Enabled MCP tools use `always_allow` provider permissions.
15
+ - `always_ask` is not used by antpath MVP.
16
+ - Only provider-native bearer/OAuth auth is supported.
17
+
18
+ Use allowlists for sensitive servers whenever possible.
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: Outputs
3
+ ---
4
+
5
+ # Outputs
6
+
7
+ `downloadOutputs()` downloads all session-scoped provider files by default.
8
+
9
+ `/antpath/outputs` is a recommended convention, not a provider default. Templates may instruct agents to write important artifacts there, but MVP output download still uses session-scoped files.
10
+
11
+ Safety rules:
12
+
13
+ - filenames are sanitized;
14
+ - downloads stay within the requested local directory;
15
+ - max file count and max total bytes are enforced;
16
+ - manifests contain provider file IDs, local paths, names, and sizes only.
@@ -0,0 +1,13 @@
1
+ ---
2
+ title: antpath quickstart
3
+ ---
4
+
5
+ # Quickstart
6
+
7
+ 1. Put `ANTHROPIC_API_KEY` in `.env.local`.
8
+ 2. Define a secret-free Template in TypeScript.
9
+ 3. Create `AntpathClient`.
10
+ 4. Run the Template.
11
+ 5. Wait, download files, then call `cleanup()`.
12
+
13
+ See `README.md` for a minimal example.
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Release
3
+ ---
4
+
5
+ # Release
6
+
7
+ CI runs on pull requests and pushes to `main`.
8
+
9
+ Publishing runs when a GitHub release is published, or when the publish workflow is manually dispatched.
10
+
11
+ Repository setup required:
12
+
13
+ 1. Create or reserve the `antpath` package on npm.
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 `package.json` version before publishing a release.
20
+ 8. Publish a GitHub release for that version.
21
+
22
+ The publish workflow uses GitHub OIDC through `id-token: write`; it does not require an npm token secret. It runs type-checks, tests, build, then `npm publish --provenance`.
package/docs/skills.md ADDED
@@ -0,0 +1,16 @@
1
+ ---
2
+ title: Skills
3
+ ---
4
+
5
+ # Skills
6
+
7
+ MVP skill inputs:
8
+
9
+ - provider-managed Anthropic skills;
10
+ - existing custom provider skill IDs;
11
+ - local files/directories uploaded as session resources;
12
+ - inline skill content uploaded as session resources.
13
+
14
+ Local directories are packaged as zip files and mounted under `/antpath/skills/` unless overridden.
15
+
16
+ Inline skills are uploaded as markdown files and mounted under `/antpath/skills/` unless overridden.
@@ -0,0 +1,24 @@
1
+ ---
2
+ title: Templates
3
+ ---
4
+
5
+ # Templates
6
+
7
+ Templates are code-defined, immutable, secret-free run configurations.
8
+
9
+ Allowed Template content:
10
+
11
+ - model;
12
+ - system prompt;
13
+ - queued user messages;
14
+ - typed variables;
15
+ - MCP server declarations;
16
+ - MCP tool allow/deny policy;
17
+ - environment package and network configuration;
18
+ - inline/local/provider skills;
19
+ - output conventions;
20
+ - non-secret metadata.
21
+
22
+ Variables use `{{name}}` and are resolved before provider calls. Use `\{{name}}` for a literal placeholder.
23
+
24
+ Secrets must not appear in Templates. Pass credentials through `run({ credentials })`.
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: Testing
3
+ ---
4
+
5
+ # Testing
6
+
7
+ antpath uses test-first development.
8
+
9
+ Commands:
10
+
11
+ ```text
12
+ npm run test:unit
13
+ npm run test:integration:components
14
+ npm run test:integration:api
15
+ npm run test:e2e:live
16
+ ```
17
+
18
+ Live tests require `.env.local` and `RUN_LIVE_ANTPATH_TESTS=1`.
19
+
20
+ Recorded API fixtures are created with:
21
+
22
+ ```text
23
+ npm run fixtures:record:anthropic
24
+ npm run fixtures:sanitize
25
+ ```
26
+
27
+ Raw fixtures and secret-shaped fixture files are ignored.
@@ -0,0 +1,30 @@
1
+ import { AntpathClient, defineTemplate, requiredStaticBearer } from "antpath";
2
+
3
+ const client = new AntpathClient({
4
+ anthropicApiKey: process.env.ANTHROPIC_API_KEY
5
+ });
6
+
7
+ const template = defineTemplate({
8
+ name: "mcp-static-bearer",
9
+ model: "claude-haiku-4-5",
10
+ messages: ["List the relevant records and summarize them."],
11
+ mcpServers: {
12
+ example: {
13
+ url: "https://mcp.example.com/mcp",
14
+ auth: requiredStaticBearer(),
15
+ tools: { allow: ["search", "fetch"] }
16
+ }
17
+ }
18
+ });
19
+
20
+ const handle = await client.run(template, {
21
+ credentials: {
22
+ example: {
23
+ type: "static_bearer",
24
+ token: process.env.EXAMPLE_MCP_TOKEN ?? ""
25
+ }
26
+ }
27
+ });
28
+
29
+ await handle.wait();
30
+ await handle.cleanup();
@@ -0,0 +1,23 @@
1
+ import { AntpathClient, defineTemplate, string } from "antpath";
2
+
3
+ const client = new AntpathClient({
4
+ anthropicApiKey: process.env.ANTHROPIC_API_KEY
5
+ });
6
+
7
+ const template = defineTemplate({
8
+ name: "quickstart",
9
+ model: "claude-haiku-4-5",
10
+ system: "You are a concise automation agent.",
11
+ messages: ["Write a short answer about {{topic}}."],
12
+ variables: {
13
+ topic: string()
14
+ }
15
+ });
16
+
17
+ const handle = await client.run(template, {
18
+ variables: { topic: "test-first SDK design" }
19
+ });
20
+
21
+ const result = await handle.wait();
22
+ console.log(result.status);
23
+ await handle.cleanup();