@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.
- package/README.md +131 -8
- package/dist/main.mjs +4909 -3551
- package/dist/main.mjs.map +1 -1
- package/dist/{mcp-xxWL3_dz.mjs → mcp-Bdp0rX0l.mjs} +2 -2
- package/dist/{mcp-xxWL3_dz.mjs.map → mcp-Bdp0rX0l.mjs.map} +1 -1
- package/package.json +5 -5
- package/skills/oxy-agents/SKILL.md +318 -0
- package/skills/oxy-agents/references/quick-reference.md +222 -0
- package/skills/oxy-agents/templates/agentic-template.yml +141 -0
- package/skills/oxy-airway-pipelines/SKILL.md +223 -316
- package/skills/oxy-automations/SKILL.md +61 -15
- package/skills/oxy-cli/SKILL.md +37 -4
- package/skills/oxy-custom-apps/SKILL.md +193 -291
- package/skills/oxy-custom-apps/references/minimal-starter.md +63 -0
- package/skills/oxy-custom-apps/references/performance-and-usage.md +105 -0
- package/skills/oxy-custom-apps/references/reading-data.md +106 -0
- package/skills/oxy-custom-apps/references/sandbox-agent-loop.md +267 -0
- package/skills/oxy-custom-apps/references/verifying-in-the-browser.md +65 -0
- package/skills/oxy-data-apps/SKILL.md +362 -0
- package/skills/oxy-data-apps/references/examples.md +263 -0
- package/skills/oxy-data-apps/references/quick-reference.md +171 -0
- package/skills/oxy-data-apps/templates/dashboard-with-controls.app.yml +128 -0
- package/skills/oxy-data-apps/templates/simple-dashboard.app.yml +102 -0
- package/skills/oxy-data-architecture/SKILL.md +137 -152
- package/skills/oxy-evals/SKILL.md +362 -0
- package/skills/oxy-evals/references/diagnosis.md +243 -0
- package/skills/oxy-evals/references/results-json.md +145 -0
- package/skills/oxy-evals/references/writing-expected.md +112 -0
- package/skills/oxy-semantic-modeling/SKILL.md +239 -59
- package/skills/oxy-semantic-modeling/references/warehouse-casts.md +57 -0
- package/skills/oxy-semantic-modeling/templates/topic-template.yml +38 -0
- package/skills/oxy-semantic-modeling/templates/view-template.yml +119 -0
- package/template/.github/workflows/publish.yaml +15 -13
- package/template/.nvmrc +1 -1
- package/template/.oxyc-managed +5 -5
- package/template/README.md +21 -10
- package/template/package.json +3 -2
- package/template/pnpm-workspace.yaml +28 -17
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oxy-automations
|
|
3
|
-
description:
|
|
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.
|
|
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`
|
|
26
|
-
|
|
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
|
|
36
|
-
|
|
37
|
-
contracts
|
|
38
|
-
|
|
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
|
|
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"
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
package/skills/oxy-cli/SKILL.md
CHANGED
|
@@ -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`
|
|
77
|
-
|
|
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
|
|
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://
|
|
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
|