antpath 0.2.1 → 0.4.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 (110) hide show
  1. package/README.md +54 -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 +25 -0
  11. package/dist/_shared/http.js +93 -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 +24 -0
  17. package/dist/_shared/operations.js +47 -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/stable.d.ts +16 -0
  30. package/dist/{utils → _shared}/stable.js +14 -0
  31. package/dist/_shared/status.d.ts +8 -0
  32. package/dist/_shared/status.js +46 -0
  33. package/dist/_shared/submission.d.ts +157 -0
  34. package/dist/_shared/submission.js +681 -0
  35. package/dist/{template → _shared/template}/compiler.js +3 -3
  36. package/dist/{template/index.d.ts → _shared/template/helpers.d.ts} +0 -2
  37. package/dist/{template/index.js → _shared/template/helpers.js} +1 -2
  38. package/dist/_shared/template/index.d.ts +4 -0
  39. package/dist/_shared/template/index.js +4 -0
  40. package/dist/_shared/template/mapper.d.ts +11 -0
  41. package/dist/_shared/template/mapper.js +70 -0
  42. package/dist/cli.mjs +1223 -64
  43. package/dist/cli.mjs.sha256 +1 -1
  44. package/dist/client.d.ts +100 -8
  45. package/dist/client.js +193 -30
  46. package/dist/client.js.map +1 -1
  47. package/dist/index.d.ts +16 -10
  48. package/dist/index.js +16 -7
  49. package/dist/index.js.map +1 -1
  50. package/docs/cleanup.md +7 -4
  51. package/docs/credentials.md +10 -12
  52. package/docs/events.md +19 -82
  53. package/docs/outputs.md +15 -4
  54. package/docs/quickstart.md +40 -6
  55. package/docs/release.md +57 -12
  56. package/docs/skills.md +1 -1
  57. package/docs/templates.md +1 -1
  58. package/docs/testing.md +11 -8
  59. package/examples/mcp-static-bearer.ts +12 -9
  60. package/examples/quickstart.ts +6 -6
  61. package/package.json +5 -7
  62. package/dist/credentials.d.ts +0 -3
  63. package/dist/credentials.js +0 -56
  64. package/dist/credentials.js.map +0 -1
  65. package/dist/errors.js.map +0 -1
  66. package/dist/files/downloader.d.ts +0 -3
  67. package/dist/files/downloader.js +0 -43
  68. package/dist/files/downloader.js.map +0 -1
  69. package/dist/platform/client.d.ts +0 -204
  70. package/dist/platform/client.js +0 -203
  71. package/dist/platform/client.js.map +0 -1
  72. package/dist/platform/index.d.ts +0 -1
  73. package/dist/platform/index.js +0 -2
  74. package/dist/platform/index.js.map +0 -1
  75. package/dist/providers/anthropic/provider.d.ts +0 -36
  76. package/dist/providers/anthropic/provider.js +0 -380
  77. package/dist/providers/anthropic/provider.js.map +0 -1
  78. package/dist/providers/known-events.js.map +0 -1
  79. package/dist/providers/types.d.ts +0 -42
  80. package/dist/providers/types.js.map +0 -1
  81. package/dist/run/controller.d.ts +0 -30
  82. package/dist/run/controller.js +0 -314
  83. package/dist/run/controller.js.map +0 -1
  84. package/dist/skills/packager.d.ts +0 -11
  85. package/dist/skills/packager.js +0 -76
  86. package/dist/skills/packager.js.map +0 -1
  87. package/dist/template/compiler.js.map +0 -1
  88. package/dist/template/index.js.map +0 -1
  89. package/dist/template/types.js +0 -2
  90. package/dist/template/types.js.map +0 -1
  91. package/dist/types.d.ts +0 -149
  92. package/dist/types.js +0 -2
  93. package/dist/types.js.map +0 -1
  94. package/dist/utils/events.d.ts +0 -27
  95. package/dist/utils/events.js +0 -120
  96. package/dist/utils/events.js.map +0 -1
  97. package/dist/utils/paths.d.ts +0 -3
  98. package/dist/utils/paths.js +0 -27
  99. package/dist/utils/paths.js.map +0 -1
  100. package/dist/utils/secrets.js.map +0 -1
  101. package/dist/utils/stable.d.ts +0 -2
  102. package/dist/utils/stable.js.map +0 -1
  103. package/references/architecture-decisions.md +0 -473
  104. package/references/implementation-plan.md +0 -452
  105. package/references/research-sources.md +0 -41
  106. package/references/testing-strategy.md +0 -29
  107. /package/dist/{utils/secrets.d.ts → _shared/sdk-secrets.d.ts} +0 -0
  108. /package/dist/{template → _shared/template}/compiler.d.ts +0 -0
  109. /package/dist/{template → _shared/template}/types.d.ts +0 -0
  110. /package/dist/{providers → _shared/template}/types.js +0 -0
