pylot-cli 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.
- package/README.md +133 -0
- package/dist/index.mjs +15799 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# pylot — the Pylot gateway CLI
|
|
2
|
+
|
|
3
|
+
First-class CLI for the Pylot gateway API (epic #1802). Replaces every curl
|
|
4
|
+
workflow — dispatching missions, tailing logs, crew/admin/secrets management —
|
|
5
|
+
for both AI operators (`claude -p` sessions, subagents) and humans.
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
pylot dispatch "fix the flaky gateway-cache test" --agent infra.lead --repo fellowship-dev/pylot --wait
|
|
9
|
+
pylot ps
|
|
10
|
+
pylot missions logs <job-id> --follow
|
|
11
|
+
pylot deploy --wait --env staging
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install -g pylot-cli
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Published on npm as [`pylot-cli`](https://www.npmjs.com/package/pylot-cli)
|
|
21
|
+
(Node 20+). The package ships a single self-contained bundle and **no
|
|
22
|
+
credentials**: it only talks to the gateway URL you configure, and every
|
|
23
|
+
request is authorized by a token your own gateway deployment mints. There is
|
|
24
|
+
no hosted signup or OAuth flow — if you don't hold a token for a gateway, the
|
|
25
|
+
CLI can't do anything ("closed by default"). Self-hosters: see
|
|
26
|
+
[SELF-HOSTING.md](../../SELF-HOSTING.md) for deploying a gateway and minting
|
|
27
|
+
the dispatch token.
|
|
28
|
+
|
|
29
|
+
Inside Pylot's own containers no install is needed — the operator image bakes
|
|
30
|
+
the bundle in at `/usr/local/bin/pylot`.
|
|
31
|
+
|
|
32
|
+
## Design contract
|
|
33
|
+
|
|
34
|
+
- **JSON on non-TTY stdout** (or `--json`): exactly one JSON document per
|
|
35
|
+
command — the *verbatim* gateway response body — newline-terminated. All
|
|
36
|
+
progress notes, hints, and errors go to stderr. `pylot missions list | jq .`
|
|
37
|
+
always works. While following logs, entries stream as NDJSON.
|
|
38
|
+
- **Tables on TTY** for list commands; pretty-printed JSON otherwise.
|
|
39
|
+
- **Exit codes**: `0` success, `1` API/runtime error, `2` usage error.
|
|
40
|
+
`missions wait` / `dispatch --wait` exit `0` only when the mission ends `done`.
|
|
41
|
+
- **Destructive commands** (`kill`, `cancel`, `delete`, `revoke`, …) require
|
|
42
|
+
`--force` and send nothing without it.
|
|
43
|
+
- Single-file bundle (`dist/index.mjs`, esbuild) — no runtime `node_modules`.
|
|
44
|
+
Runtime deps are `commander` + `conf` only; no interactive/prompt libraries.
|
|
45
|
+
|
|
46
|
+
## Configuration
|
|
47
|
+
|
|
48
|
+
Everything resolves from flags, then environment, then the config file
|
|
49
|
+
(`pylot config set …`, stored via `conf`; env vars always win).
|
|
50
|
+
|
|
51
|
+
| | resolution order |
|
|
52
|
+
|---|---|
|
|
53
|
+
| URL | `--url` → `PYLOT_DISPATCH_URL`¹ → `PYLOT_API_URL` → `PYLOT_GATEWAY_URL` → `PYLOT_API` → config file |
|
|
54
|
+
| Token | `--token` → `PYLOT_API_TOKEN` → `PYLOT_SESSION_JWT` → `PYLOT_BROKER_TOKEN` → `PYLOT_DISPATCH_TOKEN` → config file |
|
|
55
|
+
|
|
56
|
+
¹ historically holds the full `…/dispatch` endpoint URL — the CLI strips the
|
|
57
|
+
suffix automatically.
|
|
58
|
+
|
|
59
|
+
`--env staging` switches to `PYLOT_STAGING_URL` + `PYLOT_STAGING_DISPATCH_TOKEN`
|
|
60
|
+
(config keys `staging-url` / `staging-token`).
|
|
61
|
+
|
|
62
|
+
Inside Pylot containers the right credential is already injected (token plane
|
|
63
|
+
#1884): chat sessions get a session JWT (`PYLOT_API_TOKEN`), mission workers a
|
|
64
|
+
broker JWT (`PYLOT_BROKER_TOKEN`, scoped to git-token + heartbeat — it cannot
|
|
65
|
+
dispatch), operators the master token. `pylot auth status` shows which source
|
|
66
|
+
won and what the gateway thinks of it. On a `403 insufficient_scope` the CLI
|
|
67
|
+
tells you which scope is missing and how to get it.
|
|
68
|
+
|
|
69
|
+
## Command groups
|
|
70
|
+
|
|
71
|
+
Run `pylot --help` (or `pylot <group> --help`) for the full tree.
|
|
72
|
+
|
|
73
|
+
| Group | Covers |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `health` `stats` `events` | liveness, metrics, event ledger |
|
|
76
|
+
| `dispatch` | POST /dispatch with `--wait` / `--follow` |
|
|
77
|
+
| `missions` (`ps`) | list/view/wait/logs/session/deps/audit/report/complete/heartbeat/wake/update/cancel/kill |
|
|
78
|
+
| `costs` `executor` `audits` `pricing` `logs` | cost reporting, executor sweeps, audit corpus, model pricing, infra logs |
|
|
79
|
+
| `workers` `devboxes` | devbox workers and standalone devboxes |
|
|
80
|
+
| `conversations` (`convo`) | full conversation surface: messages, wakes, subscriptions, resources, devboxes, analytics |
|
|
81
|
+
| `crew` `route` | team config, operator instructions, role skills, crons, ledger, playbooks, goals |
|
|
82
|
+
| `admin` | config, audit, org caps, migrations |
|
|
83
|
+
| `deploy` | POST /admin/deploy + CodeBuild polling (`--wait`), image builds |
|
|
84
|
+
| `secrets` | path-based ASM bundle/key operations |
|
|
85
|
+
| `skills` `automations` `providers` `orgs` `assets` | skills catalog/sync, automation rules, provider chains, repo enablement, asset presign/publish |
|
|
86
|
+
| `auth` `config` `login` | identity (`auth status`), scoped tokens, git tokens, local config |
|
|
87
|
+
|
|
88
|
+
Notes on log streaming: SSE endpoints return 501 on the deployed (Lambda)
|
|
89
|
+
gateway, so `missions logs --follow` polls
|
|
90
|
+
`GET /missions/:id/logs/cloudwatch?since_time=<cursor>` — including 206
|
|
91
|
+
partial-fetch draining — and stops when the mission goes terminal. Identical
|
|
92
|
+
boundary timestamps can rarely duplicate a line (CloudWatch ms resolution).
|
|
93
|
+
|
|
94
|
+
Deliberately not covered (internal plumbing): `POST /webhook`, `/internal/*`,
|
|
95
|
+
`POST /admin/skills/commit`, `POST /cost-report`, worker-daemon turn routes
|
|
96
|
+
(`workers/poll|heartbeat|report`), `/admin/worker-keys`, `/admin/test/*`.
|
|
97
|
+
|
|
98
|
+
## Development
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
cd modules/cli
|
|
102
|
+
npm ci
|
|
103
|
+
npm run typecheck # tsc --noEmit (strict)
|
|
104
|
+
npm run build # esbuild → dist/index.mjs (executable)
|
|
105
|
+
node dist/index.mjs --help
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Integration tests live at the repo root (`tests/gateway-cli-*.test.mts`) and
|
|
109
|
+
run in the corpus gate (`./scripts/test.sh corpus`): they spawn a real hermetic
|
|
110
|
+
gateway (PGlite) and execute the **built** CLI against it — no mocked fetch.
|
|
111
|
+
`scripts/test.sh` builds the bundle before the test pass.
|
|
112
|
+
|
|
113
|
+
The operator image bakes the bundle in as `/usr/local/bin/pylot`
|
|
114
|
+
(see `Dockerfile.operator`); rebuild via `/image-builder operator`.
|
|
115
|
+
|
|
116
|
+
## Publishing to npm (maintainers)
|
|
117
|
+
|
|
118
|
+
The package is public on npm as `pylot-cli`. To cut a release:
|
|
119
|
+
|
|
120
|
+
1. Bump `version` in `modules/cli/package.json` (semver — the bundle embeds it
|
|
121
|
+
via `__CLI_VERSION__`, so `pylot --version` reports whatever you publish).
|
|
122
|
+
2. From `modules/cli/`: `npm publish --access public`. The `prepublishOnly`
|
|
123
|
+
hook runs the typecheck and a fresh build, and the `files` allowlist keeps
|
|
124
|
+
the tarball to `dist/index.mjs` + README only — no source, no lockfile.
|
|
125
|
+
3. Publishing requires an npm token with publish rights on `pylot-cli` — use
|
|
126
|
+
an **Automation** token (or a granular token with 2FA bypass) in CI;
|
|
127
|
+
interactive publishes prompt for the account OTP.
|
|
128
|
+
4. Verify: `npm view pylot-cli version` and
|
|
129
|
+
`npx -y pylot-cli@latest --version`.
|
|
130
|
+
|
|
131
|
+
Version discipline: any change to gateway routes that the CLI wraps should
|
|
132
|
+
land with a CLI bump in the same PR train, so the published CLI never lags
|
|
133
|
+
the deployed API surface.
|