@oxy-hq/cli 0.8.0 → 0.9.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 (38) hide show
  1. package/README.md +89 -7
  2. package/dist/main.mjs +4914 -3760
  3. package/dist/main.mjs.map +1 -1
  4. package/dist/{mcp-xxWL3_dz.mjs → mcp-Bdp0rX0l.mjs} +2 -2
  5. package/dist/{mcp-xxWL3_dz.mjs.map → mcp-Bdp0rX0l.mjs.map} +1 -1
  6. package/package.json +5 -5
  7. package/skills/oxy-agents/SKILL.md +318 -0
  8. package/skills/oxy-agents/references/quick-reference.md +222 -0
  9. package/skills/oxy-agents/templates/agentic-template.yml +141 -0
  10. package/skills/oxy-airway-pipelines/SKILL.md +223 -316
  11. package/skills/oxy-automations/SKILL.md +61 -15
  12. package/skills/oxy-cli/SKILL.md +32 -5
  13. package/skills/oxy-custom-apps/SKILL.md +193 -291
  14. package/skills/oxy-custom-apps/references/minimal-starter.md +63 -0
  15. package/skills/oxy-custom-apps/references/performance-and-usage.md +105 -0
  16. package/skills/oxy-custom-apps/references/reading-data.md +106 -0
  17. package/skills/oxy-custom-apps/references/sandbox-agent-loop.md +267 -0
  18. package/skills/oxy-custom-apps/references/verifying-in-the-browser.md +65 -0
  19. package/skills/oxy-data-apps/SKILL.md +362 -0
  20. package/skills/oxy-data-apps/references/examples.md +263 -0
  21. package/skills/oxy-data-apps/references/quick-reference.md +171 -0
  22. package/skills/oxy-data-apps/templates/dashboard-with-controls.app.yml +128 -0
  23. package/skills/oxy-data-apps/templates/simple-dashboard.app.yml +102 -0
  24. package/skills/oxy-data-architecture/SKILL.md +137 -152
  25. package/skills/oxy-evals/SKILL.md +362 -0
  26. package/skills/oxy-evals/references/diagnosis.md +243 -0
  27. package/skills/oxy-evals/references/results-json.md +145 -0
  28. package/skills/oxy-evals/references/writing-expected.md +112 -0
  29. package/skills/oxy-semantic-modeling/SKILL.md +239 -59
  30. package/skills/oxy-semantic-modeling/references/warehouse-casts.md +57 -0
  31. package/skills/oxy-semantic-modeling/templates/topic-template.yml +38 -0
  32. package/skills/oxy-semantic-modeling/templates/view-template.yml +119 -0
  33. package/template/.github/workflows/publish.yaml +15 -13
  34. package/template/.nvmrc +1 -1
  35. package/template/.oxyc-managed +5 -5
  36. package/template/README.md +21 -10
  37. package/template/package.json +3 -2
  38. package/template/pnpm-workspace.yaml +28 -17
package/README.md CHANGED
@@ -159,8 +159,23 @@ oxyc tokens revoke <id>
159
159
  oxyc tokens revoke --current # end the token in OXY_TOKEN
160
160
  oxyc tokens create # opens Account → Personal access tokens
161
161
  oxyc tokens create --sandbox-agent --app <org>/<app> [--app …] [--hours 8] [--name …]
