@oxy-hq/cli 0.7.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 +131 -8
  2. package/dist/main.mjs +4909 -3551
  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 +37 -4
  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
@@ -1,6 +1,13 @@
1
1
  ---
2
2
  name: oxy-automations
3
- description: Use when writing, debugging, or reviewing an Oxy automation (a `.automation.yml` / legacy `.procedure.yml` workflow — tasks, loops, variables, schedules) in a customer workspace, or when an automation *run* misbehaves: an `http_request` task that works locally and fails in cloud, a file that is silently not an automation, or an automation run landing `completed_with_errors`. Covers the file-naming trap, task-type gotchas, and where the authoritative reference lives.
3
+ description: >-
4
+ Use when writing, debugging, or reviewing an Oxy automation (a `.automation.yml` / legacy
5
+ `.procedure.yml` workflow — tasks, loops, variables, schedules) in a customer workspace, or when
6
+ an automation *run* misbehaves: an `http_request` task that works locally and fails in cloud, a
7
+ file that is silently not an automation, a task that validates but fails with "unknown task
8
+ type", SQL that receives JSON instead of a table, or an automation run landing
9
+ `completed_with_errors`. Covers the file-naming trap, task-type gotchas, running SQL and
10
+ automations from the `oxy` CLI, and where the authoritative reference lives.
4
11
  ---
5
12
 
6
13
  # Oxy automations
@@ -18,12 +25,13 @@ The canonical extension is **`.automation.yml`**.
18
25
 
19
26
  - `.procedure.yml` is the **legacy** name. It is still accepted, so a workspace
20
27
  full of it keeps working and nothing warns you — which is exactly why it
21
- spreads. Poke House's workspace has 18 automations, and every one of them is
22
- still `.procedure.yml`.
28
+ spreads. One production workspace has 18 automations, and every one of them
29
+ is still `.procedure.yml`.
23
30
  - `.workflow.yml` is **no longer a recognised file kind at all**. A file with
24
- that name is silently not an automation.
25
- - `oxy migrate-automations` exists to rename legacy files. It is the only thing
26
- that reads them for that purpose.
31
+ that name is silently not an automation, and `oxy run` refuses it.
32
+ - `oxy migrate-automations` renames legacy files (and rewrites references to
33
+ them); `--dry-run` previews. It is the only thing that reads `.workflow.yml`
34
+ files for that purpose.
27
35
 
28
36
  **Write new files as `.automation.yml`.** Do not copy the extension from a
29
37
  neighbouring file in the workspace you are editing — that is how the legacy name
@@ -32,16 +40,31 @@ propagated in the first place.
32
40
  ## Naming, and why the code disagrees with the docs
33
41
 
34
42
  "Automation" is the current name for what used to be called a Procedure, and
35
- before that a Workflow. The Rust types still say `Workflow*` / `Procedure*`, and
36
- `type: workflow` plus the `agentic_workflow_state` table are **wire and storage
37
- contracts** — they are not stale naming to be tidied up. Seeing `workflow` in the
38
- code or in a payload does not mean you are looking at something deprecated.
43
+ before that a Workflow. The sub-automation task is still `type: workflow`, and
44
+ API payloads and stored run records still say `workflow` — those are **wire and
45
+ storage contracts**, not stale naming to be tidied up. Seeing `workflow` in a
46
+ payload does not mean you are looking at something deprecated.
39
47
 
40
48
  Routes follow the same split: `/automations/:id` is canonical;
41
49
  `/workflows/:id`, `/procedures`, and `/agentic-workflows` are aliases.
42
50
 
43
51
  ## Task-type gotchas
44
52
 
53
+ - **A misspelled `type:` passes validation and fails only at run time.** An
54
+ unrecognised task type — `type: sql`, `type: execute` — is read as an
55
+ "unknown" step rather than rejected, so `oxy validate` reports the file valid
56
+ and the run fails on that step with `unknown task type`. Check every `type:`
57
+ against the task-types page by eye, then *run* the automation; validation
58
+ alone proves nothing here. (A wrong *field* inside a known type, such as
59
+ `query:` instead of `sql_query:`, does fail validation.)
60
+ - **`{{ step_name }}` renders as JSON rows, not as a table.** A prior SQL
61
+ step's result renders into a template as a compact JSON list of row objects
62
+ (`[{"region": "west", "total": 42}, …]`). That is what an `agent` or
63
+ `formatter` prompt wants, and what a loop iterates over — but `SELECT … FROM
64
+ {{ extract }}` sends that JSON to the warehouse as SQL and fails. To chain SQL
65
+ steps, either inline the earlier query as a CTE in the later step, or have
66
+ the earlier step write a table (`CREATE OR REPLACE TABLE …`) and read the
67
+ table by name.
45
68
  - **`http_request` is HTTPS-only and blocks private egress.** Requests to
