pylot-cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # pylot — the Pylot gateway CLI
2
2
 
3
3
  First-class CLI for the Pylot gateway API (epic #1802). Replaces every curl
4
- workflow — dispatching missions, tailing logs, crew/admin/secrets management —
4
+ workflow — dispatching missions, tailing logs, team/admin/secrets management —
5
5
  for both AI operators (`claude -p` sessions, subagents) and humans.
6
6
 
7
7
  ```
@@ -41,7 +41,8 @@ the bundle in at `/usr/local/bin/pylot`.
41
41
  - **Destructive commands** (`kill`, `cancel`, `delete`, `revoke`, …) require
42
42
  `--force` and send nothing without it.
43
43
  - Single-file bundle (`dist/index.mjs`, esbuild) — no runtime `node_modules`.
44
- Runtime deps are `commander` + `conf` only; no interactive/prompt libraries.
44
+ `commander` + `conf` are compiled in (a global install pulls zero packages);
45
+ no interactive/prompt libraries.
45
46
 
46
47
  ## Configuration
47
48
 
@@ -78,7 +79,7 @@ Run `pylot --help` (or `pylot <group> --help`) for the full tree.
78
79
  | `costs` `executor` `audits` `pricing` `logs` | cost reporting, executor sweeps, audit corpus, model pricing, infra logs |
79
80
  | `workers` `devboxes` | devbox workers and standalone devboxes |
80
81
  | `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
+ | `teams` `route` | team config, operator instructions, role skills, crons, ledger, playbooks, goals |
82
83
  | `admin` | config, audit, org caps, migrations |
83
84
  | `deploy` | POST /admin/deploy + CodeBuild polling (`--wait`), image builds |
84
85
  | `secrets` | path-based ASM bundle/key operations |
package/dist/index.mjs CHANGED
@@ -15177,23 +15177,23 @@ function registerConversations(program3) {
15177
15177
  });
15178
15178
  }
15179
15179
 
15180
- // src/commands/crew.mts
15180
+ // src/commands/teams.mts
15181
15181
  async function readText(file) {
15182
15182
  const { readFileSync } = await import("node:fs");
15183
15183
  return file === "-" ? readFileSync(0, "utf8") : readFileSync(file, "utf8");
15184
15184
  }