@@ -0,0 +1,17 @@
1
+ export * from "./cleanup-policy.js";
2
+ export * from "./config.js";
3
+ export * from "./dev-stack.js";
4
+ export * from "./errors.js";
5
+ export * from "./proxy-protocol.js";
6
+ export * from "./secrets.js";
7
+ export * from "./status.js";
8
+ export * from "./submission.js";
9
+ export * from "./stable.js";
10
+ export * from "./sdk-secrets.js";
11
+ export * from "./sdk-errors.js";
12
+ export * from "./template/index.js";
13
+ export * from "./runtime-types.js";
14
+ export * from "./known-events.js";
15
+ export * from "./http.js";
16
+ export * as operations from "./operations.js";
17
+ export * from "./proxy-validation.js";
@@ -0,0 +1,20 @@
1
+ export * from "./cleanup-policy.js";
2
+ export * from "./config.js";
3
+ export * from "./dev-stack.js";
4
+ export * from "./errors.js";
5
+ export * from "./proxy-protocol.js";
6
+ export * from "./secrets.js";
7
+ export * from "./status.js";
8
+ export * from "./submission.js";
9
+ // SDK + CLI shared surface — moved here so the published `antpath` SDK
10
+ // and the in-container `antpath` CLI consume the SAME implementation.
11
+ export * from "./stable.js";
12
+ export * from "./sdk-secrets.js";
13
+ export * from "./sdk-errors.js";
14
+ export * from "./template/index.js";
15
+ export * from "./runtime-types.js";
16
+ export * from "./known-events.js";
17
+ export * from "./http.js";
18
+ export * as operations from "./operations.js";
19
+ export * from "./proxy-validation.js";
20
+ //# sourceMappingURL=index.js.map
@@ -1,4 +1,4 @@
1
- import type { ProviderEvent } from "../types.js";
1
+ import type { ProviderEvent } from "./runtime-types.js";
2
2
  /**
3
3
  * Type guards that narrow a `ProviderEvent` by the documented Claude Managed
4
4
  * Agents event `type` strings. These do not assert anything about the event
@@ -22,33 +22,33 @@ export declare function isSpanEvent<E extends ProviderEvent>(event: E): event is
22
22
  export declare function isAgentMessage<E extends ProviderEvent>(event: E): event is E & {
23
23
  type: "agent.message";
24
24
  };
25
- export declare function isAgentThinking<E extends ProviderEvent>(event: E): event is E & {
26
- type: "agent.thinking";
27
- };
28
25
  export declare function isAgentToolUse<E extends ProviderEvent>(event: E): event is E & {
29
26
  type: "agent.tool_use";
30
27
  };
31
28
  export declare function isAgentToolResult<E extends ProviderEvent>(event: E): event is E & {
32
29
  type: "agent.tool_result";
33
30
  };
31
+ export declare function isAgentThinking<E extends ProviderEvent>(event: E): event is E & {
32
+ type: "agent.thinking";
33
+ };
34
+ export declare function isAgentCustomToolUse<E extends ProviderEvent>(event: E): event is E & {
35
+ type: "agent.custom_tool_use";
36
+ };
34
37
  export declare function isAgentMcpToolUse<E extends ProviderEvent>(event: E): event is E & {
35
38
  type: "agent.mcp_tool_use";
36
39
  };
37
40
  export declare function isAgentMcpToolResult<E extends ProviderEvent>(event: E): event is E & {
38
41
  type: "agent.mcp_tool_result";
39
42
  };
40
- export declare function isAgentCustomToolUse<E extends ProviderEvent>(event: E): event is E & {
41
- type: "agent.custom_tool_use";
42
- };
43
43
  export declare function isUserMessage<E extends ProviderEvent>(event: E): event is E & {
44
44
  type: "user.message";
45
45
  };
46
- export declare function isSessionStatusRunning<E extends ProviderEvent>(event: E): event is E & {
47
- type: "session.status_running";
48
- };
49
46
  export declare function isSessionStatusIdle<E extends ProviderEvent>(event: E): event is E & {
50
47
  type: "session.status_idle";
51
48
  };
49
+ export declare function isSessionStatusRunning<E extends ProviderEvent>(event: E): event is E & {
50
+ type: "session.status_running";
51
+ };
52
52
  export declare function isSessionStatusRescheduled<E extends ProviderEvent>(event: E): event is E & {
53
53
  type: "session.status_rescheduled";
54
54
  };
@@ -23,35 +23,35 @@ export function isSpanEvent(event) {
23
23
  export function isAgentMessage(event) {
24
24
  return event.type === "agent.message";
25
25
  }
26
- export function isAgentThinking(event) {
27
- return event.type === "agent.thinking";
28
- }
29
26
  export function isAgentToolUse(event) {
30
27
  return event.type === "agent.tool_use";
31
28
  }
32
29
  export function isAgentToolResult(event) {
33
30
  return event.type === "agent.tool_result";
34
31
  }
32
+ export function isAgentThinking(event) {
33
+ return event.type === "agent.thinking";
34
+ }
35
+ export function isAgentCustomToolUse(event) {
36
+ return event.type === "agent.custom_tool_use";
37
+ }
35
38
  export function isAgentMcpToolUse(event) {
36
39
  return event.type === "agent.mcp_tool_use";
37
40
  }
38
41
  export function isAgentMcpToolResult(event) {
39
42
  return event.type === "agent.mcp_tool_result";
40
43
  }
41
- export function isAgentCustomToolUse(event) {
42
- return event.type === "agent.custom_tool_use";
43
- }
44
44
  // User events.
45
45
  export function isUserMessage(event) {
46
46
  return event.type === "user.message";
47
47
  }
48
48
  // Session events.
49
- export function isSessionStatusRunning(event) {
50
- return event.type === "session.status_running";
51
- }
52
49
  export function isSessionStatusIdle(event) {
53
50
  return event.type === "session.status_idle";
54
51
  }
52
+ export function isSessionStatusRunning(event) {
53
+ return event.type === "session.status_running";
54
+ }
55
55
  export function isSessionStatusRescheduled(event) {
56
56
  return event.type === "session.status_rescheduled";
57
57
  }
@@ -0,0 +1,24 @@
1
+ import type { HttpClient } from "./http.js";
2
+ import type { Output, Run, RunEvent, SignedOutputLink, WhoAmI } from "./runtime-types.js";
3
+ import type { PlatformRunSubmissionInput } from "./submission.js";
4
+ /**
5
+ * The single source of truth for SDK<->BFF transport. The SDK class
6
+ * AND the CLI subcommands both call these functions; neither
7
+ * surface re-implements HTTP requests against the dashboard.
8
+ *
9
+ * Every function takes an HttpClient (so callers control auth + fetch
10
+ * injection) and returns parsed responses.
11
+ *
12
+ * Workspace identity is derived server-side from the API token on
13
+ * every request — callers do not pass `workspaceId`. See
14
+ * `references/development-principles.md` (Agent-first surface design,
15
+ * Concrete rule 3).
16
+ */
17
+ export declare function submitRun(http: HttpClient, request: PlatformRunSubmissionInput): Promise<Run>;
18
+ export declare function getRun(http: HttpClient, runId: string): Promise<Run>;
19
+ export declare function listRunEvents(http: HttpClient, runId: string): Promise<readonly RunEvent[]>;
20
+ export declare function listOutputs(http: HttpClient, runId: string): Promise<readonly Output[]>;
21
+ export declare function createOutputLink(http: HttpClient, runId: string, outputId: string): Promise<SignedOutputLink>;
22
+ export declare function cancelRun(http: HttpClient, runId: string): Promise<void>;
23
+ export declare function deleteRun(http: HttpClient, runId: string): Promise<void>;
24
+ export declare function whoami(http: HttpClient): Promise<WhoAmI>;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The single source of truth for SDK<->BFF transport. The SDK class
3
+ * AND the CLI subcommands both call these functions; neither
4
+ * surface re-implements HTTP requests against the dashboard.
5
+ *
6
+ * Every function takes an HttpClient (so callers control auth + fetch
7
+ * injection) and returns parsed responses.
8
+ *
9
+ * Workspace identity is derived server-side from the API token on
10
+ * every request — callers do not pass `workspaceId`. See
11
+ * `references/development-principles.md` (Agent-first surface design,
12
+ * Concrete rule 3).
13
+ */
14
+ export async function submitRun(http, request) {
15
+ return http.request("/api/runs", {
16
+ method: "POST",
17
+ body: JSON.stringify(request)
18
+ });
19
+ }
20
+ export async function getRun(http, runId) {
21
+ const result = await http.request(`/api/runs/${encodeURIComponent(runId)}`);
22
+ return hasRun(result) ? result.run : result;
23
+ }
24
+ export async function listRunEvents(http, runId) {
25
+ const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/events`);
26
+ return result.events;
27
+ }
28
+ export async function listOutputs(http, runId) {
29
+ const result = await http.request(`/api/runs/${encodeURIComponent(runId)}/outputs`);
30
+ return result.outputs;
31
+ }
32
+ export async function createOutputLink(http, runId, outputId) {
33
+ return http.request(`/api/runs/${encodeURIComponent(runId)}/outputs/${encodeURIComponent(outputId)}/link`, { method: "POST" });
34
+ }
35
+ export async function cancelRun(http, runId) {
36
+ await http.request(`/api/runs/${encodeURIComponent(runId)}/cancel`, { method: "POST" });
37
+ }
38
+ export async function deleteRun(http, runId) {
39
+ await http.request(`/api/runs/${encodeURIComponent(runId)}`, { method: "DELETE" });
40
+ }
41
+ export async function whoami(http) {
42
+ return http.request("/api/whoami");
43
+ }
44
+ function hasRun(value) {
45
+ return Boolean(value && typeof value === "object" && "run" in value);
46
+ }
47
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Wire-protocol version. Bumped on any breaking change to the request or
3
+ * response shape. The CLI sends this in the `X-Antpath-Proxy-Protocol`
4
+ * header on every request; the BFF rejects mismatches with HTTP 426
5
+ * `unsupported_protocol`.
6
+ *
7
+ * Bumps are coordinated: CLI and BFF release together, the worker
8
+ * bundles the matching CLI artifact, and the e2e suite runs both with
9
+ * the new version. See plan.md "CLI design".
10
+ */
11
+ export declare const PROXY_PROTOCOL_VERSION: "1";
12
+ export declare const PROXY_PROTOCOL_HEADER = "x-antpath-proxy-protocol";
13
+ export declare const PROXY_METHOD_HEADER = "x-antpath-method";
14
+ export declare const PROXY_PATH_HEADER = "x-antpath-path";
15
+ export declare const PROXY_QUERY_HEADER = "x-antpath-query";
16
+ export declare const PROXY_HEADERS_HEADER = "x-antpath-headers";
17
+ export declare const PROXY_RESPONSE_MODE_HEADER = "x-antpath-response-mode";
18
+ export declare const PROXY_ALLOWED_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"];
19
+ export type ProxyMethod = (typeof PROXY_ALLOWED_METHODS)[number];
20
+ export declare const PROXY_RESPONSE_MODES: readonly ["status_only", "headers_only", "full"];
21
+ export type ProxyResponseMode = (typeof PROXY_RESPONSE_MODES)[number];
22
+ /**
23
+ * Returns the narrower of the two response modes (lower width wins).
24
+ * Pure function so the CLI and BFF can both call it without import cycles.
25
+ */
26
+ export declare function narrowResponseMode(policy: ProxyResponseMode, requested: ProxyResponseMode): ProxyResponseMode;
27
+ /**
28
+ * Error codes returned by the proxy route. Stable strings — the CLI
29
+ * matches against them in scripts. Adding a new code is non-breaking;
30
+ * removing or renaming an existing code requires a protocol bump.
31
+ */
32
+ export declare const PROXY_ERROR_CODES: readonly ["unsupported_protocol", "unauthorized", "endpoint_not_found", "policy_denied", "rate_limited", "budget_exceeded", "ssrf_denied", "upstream_timeout", "upstream_error", "exceeded_cap", "bad_request", "internal_error"];
33
+ export type ProxyErrorCode = (typeof PROXY_ERROR_CODES)[number];
34
+ /**
35
+ * Shape of the JSON written to `/antpath/index.json` inside the container.
36
+ *
37
+ * Always present (every run), regardless of whether any proxy endpoints
38
+ * were declared. With zero endpoints, `endpoints` is `[]` and
39
+ * `proxyBaseUrl` is `null` — this keeps `antpath --help` working
40
+ * uniformly and makes the always-on surface observable in tests.
41
+ *
42
+ * Auth values NEVER appear in this file. The file is mounted into the
43
+ * container; treat it as world-readable from the agent's perspective.
44
+ */
45
+ export interface ProxyIndexFile {
46
+ readonly protocolVersion: typeof PROXY_PROTOCOL_VERSION;
47
+ readonly runId: string;
48
+ readonly proxyBaseUrl: string | null;
49
+ readonly endpoints: readonly ProxyIndexEntry[];
50
+ }
51
+ export interface ProxyIndexEntry {
52
+ readonly name: string;
53
+ readonly baseUrl: string;
54
+ readonly authShape: ProxyAuthShape;
55
+ readonly allowMethods: readonly ProxyMethod[];
56
+ readonly allowPathPrefixes: readonly string[];
57
+ readonly allowHeaders: readonly string[];
58
+ readonly responseMode: ProxyResponseMode;
59
+ readonly maxRequestBytes: number;
60
+ readonly maxResponseBytes: number;
61
+ readonly timeoutMs: number;
62
+ readonly perCallBudget: number;
63
+ readonly responseByteBudget: number;
64
+ }
65
+ /**
66
+ * Structural description of how the upstream endpoint expects auth.
67
+ * The actual auth value lives in the run's Vault bundle under
68
+ * `secrets.proxyEndpointAuth[i].value` and is never reflected back
69
+ * into the container or index file.
70
+ */
71
+ export type ProxyAuthShape = {
72
+ readonly type: "bearer";
73
+ } | {
74
+ readonly type: "basic";
75
+ } | {
76
+ readonly type: "header";
77
+ readonly name: string;
78
+ } | {
79
+ readonly type: "query";
80
+ readonly name: string;
81
+ };
82
+ export type ProxyAuthType = ProxyAuthShape["type"];
83
+ /**
84
+ * Header name (lowercase) that an upstream auth shape uses as its
85
+ * carrier. Returns `undefined` for query-based auth.
86
+ *
87
+ * Used by the submission parser to forbid `allowHeaders` from listing
88
+ * the auth header (avoids leaks via caller-supplied headers), and by
89
+ * the proxy route to strip any caller header that would collide with
90
+ * the auth carrier at request time.
91
+ */
92
+ export declare function authShapeHeaderName(shape: ProxyAuthShape): string | undefined;
93
+ /**
94
+ * Query-string key that an upstream query-based auth shape uses as its
95
+ * carrier. Returns `undefined` for non-query shapes.
96
+ */
97
+ export declare function authShapeQueryName(shape: ProxyAuthShape): string | undefined;
98
+ /**
99
+ * JSON body returned on a successful proxy call. The actual HTTP
100
+ * response from the BFF to the CLI is always 200 once the BFF accepts
101
+ * the request; the upstream's status/headers/body are reflected inside
102
+ * this envelope so the CLI can decide what to write to stdout/stderr.
103
+ */
104
+ export interface ProxyResponseEnvelope {
105
+ readonly endpointName: string;
106
+ readonly upstreamStatus: number;
107
+ /** Lowercase header names → values. Allowlist-filtered by the BFF. */
108
+ readonly upstreamHeaders: Readonly<Record<string, string>>;
109
+ /**
110
+ * Base64-encoded upstream body. Present only when the effective
111
+ * response mode is `full`. Truncated to `maxResponseBytes`; if the
112
+ * upstream exceeded the cap, `truncated` is `true`.
113
+ */
114
+ readonly upstreamBodyBase64?: string;
115
+ readonly truncated?: boolean;
116
+ /**
117
+ * Echoed back so the CLI can warn the agent when its requested mode
118
+ * was clamped against the policy ceiling.
119
+ */
120
+ readonly effectiveResponseMode: ProxyResponseMode;
121
+ readonly modeClamped: boolean;
122
+ /** Remaining per-endpoint per-run budget after this call. */
123
+ readonly remainingCalls: number;
124
+ readonly remainingResponseBytes: number;
125
+ }
126
+ /**
127
+ * JSON body returned on any error. The CLI emits this verbatim on
128
+ * stderr and exits non-zero. Audit row carries the same `code`.
129
+ */
130
+ export interface ProxyErrorBody {
131
+ readonly error: ProxyErrorCode;
132
+ /** Human-readable message. Never includes auth values. */
133
+ readonly message: string;
134
+ /**
135
+ * Optional diagnostic fields. Always safe to surface — auth values
136
+ * and full URLs are stripped at the BFF.
137
+ */
138
+ readonly endpointName?: string;
139
+ readonly upstreamStatus?: number;
140
+ /** Server-supplied protocol version on `unsupported_protocol`. */
141
+ readonly serverProtocolVersion?: string;
142
+ }
143
+ /**
144
+ * Status code → error code mapping used by the BFF to ensure the audit
145
+ * row's error code and the HTTP response line up. Kept here so callers
146
+ * can do a sanity check in tests.
147
+ */
148
+ export declare const PROXY_ERROR_HTTP_STATUS: Record<ProxyErrorCode, number>;
@@ -0,0 +1,113 @@
1
+ // Wire format between the in-container CLI (`/antpath/antpath`) and the
2
+ // dashboard BFF proxy route (`POST /api/runs/:runId/proxy/:endpointName`).
3
+ //
4
+ // This module is the single source of truth for the request shape, the
5
+ // response shape, the error-code enum, and the protocol version header.
6
+ // CLI and BFF both import from here; drift becomes a build-time type error.
7
+ //
8
+ // References:
9
+ // - plan.md sections "Proxy route" and "CLI design"
10
+ // - references/development-principles.md (Agent-first surface design)
11
+ /**
12
+ * Wire-protocol version. Bumped on any breaking change to the request or
13
+ * response shape. The CLI sends this in the `X-Antpath-Proxy-Protocol`
14
+ * header on every request; the BFF rejects mismatches with HTTP 426
15
+ * `unsupported_protocol`.
16
+ *
17
+ * Bumps are coordinated: CLI and BFF release together, the worker
18
+ * bundles the matching CLI artifact, and the e2e suite runs both with
19
+ * the new version. See plan.md "CLI design".
20
+ */
21
+ export const PROXY_PROTOCOL_VERSION = "1";
22
+ export const PROXY_PROTOCOL_HEADER = "x-antpath-proxy-protocol";
23
+ export const PROXY_METHOD_HEADER = "x-antpath-method";
24
+ export const PROXY_PATH_HEADER = "x-antpath-path";
25
+ export const PROXY_QUERY_HEADER = "x-antpath-query";
26
+ export const PROXY_HEADERS_HEADER = "x-antpath-headers";
27
+ export const PROXY_RESPONSE_MODE_HEADER = "x-antpath-response-mode";
28
+ export const PROXY_ALLOWED_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"];
29
+ export const PROXY_RESPONSE_MODES = ["status_only", "headers_only", "full"];
30
+ /**
31
+ * Narrowing order: a request may only narrow below the policy ceiling.
32
+ * `status_only` is narrowest, `full` is widest. The BFF computes
33
+ * `narrowest(policyMode, headerMode)` and ignores escalation attempts,
34
+ * auditing them as `mode_clamped`.
35
+ */
36
+ const RESPONSE_MODE_WIDTH = {
37
+ status_only: 0,
38
+ headers_only: 1,
39
+ full: 2
40
+ };
41
+ /**
42
+ * Returns the narrower of the two response modes (lower width wins).
43
+ * Pure function so the CLI and BFF can both call it without import cycles.
44
+ */
45
+ export function narrowResponseMode(policy, requested) {
46
+ return RESPONSE_MODE_WIDTH[requested] < RESPONSE_MODE_WIDTH[policy] ? requested : policy;
47
+ }
48
+ /**
49
+ * Error codes returned by the proxy route. Stable strings — the CLI
50
+ * matches against them in scripts. Adding a new code is non-breaking;
51
+ * removing or renaming an existing code requires a protocol bump.
52
+ */
53
+ export const PROXY_ERROR_CODES = [
54
+ "unsupported_protocol",
55
+ "unauthorized",
56
+ "endpoint_not_found",
57
+ "policy_denied",
58
+ "rate_limited",
59
+ "budget_exceeded",
60
+ "ssrf_denied",
61
+ "upstream_timeout",
62
+ "upstream_error",
63
+ "exceeded_cap",
64
+ "bad_request",
65
+ "internal_error"
66
+ ];
67
+ /**
68
+ * Header name (lowercase) that an upstream auth shape uses as its
69
+ * carrier. Returns `undefined` for query-based auth.
70
+ *
71
+ * Used by the submission parser to forbid `allowHeaders` from listing
72
+ * the auth header (avoids leaks via caller-supplied headers), and by
73
+ * the proxy route to strip any caller header that would collide with
74
+ * the auth carrier at request time.
75
+ */
76
+ export function authShapeHeaderName(shape) {
77
+ switch (shape.type) {
78
+ case "bearer":
79
+ case "basic":
80
+ return "authorization";
81
+ case "header":
82
+ return shape.name.toLowerCase();
83
+ case "query":
84
+ return undefined;
85
+ }
86
+ }
87
+ /**
88
+ * Query-string key that an upstream query-based auth shape uses as its
89
+ * carrier. Returns `undefined` for non-query shapes.
90
+ */
91
+ export function authShapeQueryName(shape) {
92
+ return shape.type === "query" ? shape.name : undefined;
93
+ }
94
+ /**
95
+ * Status code → error code mapping used by the BFF to ensure the audit
96
+ * row's error code and the HTTP response line up. Kept here so callers
97
+ * can do a sanity check in tests.
98
+ */
99
+ export const PROXY_ERROR_HTTP_STATUS = {
100
+ unsupported_protocol: 426,
101
+ unauthorized: 401,
102
+ endpoint_not_found: 404,
103
+ policy_denied: 403,
104
+ rate_limited: 429,
105
+ budget_exceeded: 429,
106
+ ssrf_denied: 403,
107
+ upstream_timeout: 504,
108
+ upstream_error: 502,
109
+ exceeded_cap: 502,
110
+ bad_request: 400,
111
+ internal_error: 500
112
+ };
113
+ //# sourceMappingURL=proxy-protocol.js.map
@@ -0,0 +1,19 @@
1
+ import type { PlatformProxyEndpoint, PlatformProxyEndpointAuth } from "./submission.js";
2
+ /**
3
+ * Cross-validate a `proxyEndpoints` policy list against a
4
+ * `secrets.proxyEndpointAuth` value list. Throws on the first mismatch
5
+ * with an actionable, field-named error message.
6
+ *
7
+ * Mirrors the BFF's authoritative validator so misconfigured submissions
8
+ * fail fast in the SDK/CLI before going over the wire.
9
+ */
10
+ export declare function validateProxyAuth(endpoints: readonly PlatformProxyEndpoint[], auth: readonly PlatformProxyEndpointAuth[] | undefined): void;
11
+ /**
12
+ * Build an `allowedHosts` list for `environment.network` that includes
13
+ * the antpath proxy host (and optionally Anthropic's MCP host) when the
14
+ * caller is hand-rolling networking.
15
+ */
16
+ export declare function buildPlatformAllowedHosts(input: {
17
+ readonly dashboardBaseUrl: string;
18
+ readonly extraHosts?: readonly string[];
19
+ }): readonly string[];
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Cross-validate a `proxyEndpoints` policy list against a
3
+ * `secrets.proxyEndpointAuth` value list. Throws on the first mismatch
4
+ * with an actionable, field-named error message.
5
+ *
6
+ * Mirrors the BFF's authoritative validator so misconfigured submissions
7
+ * fail fast in the SDK/CLI before going over the wire.
8
+ */
9
+ export function validateProxyAuth(endpoints, auth) {
10
+ const authList = auth ?? [];
11
+ const endpointNames = new Set(endpoints.map((e) => e.name));
12
+ const authNames = new Set();
13
+ for (const entry of authList) {
14
+ if (authNames.has(entry.name)) {
15
+ throw new Error(`secrets.proxyEndpointAuth contains duplicate name '${entry.name}'`);
16
+ }
17
+ authNames.add(entry.name);
18
+ if (!endpointNames.has(entry.name)) {
19
+ throw new Error(`secrets.proxyEndpointAuth[].name='${entry.name}' has no matching proxyEndpoints[].name`);
20
+ }
21
+ }
22
+ for (const endpoint of endpoints) {
23
+ const match = authList.find((a) => a.name === endpoint.name);
24
+ if (!match) {
25
+ throw new Error(`proxyEndpoints[].name='${endpoint.name}' is missing a matching secrets.proxyEndpointAuth entry`);
26
+ }
27
+ if (match.value.type !== endpoint.authShape.type) {
28
+ 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}'`);
29
+ }
30
+ }
31
+ }
32
+ /**
33
+ * Build an `allowedHosts` list for `environment.network` that includes
34
+ * the antpath proxy host (and optionally Anthropic's MCP host) when the
35
+ * caller is hand-rolling networking.
36
+ */
37
+ export function buildPlatformAllowedHosts(input) {
38
+ const result = [];
39
+ try {
40
+ result.push(new URL(input.dashboardBaseUrl).host);
41
+ }
42
+ catch {
43
+ throw new Error("buildPlatformAllowedHosts: dashboardBaseUrl must be an absolute URL");
44
+ }
45
+ for (const host of input.extraHosts ?? []) {
46
+ if (!result.includes(host))
47
+ result.push(host);
48
+ }
49
+ return result;
50
+ }
51
+ //# sourceMappingURL=proxy-validation.js.map
@@ -0,0 +1,90 @@
1
+ import type { JsonValue, PlatformInlineSecrets, PlatformProxyEndpoint } from "./submission.js";
2
+ /**
3
+ * Loose record describing a run as the dashboard BFF returns it. Concrete
4
+ * dashboard-managed fields appear in the index signature; the SDK and CLI
5
+ * may surface them without strong typing per-field.
6
+ */
7
+ export interface Run {
8
+ readonly id: string;
9
+ readonly status: string;
10
+ readonly workspaceId?: string;
11
+ readonly templateName?: string;
12
+ readonly templateHash?: string;
13
+ readonly createdAt?: string;
14
+ readonly updatedAt?: string;
15
+ readonly terminalAt?: string | null;
16
+ readonly errorMessage?: string | null;
17
+ readonly usage?: UsageSummary;
18
+ readonly [key: string]: unknown;
19
+ }
20
+ export interface UsageSummary {
21
+ readonly inputTokens?: number;
22
+ readonly outputTokens?: number;
23
+ readonly cacheReadInputTokens?: number;
24
+ readonly cacheCreationInputTokens?: number;
25
+ readonly totalTokens?: number;
26
+ readonly estimatedCostUsd?: number;
27
+ }
28
+ /**
29
+ * A run event as recorded by the dashboard. Includes the `type` field
30
+ * that the `is*Event` type guards narrow on plus any provider payload.
31
+ */
32
+ export interface RunEvent {
33
+ readonly id: string;
34
+ readonly type: string;
35
+ readonly runId?: string;
36
+ readonly recordedAt?: string;
37
+ readonly [key: string]: unknown;
38
+ }
39
+ /**
40
+ * Provider-emitted event payload, kept structurally identical to the
41
+ * upstream Claude Managed Agents event so type guards work uniformly
42
+ * whether the event came from the worker (live) or the dashboard
43
+ * (replayed).
44
+ */
45
+ export interface ProviderEvent {
46
+ readonly type: string;
47
+ readonly id?: string | undefined;
48
+ readonly created_at?: string | undefined;
49
+ readonly [key: string]: unknown;
50
+ }
51
+ /**
52
+ * One captured output file as the dashboard reports it. Use
53
+ * `createOutputLink` to get a short-lived signed URL for download.
54
+ */
55
+ export interface Output {
56
+ readonly id: string;
57
+ readonly filename?: string;
58
+ readonly sizeBytes?: number;
59
+ readonly contentType?: string;
60
+ readonly createdAt?: string;
61
+ readonly [key: string]: unknown;
62
+ }
63
+ export interface SignedOutputLink {
64
+ readonly url: string;
65
+ readonly expiresAt?: string;
66
+ readonly [key: string]: unknown;
67
+ }
68
+ export interface WhoAmI {
69
+ readonly principalType: "api_token" | "user";
70
+ readonly workspaceId?: string;
71
+ readonly tokenId?: string;
72
+ readonly tokenName?: string | null;
73
+ readonly scopes?: readonly string[];
74
+ readonly [key: string]: unknown;
75
+ }
76
+ /**
77
+ * Full submission as the SDK and CLI assemble it before posting. The
78
+ * `template` is the SDK-level ResolvedTemplate (or a JSON-encoded one);
79
+ * the SDK/CLI converts to PlatformTemplateSubmission via the mapper.
80
+ */
81
+ export interface RunSubmissionInput {
82
+ readonly workspaceId: string;
83
+ readonly idempotencyKey?: string;
84
+ readonly variables?: Record<string, JsonValue>;
85
+ readonly secrets: PlatformInlineSecrets;
86
+ readonly proxyEndpoints?: readonly PlatformProxyEndpoint[];
87
+ readonly cleanup?: {
88
+ readonly session?: "retain" | "delete";
89
+ };
90
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=runtime-types.js.map
@@ -1,4 +1,4 @@
1
- export type AntpathErrorCode = "TEMPLATE_INVALID" | "CREDENTIAL_INVALID" | "PROVIDER_ERROR" | "RUN_STATE_ERROR" | "CLEANUP_ERROR";
1
+ export type AntpathErrorCode = "TEMPLATE_INVALID" | "CREDENTIAL_INVALID" | "PROVIDER_ERROR" | "RUN_STATE_ERROR" | "CLEANUP_ERROR" | "API_ERROR";
2
2
  export declare class AntpathError extends Error {
3
3
  readonly code: AntpathErrorCode;
4
4
  readonly details?: unknown;
@@ -23,3 +23,12 @@ export declare class RunStateError extends AntpathError {
23
23
  export declare class CleanupError extends AntpathError {
24
24
  constructor(message: string, details?: unknown);
25
25
  }
26
+ /**
27
+ * Thrown by SDK and CLI operations when the dashboard BFF returns a non-2xx
28
+ * response. Carries the HTTP status and parsed body for the caller to inspect.
29
+ */
30
+ export declare class AntpathApiError extends AntpathError {
31
+ readonly status: number;
32
+ readonly body: unknown;
33
+ constructor(status: number, message: string, body: unknown);
34
+ }