46
69
  localhost, cloud-metadata endpoints, and private IP ranges are refused unless
47
70
  that task opts in with `allow_hosts`. A task that works locally and fails in
@@ -50,17 +73,40 @@ Routes follow the same split: `/automations/:id` is canonical;
50
73
  as `completed_with_errors`, not as a failed run. Code and dashboards that only
51
74
  check for "failed" will report it as a success.
52
75
 
76
+ ## Running locally with `oxy run`
77
+
78
+ `oxy run <file>` takes a `.sql` file, an `.automation.yml`, or a
79
+ `.procedure.yml` — nothing else.
80
+
81
+ - **SQL files:** `oxy run report.sql --database warehouse -v start=2024-01-01
82
+ -v region=west`. `--database` picks a database from `config.yml` (default:
83
+ the configured default database). `-v` / `--variables` fills Jinja
84
+ placeholders, and those `-v` values are the **entire** template context —
85
+ nothing else (no database or schema objects) is available inside the SQL.
86
+ `--dry-run` previews the rendered SQL without executing it.
87
+ - **No `-v` means no rendering at all.** Run a templated `.sql` file without a
88
+ single `-v` and its `{{ … }}` placeholders reach the warehouse literally, as
89
+ a syntax error. Pass at least one variable whenever the file has
90
+ placeholders.
91
+ - **`--dry-run` and `-v` are ignored for automations.** Both apply to `.sql`
92
+ files only. `oxy run x.automation.yml --dry-run` executes the automation for
93
+ real — every write, every `http_request` — and uses the file's own
94
+ `variables:` defaults whatever `-v` says. To check an automation without side
95
+ effects, run its SQL files individually with `--dry-run`.
96
+ - `--retry` and `--retry-from <step>` are accepted but currently have no effect
97
+ on an automation run; a failed run is re-run from the top.
98
+
53
99
  ## Before you write one
54
100
 
55
101
  Check whether the work belongs in an automation at all. Scheduled data movement
56
102
  is usually an Airway pipeline (`.airway.yml`); a question answered from the
57
- semantic layer is usually an agent or a Data App. Automations are for
103
+ semantic model is usually an agent or a Data App. Automations are for
58
104
  multi-step orchestration you want to run on a schedule or trigger.
59
105
 
60
- **But "usually a pipeline" is not "never an automation", and the seam is
61
- undocumented.** There is a `type: airway` task that runs a pipeline as a step —
62
- absent from the task-types page — and a step completes only once the pipeline's
63
- end-of-load fold has committed. That is what makes the standard
106
+ **But "usually a pipeline" is not "never an automation".** A `type: airway`
107
+ task runs a pipeline as a step, and the step completes only once the
108
+ pipeline's load has committed — the task-types page documents the task, but not
109
+ why that guarantee matters. It is what makes the standard
64
110
  ingest-then-aggregate automation safe: `type: airway` followed by
65
111
  `type: execute_sql` building a rollup table. Reach for it whenever a dashboard
66
112
  would otherwise aggregate at query time. **`oxy-data-architecture`** owns that
@@ -68,13 +68,21 @@ never sent to the server as a literal.
68
68
 
69
69
  oxyc validate # check the workspace YAML — no network, no token
70
70
  oxyc proxy --env dev # local app dev against cloud data
71
+ oxyc login-link --next /ide # one-time URL that signs a browser in as your token
71
72
  oxyc guide # this page, to paste into a context file
72
73
 
73
74
  `oxyc validate` is the one command that works entirely offline. It checks
74
75
  `config.yml`, `.automation.yml`, `.agentic.yml`, `.app.yml` and
75
76
  `.agent.test.yml` against the schemas the Rust config types generate. It is