162
+ oxyc tokens create --agent [--standing] [--hours 8] [--name …]
162
163
  ```
163
164
 
165
+ **An agent runs on its own token, never on the person's `oxyc login`.** Which
166
+ one depends on the task:
167
+
168
+ | The agent is… | It mints | Which reaches |
169
+ | --- | --- | --- |
170
+ | building a custom app in a sandbox | `tokens create --sandbox-agent --app …` (`oxy_sbx_…`) | the sandboxes of the apps it names, and nothing else |
171
+ | doing anything else: reading data with `oxyc api`, reproducing a bug against live data | `tokens create --agent` (`oxy_pat_…`) | everything its approver can, for hours |
172
+
173
+ Both are approved once in the browser by the person the agent works for, both
174
+ are printed once as `export OXY_TOKEN=…` and never stored, and both end with
175
+ `tokens revoke --current`. After a mint, pass `--token-env OXY_TOKEN` to every
176
+ command: a named variable is the only source, so a command that lost the
177
+ variable exits `4` instead of quietly running on the person's cached login.
178
+
164
179
  **Every command resolves its credential the same way, first match wins:**
165
180
 
166
181
  1. **`OXY_TOKEN`** (or the variable `--token-env` names). It holds any
@@ -168,7 +183,8 @@ oxyc tokens create --sandbox-agent --app <org>/<app> [--app …] [--hours 8] [--
168
183
  token (`oxy_pat_…`), a service account token (`oxy_sat_…`), a CI token
169
184
  (`oxy_ci_…`) or a sandbox agent token (`oxy_sbx_…`) — a legacy API key
170
185
  (`oxy_…`), a publish token, or a session token. A blank value counts as
171
- unset.
186
+ unset. An agent token is a personal access token by its prefix: only its
187
+ own description tells it from a login (`oxyc whoami`).
172
188
  2. **The login cache** — what `oxyc login` stored for this deployment.
173
189
  3. **GitHub OIDC**, in a GitHub Actions job granted `id-token: write`: the job's
174
190
  OIDC token is exchanged, once per process, for a fifteen-minute token acting
@@ -196,7 +212,7 @@ Settings → Workspace → Legacy API keys. Use an API token for anything new.
196
212
 
197
213
  **`login`** runs a browser loopback flow. Against a current deployment it
198
214
  receives a one-time code and exchanges it (PKCE) for a **personal access
199
- token** named `oxyc on <hostname>`: revocable, ninety days, and replacing that
215
+ token** named `oxyc on <hostname>`: revocable, a year, and replacing that
200
216
  machine's previous one. No credential travels in a URL. Against a deployment
201
217
  that predates the exchange it stores the session token the page hands back,
202
218
  exactly as before, and says so — nothing needs upgrading first, in either
@@ -212,7 +228,10 @@ rather than reading as fine from the cache. For a token it also prints what the
212
228
  token is and what it can reach — `all access`, or one line per grant with the
213
229
  role it is capped at, and any organization whose policy blocks it. For a legacy
214
230
  API key it prints `Legacy API key`, and that it reaches everything its owner
215
- can.
231
+ can. For an agent token it says `agent token`, who approved it, whether it
232
+ carries their staff or partner access, and when it expires. When a token in
233
+ `OXY_TOKEN` is refused (exit `4`), the advice is never to log in — a login
234
+ cannot replace what is in the variable. An agent stops and reports.
216
235
 
217
236
  **`token`** prints the bearer on stdout and nothing else. Inside a GitHub
218
237
  Actions job with nothing stored it prints the token the job's OIDC identity
@@ -276,6 +295,35 @@ A refusal from the server carries a hint an agent can act on — never "try
276
295
  `oxyc login` again". Exit `4` under this token means it expired, was revoked,
277
296
  or its minter lost access: stop and report.
278
297
 
298
+ **`tokens create --agent`** mints an **agent token** for everything that is not
299
+ a sandbox: a personal access token (`oxy_pat_…`) that reaches what its approver
300
+ reaches through their organization memberships, for 8 hours by default
301
+ (`--hours`, 1 to 168). It cannot be extended, edited or regenerated, and it
302
+ cannot create, extend or revoke tokens; it can open a browser session as itself
303
+ (`login-link`).
304
+
305
+ ```bash
306
+ eval "$(oxyc tokens create --agent --env dev)"
307
+ ```
308
+
309
+ The same browser loopback again, with the same guarantees: stdout is the single
310
+ line `export OXY_TOKEN=oxy_pat_…`, printed once, everything else is on stderr,
311
+ it holds no credential while it runs, never writes the credentials file and
312
+ revokes no other token. Arguments are checked before the browser opens (exit
313
+ `2`); `--agent` and `--sandbox-agent` together are a usage error.
314
+
315
+ `--standing` asks for the approver's staff or partner access as well. The
316
+ approver decides on the page, where it starts **off**: a token that comes back
317
+ without it is accepted, and stderr says so in one line. Without `--standing`, a
318
+ token that carries either is refused.
319
+
320
+ What comes back is checked before anything is printed: it must be a whole
321
+ `oxy_pat_`; it must describe itself (`GET /api/auth/token`) as `personal` with
322
+ `source` `oxyc_agent`; it must expire no later than the hours asked for; and it
323
+ must carry no standing that was not asked for. A deployment that predates agent
324
+ tokens would otherwise hand back an ordinary ninety-day login. On any mismatch
325
+ the command prints nothing, revokes what was minted, and exits `8`.
326
+
279
327
  Credentials live in the OS config directory under **`oxy`** — the same file the
280
328
  Rust `oxy login` wrote before it was removed, so an existing login still works:
281
329
 
@@ -548,7 +596,15 @@ lets it publish.
548
596
  *The workflow* is `.github/workflows/oxy-publish.yml` at the repo root: a
549
597
  `build` job (no id-token) that runs `publish --build-only`, and a `publish` job
550
598
  bound to a GitHub `environment:` (`--environment`, default `oxy-publish`) whose
551
- only work is `publish --prebuilt`. That job uses no third-party action: each
599
+ only work is `publish --prebuilt`. `build` installs pnpm with
600
+ `pnpm/action-setup@v6` — the pnpm the repo root's package.json pins
601
+ (`packageManager` or `devEngines.packageManager`), with no `version:` of its
602
+ own, since the action refuses a second, different one; pnpm 11 when nothing
603
+ pins it — and both jobs run the Node in `.nvmrc`, else 26 (pnpm 11 needs
604
+ Node 22.13 or later). It warns when nothing pins pnpm, and when
605
+ `pnpm-workspace.yaml` approves build scripts only with `onlyBuiltDependencies`,
606
+ which pnpm 11 ignores (the build's install would fail with
607
+ `ERR_PNPM_IGNORED_BUILDS`; move the entries to `allowBuilds`). The publish job uses no third-party action: each
552
608
  step runs `npx @oxy-hq/cli@<this version>` and `oxyc` exchanges the job's OIDC
553
609
  token for itself, acting as the service account `--service-account <org>/<name>`
554
610
  names — by default `<app's org>/deployer`. **Here, and only here, the account is
