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.
- package/README.md +54 -40
- package/dist/_shared/cleanup-policy.d.ts +8 -0
- package/dist/_shared/cleanup-policy.js +24 -0
- package/dist/_shared/config.d.ts +47 -0
- package/dist/_shared/config.js +150 -0
- package/dist/_shared/dev-stack.d.ts +19 -0
- package/dist/_shared/dev-stack.js +105 -0
- package/dist/_shared/errors.d.ts +8 -0
- package/dist/_shared/errors.js +18 -0
- package/dist/_shared/http.d.ts +25 -0
- package/dist/_shared/http.js +93 -0
- package/dist/_shared/index.d.ts +17 -0
- package/dist/_shared/index.js +20 -0
- package/dist/{providers → _shared}/known-events.d.ts +10 -10
- package/dist/{providers → _shared}/known-events.js +9 -9
- package/dist/_shared/operations.d.ts +24 -0
- package/dist/_shared/operations.js +47 -0
- package/dist/_shared/proxy-protocol.d.ts +148 -0
- package/dist/_shared/proxy-protocol.js +113 -0
- package/dist/_shared/proxy-validation.d.ts +19 -0
- package/dist/_shared/proxy-validation.js +51 -0
- package/dist/_shared/runtime-types.d.ts +90 -0
- package/dist/_shared/runtime-types.js +2 -0
- package/dist/{errors.d.ts → _shared/sdk-errors.d.ts} +10 -1
- package/dist/{errors.js → _shared/sdk-errors.js} +15 -2
- package/dist/{utils/secrets.js → _shared/sdk-secrets.js} +1 -1
- package/dist/_shared/secrets.d.ts +7 -0
- package/dist/_shared/secrets.js +20 -0
- package/dist/_shared/stable.d.ts +16 -0
- package/dist/{utils → _shared}/stable.js +14 -0
- package/dist/_shared/status.d.ts +8 -0
- package/dist/_shared/status.js +46 -0
- package/dist/_shared/submission.d.ts +157 -0
- package/dist/_shared/submission.js +681 -0
- package/dist/{template → _shared/template}/compiler.js +3 -3
- package/dist/{template/index.d.ts → _shared/template/helpers.d.ts} +0 -2
- package/dist/{template/index.js → _shared/template/helpers.js} +1 -2
- package/dist/_shared/template/index.d.ts +4 -0
- package/dist/_shared/template/index.js +4 -0
- package/dist/_shared/template/mapper.d.ts +11 -0
- package/dist/_shared/template/mapper.js +70 -0
- package/dist/cli.mjs +1223 -64
- package/dist/cli.mjs.sha256 +1 -1
- package/dist/client.d.ts +100 -8
- package/dist/client.js +193 -30
- package/dist/client.js.map +1 -1
- package/dist/index.d.ts +16 -10
- package/dist/index.js +16 -7
- package/dist/index.js.map +1 -1
- package/docs/cleanup.md +7 -4
- package/docs/credentials.md +10 -12
- package/docs/events.md +19 -82
- package/docs/outputs.md +15 -4
- package/docs/quickstart.md +40 -6
- package/docs/release.md +57 -12
- package/docs/skills.md +1 -1
- package/docs/templates.md +1 -1
- package/docs/testing.md +11 -8
- package/examples/mcp-static-bearer.ts +12 -9
- package/examples/quickstart.ts +6 -6
- package/package.json +5 -7
- package/dist/credentials.d.ts +0 -3
- package/dist/credentials.js +0 -56
- package/dist/credentials.js.map +0 -1
- package/dist/errors.js.map +0 -1
- package/dist/files/downloader.d.ts +0 -3
- package/dist/files/downloader.js +0 -43
- package/dist/files/downloader.js.map +0 -1
- package/dist/platform/client.d.ts +0 -204
- package/dist/platform/client.js +0 -203
- package/dist/platform/client.js.map +0 -1
- package/dist/platform/index.d.ts +0 -1
- package/dist/platform/index.js +0 -2
- package/dist/platform/index.js.map +0 -1
- package/dist/providers/anthropic/provider.d.ts +0 -36
- package/dist/providers/anthropic/provider.js +0 -380
- package/dist/providers/anthropic/provider.js.map +0 -1
- package/dist/providers/known-events.js.map +0 -1
- package/dist/providers/types.d.ts +0 -42
- package/dist/providers/types.js.map +0 -1
- package/dist/run/controller.d.ts +0 -30
- package/dist/run/controller.js +0 -314
- package/dist/run/controller.js.map +0 -1
- package/dist/skills/packager.d.ts +0 -11
- package/dist/skills/packager.js +0 -76
- package/dist/skills/packager.js.map +0 -1
- package/dist/template/compiler.js.map +0 -1
- package/dist/template/index.js.map +0 -1
- package/dist/template/types.js +0 -2
- package/dist/template/types.js.map +0 -1
- package/dist/types.d.ts +0 -149
- package/dist/types.js +0 -2
- package/dist/types.js.map +0 -1
- package/dist/utils/events.d.ts +0 -27
- package/dist/utils/events.js +0 -120
- package/dist/utils/events.js.map +0 -1
- package/dist/utils/paths.d.ts +0 -3
- package/dist/utils/paths.js +0 -27
- package/dist/utils/paths.js.map +0 -1
- package/dist/utils/secrets.js.map +0 -1
- package/dist/utils/stable.d.ts +0 -2
- package/dist/utils/stable.js.map +0 -1
- 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/{utils/secrets.d.ts → _shared/sdk-secrets.d.ts} +0 -0
- /package/dist/{template → _shared/template}/compiler.d.ts +0 -0
- /package/dist/{template → _shared/template}/types.d.ts +0 -0
- /package/dist/{providers → _shared/template}/types.js +0 -0
package/docs/events.md
CHANGED
|
@@ -4,105 +4,41 @@ title: Events
|
|
|
4
4
|
|
|
5
5
|
# Events
|
|
6
6
|
|
|
7
|
-
Claude Managed Agents sessions run autonomously on Anthropic's infrastructure.
|
|
8
|
-
They are **non-blocking**: the SDK opens a long-lived SSE stream while the
|
|
9
|
-
agent thinks, calls tools, and emits messages on its own schedule. The SDK
|
|
10
|
-
cannot intercept a tool call to return a value — `permission_policy` is
|
|
11
|
-
`always_allow`. This guide covers the observe-only event surface.
|
|
7
|
+
Claude Managed Agents sessions run autonomously on Anthropic's infrastructure. They are **non-blocking**: the worker polls the provider session while the agent thinks, calls tools, and emits messages on its own schedule, and persists every captured event to the dashboard. The SDK and CLI observe the durable event timeline from the dashboard — there is no in-process tool-approval hook (`permission_policy` is `always_allow`).
|
|
12
8
|
|
|
13
9
|
## Two ways to consume events
|
|
14
10
|
|
|
15
11
|
```ts
|
|
16
|
-
//
|
|
17
|
-
const
|
|
18
|
-
onEvent: async (event) => {
|
|
19
|
-
if (event.type === "provider.event") {
|
|
20
|
-
// event.event is a ProviderEvent (typed via a type guard below).
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
await handle.wait();
|
|
12
|
+
// Pull a snapshot of every event captured so far.
|
|
13
|
+
const events = await ref.events();
|
|
25
14
|
```
|
|
26
15
|
|
|
27
16
|
```ts
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
const
|
|
31
|
-
|
|
17
|
+
// Stream live: yields each event exactly once, stops when the run reaches
|
|
18
|
+
// a terminal status. Backed by polling the dashboard events endpoint.
|
|
19
|
+
for await (const event of ref.stream({ intervalMs: 1000 })) {
|
|
20
|
+
if (event.type === "agent.message") {
|
|
32
21
|
// ...
|
|
33
22
|
}
|
|
34
|
-
})();
|
|
35
|
-
const result = await handle.wait();
|
|
36
|
-
await collect;
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
Both surfaces observe the same events. They can be used together; every
|
|
40
|
-
subscriber sees every event. A subscriber attached after `client.run()`
|
|
41
|
-
returns replays the events it missed (including the initial
|
|
42
|
-
`sdk.status` emitted while provider resources were being created), then
|
|
43
|
-
continues live.
|
|
44
|
-
|
|
45
|
-
## Event shape
|
|
46
|
-
|
|
47
|
-
```ts
|
|
48
|
-
type RunEvent =
|
|
49
|
-
| { type: "sdk.status"; status: RunStatus; at: string }
|
|
50
|
-
| { type: "sdk.message_sent"; index: number; at: string }
|
|
51
|
-
| { type: "sdk.cleanup"; ... } // see "Cleanup events" below
|
|
52
|
-
| { type: "provider.event"; event: ProviderEvent; at: string };
|
|
53
|
-
|
|
54
|
-
interface ProviderEvent {
|
|
55
|
-
type: string; // documented Claude event type, e.g. "agent.tool_use"
|
|
56
|
-
payload: unknown; // raw provider payload, redacted
|
|
57
|
-
receivedAt: string;
|
|
58
23
|
}
|
|
59
24
|
```
|
|
60
25
|
|
|
61
|
-
|
|
62
|
-
subscriber, so payloads do not contain the Anthropic key or MCP credentials
|
|
63
|
-
that were supplied to `client.run()`.
|
|
26
|
+
The CLI mirrors the same surface:
|
|
64
27
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
resolved or rejected. Async handlers are invoked serially in event order on
|
|
70
|
-
a single per-listener promise chain, so callers can persist events in order
|
|
71
|
-
without their own queue.
|
|
72
|
-
|
|
73
|
-
The same drain applies to handlers that throw — both modes (warn-only and
|
|
74
|
-
abort-on-error, see below) wait for the offending invocation to settle
|
|
75
|
-
before resolving.
|
|
76
|
-
|
|
77
|
-
## Error semantics
|
|
78
|
-
|
|
79
|
-
Default: a handler that throws (or returns a rejecting promise) is logged
|
|
80
|
-
via the SDK's configured `logger` at `warn`. The run continues, and the
|
|
81
|
-
final result is unaffected.
|
|
82
|
-
|
|
83
|
-
Opt-in: `onEventAbortOnError: true` upgrades the **first** pre-terminal
|
|
84
|
-
handler error into a `RunStateError` that fails the run. Once terminal
|
|
85
|
-
status has been reached, listener errors are always logged only — they
|
|
86
|
-
never mutate the result, and they cannot trigger recursion when the
|
|
87
|
-
terminal `sdk.status: failed` event itself causes another error.
|
|
28
|
+
```bash
|
|
29
|
+
antpath events <run-id> --api-token … --workspace … --dashboard-url … # snapshot
|
|
30
|
+
antpath events <run-id> --follow --api-token … --workspace … --dashboard-url … # stream until terminal
|
|
31
|
+
```
|
|
88
32
|
|
|
89
|
-
|
|
90
|
-
redaction layer used for events.
|
|
33
|
+
Both surfaces observe the same events. A subscriber attached after `submitRun()` returns replays the events it missed, then continues live.
|
|
91
34
|
|
|
92
|
-
##
|
|
35
|
+
## Event shape
|
|
93
36
|
|
|
94
|
-
`
|
|
95
|
-
emitted by `handle.cleanup()` after `handle.wait()` has already resolved.
|
|
96
|
-
By that time the event bus has been closed; subscribers attached during
|
|
97
|
-
the run do **not** see them. Inspect cleanup outcomes via the
|
|
98
|
-
`CleanupResult.operations` array returned by `cleanup()` instead.
|
|
37
|
+
Events are typed as the discriminated `RunEvent` union — agent messages, tool uses, tool results, session status transitions, sdk lifecycle events, span events. The dashboard records the raw provider payload **after** secret redaction and structural sanitization, so the bytes you see in `event.payload` never contain the Anthropic key, MCP credentials, or proxy bearer that were supplied to `submitRun`.
|
|
99
38
|
|
|
100
39
|
## Typed helpers
|
|
101
40
|
|
|
102
|
-
|
|
103
|
-
guards that narrow `ProviderEvent.type` to documented Claude event strings.
|
|
104
|
-
They do **not** assert payload field shapes — the raw provider payload
|
|
105
|
-
stays `unknown` until callers parse it themselves.
|
|
41
|
+
The package exports conservative type guards that narrow events to documented Claude event types:
|
|
106
42
|
|
|
107
43
|
```ts
|
|
108
44
|
import {
|
|
@@ -125,5 +61,6 @@ import {
|
|
|
125
61
|
} from "antpath";
|
|
126
62
|
```
|
|
127
63
|
|
|
128
|
-
|
|
129
|
-
|
|
64
|
+
They narrow only the discriminant — payload field shapes stay `unknown` until callers parse them.
|
|
65
|
+
|
|
66
|
+
The official list of event types is maintained at [`platform.claude.com/docs/en/managed-agents/events-and-streaming`](https://platform.claude.com/docs/en/managed-agents/events-and-streaming).
|
package/docs/outputs.md
CHANGED
|
@@ -4,13 +4,24 @@ title: Outputs
|
|
|
4
4
|
|
|
5
5
|
# Outputs
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Every run captures provider session-scoped files into private Supabase Storage. List and download them through whichever surface is convenient.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```ts
|
|
10
|
+
const outputs = await ref.outputs(); // OutputSummary[]
|
|
11
|
+
const { url } = await client.createOutputLink(ref.runId, outputs[0].id);
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
antpath outputs list <run-id> --api-token … --workspace … --dashboard-url …
|
|
16
|
+
antpath outputs download <run-id> <output-id> --out ./dir \
|
|
17
|
+
--api-token … --workspace … --dashboard-url …
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`/antpath/outputs` is a recommended convention, not a provider default. Templates may instruct agents to write important artifacts there, but every session-scoped provider file is captured unconditionally (bounded only by the workspace storage cap; skipped files are recorded as `output_capture_failures`).
|
|
10
21
|
|
|
11
22
|
Safety rules:
|
|
12
23
|
|
|
13
24
|
- filenames are sanitized;
|
|
14
25
|
- downloads stay within the requested local directory;
|
|
15
|
-
-
|
|
16
|
-
- manifests contain provider file IDs, local paths, names, and sizes only.
|
|
26
|
+
- signed download links are short-lived;
|
|
27
|
+
- manifests contain provider file IDs, local paths, names, and sizes only — never file bytes.
|
package/docs/quickstart.md
CHANGED
|
@@ -4,10 +4,44 @@ title: antpath quickstart
|
|
|
4
4
|
|
|
5
5
|
# Quickstart
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2. Define a secret-free Template in TypeScript.
|
|
9
|
-
3. Create `AntpathClient
|
|
10
|
-
4.
|
|
11
|
-
5. Wait, download files, then call `cleanup()`.
|
|
7
|
+
1. Get an antpath SDK API token (`ant_…`).
|
|
8
|
+
2. Define a secret-free Template in TypeScript (or JSON / a `.mjs` default export).
|
|
9
|
+
3. Create `AntpathClient` — the workspace is derived server-side from the token.
|
|
10
|
+
4. Submit the run with an inline `secrets` bundle. Wait for terminal status. Fetch outputs.
|
|
12
11
|
|
|
13
|
-
|
|
12
|
+
```ts
|
|
13
|
+
import { AntpathClient, defineTemplate, string } from "antpath";
|
|
14
|
+
|
|
15
|
+
const client = new AntpathClient({
|
|
16
|
+
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
17
|
+
// baseUrl defaults to https://antpath.ai — set it for self-hosted deployments.
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const template = defineTemplate({
|
|
21
|
+
name: "hello",
|
|
22
|
+
model: "claude-haiku-4-5",
|
|
23
|
+
messages: ["Write a short answer about {{topic}}."],
|
|
24
|
+
variables: { topic: string() }
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
const ref = await client.submitRun(template, {
|
|
28
|
+
variables: { topic: "agent-first SDK design" },
|
|
29
|
+
secrets: { anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! } }
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const run = await ref.wait();
|
|
33
|
+
console.log(run.status);
|
|
34
|
+
console.log(await ref.outputs());
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or from the shell:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
antpath run ./template.json \
|
|
41
|
+
--api-token "$ANTPATH_API_TOKEN" \
|
|
42
|
+
--anthropic-api-key "$ANTHROPIC_API_KEY" \
|
|
43
|
+
--var topic="agent-first SDK design" \
|
|
44
|
+
--follow
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Both surfaces hit the same dashboard BFF and operate on the same durable run records — pick whichever is most convenient.
|
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.
|
package/docs/skills.md
CHANGED
|
@@ -15,4 +15,4 @@ Local directories are packaged as zip files and mounted under `/antpath/skills/`
|
|
|
15
15
|
|
|
16
16
|
Inline skills are uploaded as markdown files and mounted under `/antpath/skills/` unless overridden.
|
|
17
17
|
|
|
18
|
-
The platform also mounts the `antpath` CLI at `/antpath/antpath` and a per-run manifest at `/antpath/index.json` on **every** run. Skills can invoke the managed HTTP proxy via
|
|
18
|
+
The platform also mounts the `antpath` CLI at `/antpath/antpath` and a per-run manifest at `/antpath/index.json` on **every** run. Skills can invoke the managed HTTP proxy via `/antpath/antpath proxy …` — see `credentials.md` for the policy/auth model.
|
package/docs/templates.md
CHANGED
|
@@ -21,4 +21,4 @@ Allowed Template content:
|
|
|
21
21
|
|
|
22
22
|
Variables use `{{name}}` and are resolved before provider calls. Use `\{{name}}` for a literal placeholder.
|
|
23
23
|
|
|
24
|
-
Secrets must not appear in Templates. Pass credentials through `
|
|
24
|
+
Secrets must not appear in Templates. Pass credentials through `submitRun(template, { secrets, proxyEndpointAuth })` (SDK) or the equivalent host-mode flags (`--anthropic-api-key`, `--mcp-secret`, `--proxy-auth`).
|
package/docs/testing.md
CHANGED
|
@@ -6,21 +6,24 @@ title: Testing
|
|
|
6
6
|
|
|
7
7
|
antpath uses test-first development.
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Workspace-wide commands:
|
|
10
10
|
|
|
11
11
|
```text
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
pnpm test # unit, all packages, deterministic
|
|
13
|
+
pnpm test:unit:recorded # unit + replayed provider fixtures
|
|
14
|
+
pnpm test:integration # live external systems (Supabase + dashboard) — no skip flags
|
|
15
|
+
pnpm test:e2e:live # full top-to-bottom flows against live services
|
|
16
|
+
pnpm test:user # offline assertions on the published antpath package
|
|
17
|
+
pnpm test:user:live # live assertions on the published antpath package
|
|
15
18
|
```
|
|
16
19
|
|
|
17
|
-
Unit tests are deterministic and may use fakes or sanitized recorded snapshots.
|
|
20
|
+
Unit tests are deterministic and may use fakes or sanitized recorded snapshots. Integration tests run live external systems without any skip flag; if credentials are missing they fail loudly. Live e2e and user-live tests require `.env.local` (or runner-provided env) to include `ANTHROPIC_API_KEY` and any other live target vars; see `references/environment-variables.md`.
|
|
18
21
|
|
|
19
|
-
Recorded
|
|
22
|
+
Recorded provider fixtures are produced with:
|
|
20
23
|
|
|
21
24
|
```text
|
|
22
|
-
|
|
23
|
-
|
|
25
|
+
pnpm --filter antpath run fixtures:record:anthropic
|
|
26
|
+
pnpm --filter antpath run fixtures:sanitize
|
|
24
27
|
```
|
|
25
28
|
|
|
26
29
|
Raw fixtures and secret-shaped fixture files are ignored.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AntpathClient, defineTemplate, requiredStaticBearer } from "antpath";
|
|
2
2
|
|
|
3
3
|
const client = new AntpathClient({
|
|
4
|
-
|
|
4
|
+
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
5
5
|
});
|
|
6
6
|
|
|
7
7
|
const template = defineTemplate({
|
|
@@ -17,14 +17,17 @@ const template = defineTemplate({
|
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
const ref = await client.submitRun(template, {
|
|
21
|
+
secrets: {
|
|
22
|
+
anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! },
|
|
23
|
+
mcpServers: [
|
|
24
|
+
{
|
|
25
|
+
name: "example",
|
|
26
|
+
url: "https://mcp.example.com/mcp",
|
|
27
|
+
headers: { Authorization: `Bearer ${process.env.EXAMPLE_MCP_TOKEN ?? ""}` }
|
|
28
|
+
}
|
|
29
|
+
]
|
|
26
30
|
}
|
|
27
31
|
});
|
|
28
32
|
|
|
29
|
-
await
|
|
30
|
-
await handle.cleanup();
|
|
33
|
+
await ref.wait();
|
package/examples/quickstart.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AntpathClient, defineTemplate, string } from "antpath";
|
|
2
2
|
|
|
3
3
|
const client = new AntpathClient({
|
|
4
|
-
|
|
4
|
+
apiToken: process.env.ANTPATH_API_TOKEN!
|
|
5
5
|
});
|
|
6
6
|
|
|
7
7
|
const template = defineTemplate({
|
|
@@ -14,10 +14,10 @@ const template = defineTemplate({
|
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
variables: { topic: "
|
|
17
|
+
const ref = await client.submitRun(template, {
|
|
18
|
+
variables: { topic: "agent-first SDK design" },
|
|
19
|
+
secrets: { anthropic: { apiKey: process.env.ANTHROPIC_API_KEY! } }
|
|
19
20
|
});
|
|
20
21
|
|
|
21
|
-
const
|
|
22
|
-
console.log(
|
|
23
|
-
await handle.cleanup();
|
|
22
|
+
const run = await ref.wait();
|
|
23
|
+
console.log(run.status);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "antpath",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "TypeScript SDK for running autonomous Claude Managed Agents sessions.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -22,18 +22,16 @@
|
|
|
22
22
|
"dist",
|
|
23
23
|
"README.md",
|
|
24
24
|
"docs",
|
|
25
|
-
"examples"
|
|
26
|
-
"references"
|
|
25
|
+
"examples"
|
|
27
26
|
],
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"fflate": "0.8.2"
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@antpath/shared": "0.1.0"
|
|
31
29
|
},
|
|
32
30
|
"engines": {
|
|
33
31
|
"node": ">=20"
|
|
34
32
|
},
|
|
35
33
|
"scripts": {
|
|
36
|
-
"build": "pnpm --filter @antpath/cli run build && tsc -p tsconfig.build.json && node ./scripts/bundle-cli.mjs",
|
|
34
|
+
"build": "pnpm --filter @antpath/cli run build && pnpm --filter @antpath/shared run build && tsc -p tsconfig.build.json && node ./scripts/bundle-cli.mjs && node ./scripts/inline-shared.mjs",
|
|
37
35
|
"lint": "tsc --noEmit",
|
|
38
36
|
"test": "vitest run test/unit",
|
|
39
37
|
"test:unit": "vitest run test/unit",
|
package/dist/credentials.d.ts
DELETED
package/dist/credentials.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { CredentialValidationError } from "./errors.js";
|
|
2
|
-
export function validateCredentials(template, credentials = {}) {
|
|
3
|
-
for (const [key, requirement] of Object.entries(template.credentialRequirements)) {
|
|
4
|
-
const credential = credentials[key];
|
|
5
|
-
if (credential === undefined) {
|
|
6
|
-
throw new CredentialValidationError(`Missing credential for MCP server '${key}'`);
|
|
7
|
-
}
|
|
8
|
-
if (!isRecord(credential)) {
|
|
9
|
-
throw new CredentialValidationError(`Credential for MCP server '${key}' must be an object`);
|
|
10
|
-
}
|
|
11
|
-
if (credential.type !== requirement.type) {
|
|
12
|
-
throw new CredentialValidationError(`Credential for MCP server '${key}' must be '${requirement.type}'`);
|
|
13
|
-
}
|
|
14
|
-
validateCredentialValue(key, credential);
|
|
15
|
-
}
|
|
16
|
-
for (const key of Object.keys(credentials)) {
|
|
17
|
-
if (!template.credentialRequirements[key]) {
|
|
18
|
-
throw new CredentialValidationError(`Credential provided for unknown MCP server '${key}'`);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
function validateCredentialValue(key, credential) {
|
|
23
|
-
if (!isRecord(credential)) {
|
|
24
|
-
throw new CredentialValidationError(`Credential for MCP server '${key}' must be an object`);
|
|
25
|
-
}
|
|
26
|
-
if (credential.type === "static_bearer") {
|
|
27
|
-
assertAllowedFields(key, credential, ["type", "token"]);
|
|
28
|
-
if (typeof credential.token !== "string" || credential.token.length === 0) {
|
|
29
|
-
throw new CredentialValidationError(`Static bearer credential for '${key}' requires token`);
|
|
30
|
-
}
|
|
31
|
-
return;
|
|
32
|
-
}
|
|
33
|
-
if (credential.type === "oauth_access_token") {
|
|
34
|
-
assertAllowedFields(key, credential, ["type", "accessToken", "expiresAt"]);
|
|
35
|
-
if (typeof credential.accessToken !== "string" || credential.accessToken.length === 0) {
|
|
36
|
-
throw new CredentialValidationError(`OAuth credential for '${key}' requires accessToken`);
|
|
37
|
-
}
|
|
38
|
-
if (credential.expiresAt !== undefined && (typeof credential.expiresAt !== "string" || credential.expiresAt.length === 0)) {
|
|
39
|
-
throw new CredentialValidationError(`OAuth credential for '${key}' has invalid expiresAt`);
|
|
40
|
-
}
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
throw new CredentialValidationError(`Credential for MCP server '${key}' has unsupported type`);
|
|
44
|
-
}
|
|
45
|
-
function assertAllowedFields(key, credential, allowed) {
|
|
46
|
-
const allowedSet = new Set(allowed);
|
|
47
|
-
for (const field of Object.keys(credential)) {
|
|
48
|
-
if (!allowedSet.has(field)) {
|
|
49
|
-
throw new CredentialValidationError(`Credential for MCP server '${key}' contains unsupported field '${field}'`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
function isRecord(input) {
|
|
54
|
-
return typeof input === "object" && input !== null && !Array.isArray(input);
|
|
55
|
-
}
|
|
56
|
-
//# sourceMappingURL=credentials.js.map
|
package/dist/credentials.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AASnD,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,IAAI,CAAmB;IACvB,OAAO,CAAW;IAE3B,YAAY,IAAsB,EAAE,OAAe,EAAE,OAAiB;QACpE,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;QAClC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC5E,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,YAAY;IACvD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,kBAAkB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,OAAO,yBAA0B,SAAQ,YAAY;IACzD,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,oBAAoB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IACpC,MAAM,CAAqB;IAEpC,YAAY,OAAe,EAAE,UAAkD,EAAE;QAC/E,KAAK,CAAC,gBAAgB,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,aAAc,SAAQ,YAAY;IAC7C,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,iBAAiB,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,YAAY;IAC5C,YAAY,OAAe,EAAE,OAAiB;QAC5C,KAAK,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3C,CAAC;CACF"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { DownloadOutputsOptions, DownloadOutputsResult } from "../types.js";
|
|
2
|
-
import type { ManagedAgentProvider } from "../providers/types.js";
|
|
3
|
-
export declare function downloadOutputs(provider: ManagedAgentProvider, sessionId: string, options: DownloadOutputsOptions): Promise<DownloadOutputsResult>;
|
package/dist/files/downloader.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { writeFileSafe } from "../utils/paths.js";
|
|
2
|
-
const DEFAULT_MAX_FILES = 100;
|
|
3
|
-
const DEFAULT_MAX_BYTES = 250 * 1024 * 1024;
|
|
4
|
-
export async function downloadOutputs(provider, sessionId, options) {
|
|
5
|
-
const files = filterFiles(await provider.listFiles(sessionId), options);
|
|
6
|
-
if (files.length > (options.maxFiles ?? DEFAULT_MAX_FILES)) {
|
|
7
|
-
throw new Error(`Refusing to download ${files.length} files; maxFiles exceeded`);
|
|
8
|
-
}
|
|
9
|
-
const totalBytes = files.reduce((sum, file) => sum + (file.sizeBytes ?? 0), 0);
|
|
10
|
-
if (totalBytes > (options.maxTotalBytes ?? DEFAULT_MAX_BYTES)) {
|
|
11
|
-
throw new Error(`Refusing to download ${totalBytes} bytes; maxTotalBytes exceeded`);
|
|
12
|
-
}
|
|
13
|
-
const manifest = { directory: options.directory, files: [] };
|
|
14
|
-
let downloadedBytes = 0;
|
|
15
|
-
for (const file of files) {
|
|
16
|
-
const content = await provider.downloadFile(file.id);
|
|
17
|
-
if (file.sizeBytes !== undefined && content.byteLength !== file.sizeBytes) {
|
|
18
|
-
throw new Error(`Downloaded byte size for ${file.id} did not match provider metadata`);
|
|
19
|
-
}
|
|
20
|
-
downloadedBytes += content.byteLength;
|
|
21
|
-
if (downloadedBytes > (options.maxTotalBytes ?? DEFAULT_MAX_BYTES)) {
|
|
22
|
-
throw new Error(`Downloaded outputs exceeded maxTotalBytes`);
|
|
23
|
-
}
|
|
24
|
-
const localPath = await writeFileSafe(options.directory, file.filename, content);
|
|
25
|
-
const entry = {
|
|
26
|
-
providerFileId: file.id,
|
|
27
|
-
filename: file.filename,
|
|
28
|
-
localPath
|
|
29
|
-
};
|
|
30
|
-
manifest.files.push(file.sizeBytes === undefined ? entry : { ...entry, sizeBytes: file.sizeBytes });
|
|
31
|
-
}
|
|
32
|
-
return { manifest };
|
|
33
|
-
}
|
|
34
|
-
function filterFiles(files, options) {
|
|
35
|
-
if (!options.include) {
|
|
36
|
-
return files;
|
|
37
|
-
}
|
|
38
|
-
if (options.include instanceof RegExp) {
|
|
39
|
-
return files.filter((file) => options.include instanceof RegExp && options.include.test(file.filename));
|
|
40
|
-
}
|
|
41
|
-
return files.filter(options.include);
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=downloader.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"downloader.js","sourceRoot":"","sources":["../../src/files/downloader.ts"],"names":[],"mappings":"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"}
|