76
- STRUCTURAL only — `oxy validate` also resolves `databases:` and `llm.ref`, and
77
- wins where the two disagree.
77
+ STRUCTURAL only — `oxy validate` additionally checks an automation's or app's
78
+ `database:` names against `config.yml`, but it too is structural for
79
+ `.agentic.yml` (`databases:` and `llm.ref` are not resolved), so an agent both
80
+ accept can still fail at run time.
81
+
82
+ To look at a deployed environment in a browser, navigate your browser tool to
83
+ `$(oxyc login-link --env dev --next /ide)`. It is a one-time link that signs
84
+ the browser in as your token — no OAuth, no inbox — and it needs a personal
85
+ access token: an agent token (below) is one, and so is what `oxyc login` stores.
78
86
 
79
87
  If your runtime speaks MCP, `oxyc mcp` serves the same API surface as four
80
88
  tools (`oxy_routes`, `oxy_schema`, `oxy_request`, `oxy_whoami`) instead. It
@@ -82,6 +90,31 @@ reads its credential from `OXY_TOKEN` only — with the variable unset it exits
82
90
  `4` rather than using the machine's `oxyc login`; `oxyc mcp --login` opts
83
91
  into that. The same holds for any command given `--token-env <VAR>`.
84
92
 
93
+ ## An agent's own credential
94
+
95
+ If you are an agent, run on your own token — never on the person's
96
+ `oxyc login`. Mint the one that fits the task; your operator approves it once
97
+ in the browser, and it is printed once and stored nowhere.
98
+
99
+ eval "$(oxyc tokens create --sandbox-agent --app <org>/<app> --env <deployment>)" # building a custom app in a sandbox
100
+ eval "$(oxyc tokens create --agent --env <deployment>)" # everything else
101
+
102
+ - **Sandbox agent token** (`oxy_sbx_…`): the sandboxes of the apps it names,
103
+ and nothing else on the deployment.
104
+ - **Agent token** (`oxy_pat_…`): everything your operator can reach, for hours
105
+ (`--hours`, default 8). Add `--standing` only when the task needs their staff
106
+ or partner access: they decide on the page, where it starts off, and a token
107
+ that comes back without it is still a success.
108
+ - **After a mint, pass `--token-env OXY_TOKEN` to every command.** A named
109
+ token variable is the only source, so a command that lost the variable (a new
110
+ shell, a subprocess started without it) exits `4` instead of silently running
111
+ on the person's cached login.
112
+ - `oxyc whoami --token-env OXY_TOKEN` says what you hold and when it ends.
113
+ `oxyc tokens revoke --current --token-env OXY_TOKEN` ends it when the task is
114
+ done.
115
+ - **Exit `4` on your own token means it expired or was revoked. Stop and
116
+ report.** Do not run `oxyc login`, and do not look for another credential.
117
+
85
118
  ## Custom apps: what is live, healthy, used
86
119
 
87
120
  Read-only — every request is a GET. `<app>` is `<org-slug>/<app-slug>` or an
@@ -111,7 +144,7 @@ app UUID; each command takes `--json`.
111
144
  | --- | --- |
112
145
  | `0` | fine |
113
146
  | `2` | you called it wrong — fix the command, do not retry |
114
- | `4` | not authenticated → `oxyc login --env <env>`, or the token expired |
147
+ | `4` | not authenticated. A person: `oxyc login --env <env>`. An agent on its own token: the token ended — stop and report, never log in |
115
148
  | `5` | 404 — check the path with `oxyc routes`. In an **admin** surface a 404 can be a scope boundary, not a missing row. |
116
149
  | `6` | the request was malformed — check `oxyc schema` |
117
150
  | `7` | 5xx / timeout / network — **retryable** |
@@ -134,7 +167,7 @@ app UUID; each command takes `--json`.
134
167
  - **A listed route can still 404** if it is `ide-only` or `worker-only`; those
135
168
  are hidden by default and shown by `oxyc routes --all`.
136
169
  - **Pick the environment deliberately.** `--env local|dev|staging|production`
137
- (default production), or paste a URL: `--env https://poke-house.oxygen-hq.com`
170
+ (default production), or paste a URL: `--env https://your-org.oxygen-hq.com`
138
171
  targets that deployment *and* sets `{org}`.
139
172
  - **Staff hitting a tenant surface need an assume-role session.** A 403 there
140
173
  usually means no active session, not a mis-modeled role — check with