@@ -705,6 +761,26 @@ object to stdout instead:
705
761
  { "app": "acme/dashboards", "appId": "…", "checks": [{ "name": "canary", "runId": "…", "status": "done", "passed": true, "durationMs": 4123 }] }
706
762
  ```
707
763
 
764
+ **`--browser`** also loads the app's page in headless Chromium and proves it
765
+ mounted: the platform runtime's `oxy-app-ready` beacon fires, nothing on the
766
+ page throws, and `--expect-selector <css>` (optional) becomes visible. With
767
+ `--app-env` the page must also report that environment and the build it serves
768
+ (`oxyc env show`'s `build_uuid`) in `window.__OXY_APP__`. The credential and
769
+ `X-Oxy-App-Env` ride only on requests under the app's own base path
770
+ (`/customer-apps/<org>/<app>/`: the document, assets, beacon and `/fn` calls).
771
+ The rest of the deployment's API is on the same origin, and the code under test
772
+ is often a build someone else published, so its `/api/…` calls go without the
773
+ credential, as an anonymous visitor's would. The result is one more entry in `checks[]`, with `"kind": "browser"` and
774
+ the `/fn` calls the page made. Playwright is not a dependency: it is resolved
775
+ from the working directory (`playwright`, `playwright-core` or
776
+ `@playwright/test`), so run it where one is installed. The page loads as a
777
+ user, so a publish, service-account, CI or sandbox agent token is refused
778
+ before any request.
779
+
780
+ ```bash
781
+ oxyc checks run acme/store --app-env dev-a1 --browser --expect-selector 'main'
782
+ ```
783
+
708
784
  **Auth** follows the same rule as `oxyc api`'s bearer surface, with one
709
785
  difference: `checks run` talks to `/api/admin/**`, which is not the
710
786
  `/external/api/*` surface, so a configured API key is sent explicitly as
@@ -1021,9 +1097,12 @@ them, and a tool that can only fail still costs its schema every turn. A dead
1021
1097
  token ends the server at startup with exit `4`.
1022
1098
 
1023
1099
  **`guide`** prints a page to paste into `AGENTS.md` / `CLAUDE.md`.
1024
- **`skills install`** symlinks the six bundled Claude skills into
1100
+ **`skills install`** symlinks the bundled Oxy platform skills into
1025
1101
  `~/.claude/skills`; it refuses to run from an `npx` cache, whose symlinks dangle
1026
- once npm reclaims it.
1102
+ once npm reclaims it. The same skills are published to
1103
+ [`oxy-hq/skills`](https://github.com/oxy-hq/skills) for every other agent —
1104
+ `npx skills add oxy-hq/skills`, or the Claude Code plugin `oxy@oxy-hq`. They are
1105
+ written in `skills/` here; see `internal-docs/platform-skills.md`.
1027
1106
 
1028
1107
  ## Exit codes
1029
1108
 
@@ -1039,7 +1118,10 @@ once npm reclaims it.
1039
1118
  9 a check ran and failed or timed out (`oxyc checks run`)
1040
1119
  ```
1041
1120
 
1042
- `4` almost always means the wrong `--env`. `7` is worth retrying; `6` never is.
1121
+ `4` almost always means the wrong `--env`. A person logs in again. An agent on
1122
+ its own token (`tokens create --agent` or `--sandbox-agent`) does not: there,
1123
+ `4` means the token expired or was revoked, and the agent stops and reports.
1124
+ `7` is worth retrying; `6` never is.
1043
1125
 
1044
1126
  ## Environment variables
1045
1127