15185
- function registerCrew(program3) {
15186
- const crew = program3.command("crew").description("team config, operators, playbooks, goals, ledger");
15187
- crew.command("list").description("crew roster (GET /crew); --db for the raw DB view (GET /crew/_db)").option("--db", "DB-authoritative view (GET /crew/_db)").action(async (flags, cmd) => {
15185
+ function registerTeams(program3) {
15186
+ const teams = program3.command("teams").description("team config, operators, playbooks, goals, ledger");
15187
+ teams.command("list").description("team roster (GET /crew); --db for the raw DB view (GET /crew/_db)").option("--db", "DB-authoritative view (GET /crew/_db)").action(async (flags, cmd) => {
15188
15188
  const { opts, cfg } = await ctx(cmd);
15189
15189
  emit(opts, await request(cfg, flags.db ? "/crew/_db" : "/crew"));
15190
15190
  });
15191
- crew.command("update").description("patch team config fields (PATCH /admin/crew/:team)").argument("<team>").argument("[fields...]", "key=value pairs (e.g. max_concurrent=3 enabled=true)").option("--file <path>", "JSON body from file ('-' for stdin)").action(async (team, fields, flags, cmd) => {
15191
+ teams.command("update").description("patch team config fields (PATCH /admin/crew/:team)").argument("<team>").argument("[fields...]", "key=value pairs (e.g. max_concurrent=3 enabled=true)").option("--file <path>", "JSON body from file ('-' for stdin)").action(async (team, fields, flags, cmd) => {
15192
15192
  const { opts, cfg } = await ctx(cmd);
15193
15193
  const body = await bodyFromArgs(fields, flags.file);
15194
15194
  emit(opts, await request(cfg, `/admin/crew/${encodeURIComponent(team)}`, { method: "PATCH", body }));
15195
15195
  });
15196
- crew.command("delete").description("delete a team (DELETE /admin/crew/:team?confirm=true)").argument("<team>").option("--force", "required to confirm deletion").action(async (team, flags, cmd) => {
15196
+ teams.command("delete").description("delete a team (DELETE /admin/crew/:team?confirm=true)").argument("<team>").option("--force", "required to confirm deletion").action(async (team, flags, cmd) => {
15197
15197
  const { opts, cfg } = await ctx(cmd);
15198
15198
  if (!flags.force) throw new UsageError("deleting a team is destructive \u2014 re-run with --force");
15199
15199
  emit(
@@ -15204,7 +15204,7 @@ function registerCrew(program3) {
15204
15204
  })
15205
15205
  );
15206
15206
  });
15207
- crew.command("instructions").description("operator instructions text (GET /admin/crew/:team/operators/:role/instructions); --set --file to replace").argument("<team>").argument("<role>").option("--set", "replace the instructions (PUT, raw text body)").option("--file <path>", "text from file ('-' for stdin; required with --set)").action(async (team, role, flags, cmd) => {
15207
+ teams.command("instructions").description("operator instructions text (GET /admin/crew/:team/operators/:role/instructions); --set --file to replace").argument("<team>").argument("<role>").option("--set", "replace the instructions (PUT, raw text body)").option("--file <path>", "text from file ('-' for stdin; required with --set)").action(async (team, role, flags, cmd) => {
15208
15208
  const { opts, cfg } = await ctx(cmd);
15209
15209
  const path5 = `/admin/crew/${encodeURIComponent(team)}/operators/${encodeURIComponent(role)}/instructions`;
15210
15210
  if (flags.set) {
@@ -15214,7 +15214,7 @@ function registerCrew(program3) {
15214
15214
  }
15215
15215
  emit(opts, await request(cfg, path5));
15216
15216
  });
15217
- crew.command("skills-add").description("add one skill to an operator (POST /admin/crew/:team/operators/:role/skills, body {skill, repo?, ref?})").argument("<team>").argument("<role>").argument("<skill>").option("--repo <org/repo>", "source repo \u2014 required when the skill is not yet in the org catalog").option("--ref <ref>", "source ref for fetch-on-add").action(async (team, role, skill, flags, cmd) => {
15217
+ teams.command("skills-add").description("add one skill to an operator (POST /admin/crew/:team/operators/:role/skills, body {skill, repo?, ref?})").argument("<team>").argument("<role>").argument("<skill>").option("--repo <org/repo>", "source repo \u2014 required when the skill is not yet in the org catalog").option("--ref <ref>", "source ref for fetch-on-add").action(async (team, role, skill, flags, cmd) => {
15218
15218
  const { opts, cfg } = await ctx(cmd);
15219
15219
  const body = { skill };
15220
15220
  if (flags.repo) body.repo = flags.repo;
@@ -15227,7 +15227,7 @@ function registerCrew(program3) {
15227
15227
  })
15228
15228
  );
15229
15229
  });
15230
- crew.command("skills-remove").description("remove one skill from an operator (DELETE /admin/crew/:team/operators/:role/skills/:name)").argument("<team>").argument("<role>").argument("<skill>").option("--force", "required to confirm removal").action(async (team, role, skill, flags, cmd) => {
15230
+ teams.command("skills-remove").description("remove one skill from an operator (DELETE /admin/crew/:team/operators/:role/skills/:name)").argument("<team>").argument("<role>").argument("<skill>").option("--force", "required to confirm removal").action(async (team, role, skill, flags, cmd) => {
15231
15231
  const { opts, cfg } = await ctx(cmd);
15232
15232
  if (!flags.force) throw new UsageError("removing a skill is destructive \u2014 re-run with --force");
15233
15233
  emit(
@@ -15239,7 +15239,7 @@ function registerCrew(program3) {
15239
15239
  )
15240
15240
  );
15241
15241
  });
15242
- crew.command("crons").description("enable/disable one named cron entry (PATCH /admin/crew/:team/crons/:name)").argument("<team>").argument("<name>").option("--enable", "set enabled: true").option("--disable", "set enabled: false").action(async (team, name, flags, cmd) => {
15242
+ teams.command("crons").description("enable/disable one named cron entry (PATCH /admin/crew/:team/crons/:name)").argument("<team>").argument("<name>").option("--enable", "set enabled: true").option("--disable", "set enabled: false").action(async (team, name, flags, cmd) => {
15243
15243
  const { opts, cfg } = await ctx(cmd);
15244
15244
  if (Boolean(flags.enable) === Boolean(flags.disable)) {
15245
15245
  throw new UsageError("pass exactly one of --enable / --disable");
@@ -15252,7 +15252,7 @@ function registerCrew(program3) {
15252
15252
  })
15253
15253
  );
15254
15254
  });
15255
- crew.command("ledger").description("query team ledger entries (GET /admin/crew/:team/ledger)").argument("<team>").option("--type <type>", "heartbeat | dispatch | completion | event").option("--actor <actor>", "filter by actor").option("--days <n>", "lookback days (default 1)", (v) => parseInt(v, 10)).option("--limit <n>", "max rows (default 20)", (v) => parseInt(v, 10)).action(async (team, flags, cmd) => {
15255
+ teams.command("ledger").description("query team ledger entries (GET /admin/crew/:team/ledger)").argument("<team>").option("--type <type>", "heartbeat | dispatch | completion | event").option("--actor <actor>", "filter by actor").option("--days <n>", "lookback days (default 1)", (v) => parseInt(v, 10)).option("--limit <n>", "max rows (default 20)", (v) => parseInt(v, 10)).action(async (team, flags, cmd) => {
15256
15256
  const { opts, cfg } = await ctx(cmd);
15257
15257
  emit(
15258
15258
  opts,
@@ -15261,14 +15261,14 @@ function registerCrew(program3) {
15261
15261
  })
15262
15262
  );
15263
15263
  });
15264
- crew.command("ledger-add").description("insert a ledger entry (POST /admin/crew/:team/ledger)").argument("<team>").requiredOption("--type <type>", "heartbeat | dispatch | completion | event").requiredOption("--summary <text>", "entry summary").option("--actor <actor>", "attributed actor").option("--metadata-file <path>", "JSON metadata from file ('-' for stdin)").action(async (team, flags, cmd) => {
15264
+ teams.command("ledger-add").description("insert a ledger entry (POST /admin/crew/:team/ledger)").argument("<team>").requiredOption("--type <type>", "heartbeat | dispatch | completion | event").requiredOption("--summary <text>", "entry summary").option("--actor <actor>", "attributed actor").option("--metadata-file <path>", "JSON metadata from file ('-' for stdin)").action(async (team, flags, cmd) => {
15265
15265
  const { opts, cfg } = await ctx(cmd);
15266
15266
  const body = { type: flags.type, summary: flags.summary };
15267
15267
  if (flags.actor) body.actor = flags.actor;
15268
15268
  if (flags.metadataFile) body.metadata = JSON.parse(await readText(flags.metadataFile));
15269
15269
  emit(opts, await request(cfg, `/admin/crew/${encodeURIComponent(team)}/ledger`, { method: "POST", body }));
15270
15270
  });
15271
- crew.command("playbook").description("repo playbook text (GET /admin/playbooks/:org/repo); --set --file to replace").argument("<org/repo>").option("--set", "replace the playbook (PUT, raw text body)").option("--file <path>", "text from file ('-' for stdin; required with --set)").action(async (repo, flags, cmd) => {
15271
+ teams.command("playbook").description("repo playbook text (GET /admin/playbooks/:org/repo); --set --file to replace").argument("<org/repo>").option("--set", "replace the playbook (PUT, raw text body)").option("--file <path>", "text from file ('-' for stdin; required with --set)").action(async (repo, flags, cmd) => {
15272
15272
  const { opts, cfg } = await ctx(cmd);
15273
15273
  const path5 = `/admin/playbooks/${repo}`;
15274
15274
  if (flags.set) {
@@ -15278,7 +15278,7 @@ function registerCrew(program3) {
15278
15278
  }
15279
15279
  emit(opts, await request(cfg, path5));
15280
15280
  });
15281
- crew.command("goals").description(
15281
+ teams.command("goals").description(
15282
15282
  "team goals text (GET /admin/goals/:team); --set --file replaces (PUT raw text), --update --file appends the file text (PATCH JSON {append})"
15283
15283
  ).argument("<team>").option("--set", "replace the goals (PUT, raw text body)").option("--update", "append to the goals (PATCH, JSON {append: <file text>})").option("--file <path>", "text from file ('-' for stdin; required with --set/--update)").action(async (team, flags, cmd) => {
15284
15284
  const { opts, cfg } = await ctx(cmd);
@@ -15760,12 +15760,12 @@ function registerAssets(program3) {
15760
15760
  }
15761
15761
 
15762
15762
  // src/index.mts
15763
- var VERSION = true ? "0.1.0" : "0.0.0-dev";
15763
+ var VERSION = true ? "0.1.1" : "0.0.0-dev";
15764
15764
  installEpipeGuard();
15765
15765
  var program2 = new Command();
15766
15766
  program2.name("pylot").description(
15767
- "Pylot gateway CLI \u2014 dispatch missions, tail logs, manage crew/admin/secrets without curl.\nJSON on non-TTY stdout (pipe-friendly for agents and jq); tables on TTY."
15768
- ).version(VERSION).option("--url <url>", "gateway base URL (default: PYLOT_DISPATCH_URL / PYLOT_API_URL / PYLOT_GATEWAY_URL)").option("--token <token>", "bearer token (default: PYLOT_API_TOKEN / PYLOT_SESSION_JWT / PYLOT_BROKER_TOKEN / PYLOT_DISPATCH_TOKEN)").option("--env <env>", "target environment: prod | staging (staging uses PYLOT_STAGING_URL + PYLOT_STAGING_DISPATCH_TOKEN)").option("--json", "force JSON output even on a TTY").option("-q, --quiet", "suppress progress notes on stderr");
15767
+ "Pylot gateway CLI \u2014 dispatch missions, tail logs, manage teams/admin/secrets without curl.\nJSON on non-TTY stdout (pipe-friendly for agents and jq); tables on TTY."
15768
+ ).configureHelp({ sortSubcommands: true }).version(VERSION).option("--url <url>", "gateway base URL (default: PYLOT_DISPATCH_URL / PYLOT_API_URL / PYLOT_GATEWAY_URL)").option("--token <token>", "bearer token (default: PYLOT_API_TOKEN / PYLOT_SESSION_JWT / PYLOT_BROKER_TOKEN / PYLOT_DISPATCH_TOKEN)").option("--env <env>", "target environment: prod | staging (staging uses PYLOT_STAGING_URL + PYLOT_STAGING_DISPATCH_TOKEN)").option("--json", "force JSON output even on a TTY").option("-q, --quiet", "suppress progress notes on stderr");
15769
15769
  program2.exitOverride();
15770
15770
  program2.configureOutput({ outputError: (str, write) => write(str) });
15771
15771
  registerCore(program2);
@@ -15777,7 +15777,7 @@ registerObservability(program2);
15777
15777
  registerWorkers(program2);
15778
15778
  registerDevboxes(program2);
15779
15779
  registerConversations(program2);
15780
- registerCrew(program2);
15780
+ registerTeams(program2);
15781
15781
  registerAdmin(program2);
15782
15782
  registerDeploy(program2);
15783
15783
  registerSecrets(program2);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pylot-cli",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "type": "module",
5
5
  "description": "pylot — first-class CLI for the Pylot gateway API. Replaces curl workflows for operators and humans.",
6
6
  "bin": {
@@ -34,12 +34,10 @@
34
34
  "typecheck": "tsc --noEmit",
35
35
  "prepublishOnly": "npm run typecheck && npm run build"
36
36
  },
37
- "dependencies": {
38
- "commander": "^12.1.0",
39
- "conf": "^13.1.0"
40
- },
41
37
  "devDependencies": {
42
38
  "@types/node": "^22.10.0",
39
+ "commander": "^12.1.0",
40
+ "conf": "^13.1.0",
43
41
  "esbuild": "^0.25.0",
44
42
  "typescript": "^5.7.2"
45
43
  }