@revos/cli 0.2.0 → 0.2.2
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/LICENSE +9 -0
- package/README.md +286 -41
- package/dist/adapters/oclif/commands/action-runs/get.mjs +1 -1
- package/dist/adapters/oclif/commands/action-runs/list.mjs +8 -2
- package/dist/adapters/oclif/commands/actions/get-input-schema.mjs +2 -2
- package/dist/adapters/oclif/commands/actions/get-params-schema.mjs +2 -2
- package/dist/adapters/oclif/commands/actions/get.mjs +1 -1
- package/dist/adapters/oclif/commands/actions/list.mjs +8 -4
- package/dist/adapters/oclif/commands/ai-instructions/create.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/get.mjs +1 -1
- package/dist/adapters/oclif/commands/ai-instructions/list.mjs +8 -2
- package/dist/adapters/oclif/commands/ai-instructions/update.mjs +1 -1
- package/dist/adapters/oclif/commands/api.d.mts +11 -0
- package/dist/adapters/oclif/commands/api.mjs +112 -0
- package/dist/adapters/oclif/commands/apply.d.mts +28 -0
- package/dist/adapters/oclif/commands/apply.mjs +77 -0
- package/dist/adapters/oclif/commands/auth/login.d.mts +5 -4
- package/dist/adapters/oclif/commands/auth/login.mjs +22 -11
- package/dist/adapters/oclif/commands/auth/logout.d.mts +1 -1
- package/dist/adapters/oclif/commands/auth/logout.mjs +7 -3
- package/dist/adapters/oclif/commands/auth/status.d.mts +2 -2
- package/dist/adapters/oclif/commands/auth/status.mjs +2 -2
- package/dist/adapters/oclif/commands/connections/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/connections/create.mjs +8 -0
- package/dist/adapters/oclif/commands/connections/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/connections/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/connections/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/connections/get.mjs +8 -0
- package/dist/adapters/oclif/commands/connections/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/connections/list.mjs +14 -0
- package/dist/adapters/oclif/commands/connections/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/connections/update.mjs +8 -0
- package/dist/adapters/oclif/commands/cubes/create.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/create.mjs +8 -0
- package/dist/adapters/oclif/commands/cubes/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/cubes/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/get.mjs +8 -0
- package/dist/adapters/oclif/commands/cubes/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/list.mjs +13 -0
- package/dist/adapters/oclif/commands/cubes/update.d.mts +6 -0
- package/dist/adapters/oclif/commands/cubes/update.mjs +8 -0
- package/dist/adapters/oclif/commands/diff.d.mts +27 -0
- package/dist/adapters/oclif/commands/diff.mjs +66 -0
- package/dist/adapters/oclif/commands/gservice-account-keys/get.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-account-keys/reveal.mjs +2 -2
- package/dist/adapters/oclif/commands/gservice-accounts/create.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-accounts/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-accounts/get.mjs +1 -1
- package/dist/adapters/oclif/commands/gservice-accounts/list.mjs +7 -2
- package/dist/adapters/oclif/commands/init.d.mts +2 -1
- package/dist/adapters/oclif/commands/init.mjs +28 -24
- package/dist/adapters/oclif/commands/org/create.mjs +1 -1
- package/dist/adapters/oclif/commands/org/current.d.mts +2 -2
- package/dist/adapters/oclif/commands/org/current.mjs +2 -2
- package/dist/adapters/oclif/commands/org/get.mjs +1 -1
- package/dist/adapters/oclif/commands/org/list.d.mts +3 -11
- package/dist/adapters/oclif/commands/org/list.mjs +26 -26
- package/dist/adapters/oclif/commands/org/switch.d.mts +3 -2
- package/dist/adapters/oclif/commands/org/switch.mjs +13 -5
- package/dist/adapters/oclif/commands/pull.d.mts +28 -0
- package/dist/adapters/oclif/commands/pull.mjs +88 -0
- package/dist/adapters/oclif/commands/score-groups/create.mjs +3 -2
- package/dist/adapters/oclif/commands/score-groups/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/score-groups/get.mjs +1 -1
- package/dist/adapters/oclif/commands/score-groups/list.mjs +3 -2
- package/dist/adapters/oclif/commands/score-groups/update.mjs +1 -1
- package/dist/adapters/oclif/commands/scores/create.mjs +3 -2
- package/dist/adapters/oclif/commands/scores/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/scores/list.mjs +3 -2
- package/dist/adapters/oclif/commands/scores/update.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/create.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/evaluate.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/get-evaluation-history.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/get-version.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/get.mjs +1 -1
- package/dist/adapters/oclif/commands/segments/list-versions.mjs +16 -5
- package/dist/adapters/oclif/commands/segments/list.mjs +9 -2
- package/dist/adapters/oclif/commands/segments/restore-version.mjs +2 -2
- package/dist/adapters/oclif/commands/segments/update.mjs +1 -1
- package/dist/adapters/oclif/commands/sources/create.d.mts +11 -0
- package/dist/adapters/oclif/commands/sources/create.mjs +16 -0
- package/dist/adapters/oclif/commands/sources/delete.d.mts +6 -0
- package/dist/adapters/oclif/commands/sources/delete.mjs +8 -0
- package/dist/adapters/oclif/commands/sources/get.d.mts +6 -0
- package/dist/adapters/oclif/commands/sources/get.mjs +8 -0
- package/dist/adapters/oclif/commands/sources/list-streams.d.mts +6 -0
- package/dist/adapters/oclif/commands/sources/list-streams.mjs +31 -0
- package/dist/adapters/oclif/commands/sources/list.d.mts +6 -0
- package/dist/adapters/oclif/commands/sources/list.mjs +13 -0
- package/dist/adapters/oclif/commands/sources/update.d.mts +15 -0
- package/dist/adapters/oclif/commands/sources/update.mjs +21 -0
- package/dist/adapters/oclif/commands/status.d.mts +26 -0
- package/dist/adapters/oclif/commands/status.mjs +77 -0
- package/dist/adapters/oclif/commands/table-views/create.mjs +3 -2
- package/dist/adapters/oclif/commands/table-views/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/table-views/list.mjs +3 -2
- package/dist/adapters/oclif/commands/table-views/update.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/create.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/delete.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/get.mjs +1 -1
- package/dist/adapters/oclif/commands/tables/list.mjs +3 -2
- package/dist/adapters/oclif/commands/tables/update.mjs +1 -1
- package/dist/{base.command-d7VW6WTp.d.mts → base.command-D7X3ZNtY.d.mts} +0 -1
- package/dist/{base.command-DlVQ9Cqa.mjs → base.command-cV5d65r8.mjs} +15 -12
- package/dist/chunk-CfYAbeIz.mjs +13 -0
- package/dist/core-CMrP5BQS.mjs +2378 -0
- package/dist/{factory-D9sR_S_g.mjs → factory-C6XLqhT9.mjs} +44 -10
- package/dist/iac-render-BSZZEP0n.mjs +17 -0
- package/dist/index-BqKwXXAo.d.mts +598 -0
- package/dist/index.d.mts +3 -4
- package/dist/index.mjs +2 -2
- package/dist/{presets-Cvazkjmu.mjs → presets-CJbFbHlw.mjs} +35 -8
- package/dist/templates/.claude/settings.json +39 -0
- package/dist/templates/.devcontainer/devcontainer.json +2 -2
- package/dist/templates/.devcontainer/setup.sh +3 -0
- package/dist/templates/AGENTS.md +36 -13
- package/dist/templates/dbt/dbt_project.yml +2 -2
- package/dist/templates/skills/create-connections/SKILL.md +210 -0
- package/dist/templates/skills/create-connections/references/mappers.md +152 -0
- package/dist/templates/skills/{create-semantic-model → create-cubes}/SKILL.md +28 -26
- package/dist/templates/skills/create-cubes/references/bq-pk-fk-conventions.md +183 -0
- package/dist/templates/skills/{create-semantic-model → create-cubes}/references/cube-examples.md +85 -7
- package/dist/templates/skills/create-cubes/references/hubspot-entities.md +289 -0
- package/dist/templates/skills/create-cubes/references/jira-entities.md +201 -0
- package/dist/templates/skills/create-cubes/references/netsuite-entities.md +121 -0
- package/dist/templates/skills/create-cubes/references/stripe-entities.md +114 -0
- package/dist/templates/skills/create-dbt-transformations/SKILL.md +62 -33
- package/dist/templates/skills/create-dbt-transformations/references/edge-cases.md +21 -3
- package/dist/templates/skills/create-dbt-transformations/references/schema-conventions.md +21 -7
- package/dist/templates/skills/create-dbt-transformations/references/sql-templates.md +34 -20
- package/dist/templates/skills/explore-lakehouse/SKILL.md +8 -4
- package/dist/templates/skills/load-sample-data/SKILL.md +119 -0
- package/dist/templates/skills/visualize-semantic-model/SKILL.md +159 -0
- package/dist/templates/skills/visualize-semantic-model/scripts/render_graph.py +186 -0
- package/dist/{types-Y_ht_ja5.d.mts → types-CGjxcj4L.d.mts} +3 -0
- package/package.json +48 -6
- package/dist/adapters/oclif/commands/overlays/diff.d.mts +0 -19
- package/dist/adapters/oclif/commands/overlays/diff.mjs +0 -80
- package/dist/adapters/oclif/commands/overlays/pull.d.mts +0 -15
- package/dist/adapters/oclif/commands/overlays/pull.mjs +0 -44
- package/dist/adapters/oclif/commands/overlays/push.d.mts +0 -18
- package/dist/adapters/oclif/commands/overlays/push.mjs +0 -59
- package/dist/adapters/oclif/commands/overlays/status.d.mts +0 -18
- package/dist/adapters/oclif/commands/overlays/status.mjs +0 -53
- package/dist/core-gKJ_V-K5.mjs +0 -973
- package/dist/index-KAzwt5vr.d.mts +0 -190
- package/dist/types-C_p_6rkj.d.mts +0 -69
- /package/dist/templates/skills/{create-semantic-model → create-cubes}/references/key-patterns.md +0 -0
- /package/dist/templates/skills/{create-semantic-model → create-cubes}/references/validation-queries.md +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RevOS GmbH.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -8,6 +8,13 @@ Command-line interface for managing RevOS resources.
|
|
|
8
8
|
pnpm add @revos/cli
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Platform support
|
|
12
|
+
|
|
13
|
+
Linux, macOS, and Windows. On POSIX systems the credentials store
|
|
14
|
+
(`~/.revos/credentials.json`) is created with `0600` permissions; on Windows
|
|
15
|
+
those bits are not applied (Windows uses ACLs). Treat your home directory's
|
|
16
|
+
`.revos` folder as sensitive on Windows and rely on standard user-profile ACLs.
|
|
17
|
+
|
|
11
18
|
## Usage
|
|
12
19
|
|
|
13
20
|
```bash
|
|
@@ -26,7 +33,7 @@ revos [command] [options]
|
|
|
26
33
|
### Project Initialization
|
|
27
34
|
|
|
28
35
|
```bash
|
|
29
|
-
revos init [destination] [--yes] [--dry-run]
|
|
36
|
+
revos init [destination] [--yes] [--dry-run] [--no-pull]
|
|
30
37
|
```
|
|
31
38
|
|
|
32
39
|
Scaffolds a new RevOS data engineering project. If `destination` is omitted, initializes in the current directory.
|
|
@@ -47,6 +54,7 @@ destination Path or project name (default: current directory)
|
|
|
47
54
|
```
|
|
48
55
|
-y, --yes Skip confirmation prompts, use defaults
|
|
49
56
|
--dry-run Show what would be created without creating files or GCP resources
|
|
57
|
+
--no-pull Skip discovering existing remote Connections and Cubes
|
|
50
58
|
```
|
|
51
59
|
|
|
52
60
|
**Non-empty directory behavior:**
|
|
@@ -57,16 +65,211 @@ If the destination already exists and is not empty, you will be prompted to conf
|
|
|
57
65
|
|
|
58
66
|
1. Fetches your organizations and prompts you to select one (auto-selects if only one).
|
|
59
67
|
2. Provisions a GCP service account for your org (idempotent) and writes the key to `~/.revos/{project-name}-gsa-creds.json`.
|
|
60
|
-
3.
|
|
61
|
-
4.
|
|
62
|
-
5. Generates
|
|
63
|
-
6. Generates
|
|
64
|
-
7.
|
|
68
|
+
3. Writes `revos.yaml` — the project marker that pins this directory to your organization. CLI commands like `revos status` walk up from the current directory to find this file.
|
|
69
|
+
4. Creates the project directory structure (medallion layout: bronze/silver/gold).
|
|
70
|
+
5. Generates `.devcontainer/devcontainer.json` with Python 3.11, Node.js, Google Cloud SDK (`bq`), and dbt pre-installed. The Dev Container mounts `~/.revos/{project-name}-gsa-creds.json` automatically.
|
|
71
|
+
6. Generates `dbt/profiles.yml` pre-configured for BigQuery.
|
|
72
|
+
7. Generates `.gitignore` and `README.md`.
|
|
73
|
+
8. Scaffolds AI companion files: `CLAUDE.md`, `AGENTS.md`, and `.claude/skills/` with six pre-installed skills: `explore-lakehouse`, `create-connections`, `create-cubes`, `create-dbt-transformations`, `load-sample-data`, and `visualize-semantic-model`. Also writes `.claude/settings.json` with deny rules that block AI assistants from reading `~/.revos/` (CLI credentials and service account keys), `~/.config/gcloud/` (Google Cloud Application Default Credentials), from running `gcloud auth print-*-token` commands, and from editing the settings file itself (so the AI can't lift its own restrictions).
|
|
74
|
+
9. Discovers every Connection and Cube currently in the org and writes them under `connections/` and `cubes/` so a developer joining an org with existing pipelines and cubes starts from the live state. Pass `--no-pull` to skip. Sources are managed only through the API surface (see [Sources](#sources)) and are referenced from Connection YAML by their server id.
|
|
65
75
|
|
|
66
76
|
**Requires:** `revos auth login` first.
|
|
67
77
|
|
|
68
78
|
---
|
|
69
79
|
|
|
80
|
+
### Apply local resources
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
revos apply [path] [--project <path>] [--dry-run] [--parallelism <n>] [--json]
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Reconciles local revos resources with the API:
|
|
87
|
+
|
|
88
|
+
- Resources without `metadata.id` are created (POST) and the YAML file is rewritten in place to record the returned id.
|
|
89
|
+
- Resources with `metadata.id` are read from the API and compared field by field; if the local spec drifts, the resource is updated (PATCH).
|
|
90
|
+
- Resources that already match the API are reported as `unchanged`.
|
|
91
|
+
|
|
92
|
+
Resources are applied in dependency order when one local resource references another. Within a level, up to `--parallelism` resources are processed concurrently (default 4). Unresolved references and cycles fail before any API call.
|
|
93
|
+
|
|
94
|
+
Two `kind`s are supported today: `Connection` (a sync pipeline from a Source into your org's data warehouse) and `Cube` (a Cube.dev semantic model definition). Connections reference a Source by its server id under `spec.source.id`. Get the id from `revos sources list --json`:
|
|
95
|
+
|
|
96
|
+
```yaml
|
|
97
|
+
apiVersion: revos/v1
|
|
98
|
+
kind: Connection
|
|
99
|
+
metadata:
|
|
100
|
+
name: analytics-pipeline
|
|
101
|
+
spec:
|
|
102
|
+
name: "Analytics pipeline"
|
|
103
|
+
source: { id: src_abc123 } # from `revos sources list`
|
|
104
|
+
schedule: { units: 24, timeUnit: hours }
|
|
105
|
+
status: active
|
|
106
|
+
prefix: analytics_ # optional; auto-generated from the source if omitted
|
|
107
|
+
streams:
|
|
108
|
+
- name: users
|
|
109
|
+
namespace: public
|
|
110
|
+
syncMode: incremental_deduped_history
|
|
111
|
+
cursorField: [updated_at]
|
|
112
|
+
primaryKey: [[id]]
|
|
113
|
+
- name: orders
|
|
114
|
+
namespace: public
|
|
115
|
+
syncMode: full_refresh_overwrite
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Sources themselves are not IaC — create them via `revos sources create` (opens the UI) and pull the id with `revos sources list`.
|
|
119
|
+
|
|
120
|
+
`spec.prefix` is prepended to every destination table name. It must match `^[a-z0-9_]*$` (lowercase letters, digits, and underscores) and be at most 63 characters. If omitted on first apply, the API auto-generates a prefix from the source (e.g. `postgres_`) and `revos apply` writes it back into your YAML so subsequent diffs are clean. Edit `spec.prefix` and run `revos apply` to rename it on an existing connection.
|
|
121
|
+
|
|
122
|
+
#### Data masking on a Connection
|
|
123
|
+
|
|
124
|
+
Each stream may carry a `mappers:` array — server-side transformations applied before rows land in BigQuery. Use them to hash PII, drop columns, rename fields, or filter rows out of the sync. Five `type`s are supported: `hashing`, `field-renaming`, `field-filtering`, `row-filtering`, and `encryption`. The kind-specific configuration always lives under `mapperConfiguration`:
|
|
125
|
+
|
|
126
|
+
```yaml
|
|
127
|
+
streams:
|
|
128
|
+
- name: customers
|
|
129
|
+
namespace: public
|
|
130
|
+
syncMode: incremental_deduped_history
|
|
131
|
+
cursorField: [updated_at]
|
|
132
|
+
primaryKey: [[id]]
|
|
133
|
+
mappers:
|
|
134
|
+
# Hash PII so analysts get joinable but irreversible identifiers.
|
|
135
|
+
- type: hashing
|
|
136
|
+
mapperConfiguration:
|
|
137
|
+
targetField: email
|
|
138
|
+
method: SHA-256
|
|
139
|
+
fieldNameSuffix: _hashed
|
|
140
|
+
# Rename a column on the way in.
|
|
141
|
+
- type: field-renaming
|
|
142
|
+
mapperConfiguration:
|
|
143
|
+
originalFieldName: ssn
|
|
144
|
+
newFieldName: ssn_redacted
|
|
145
|
+
# Drop a column entirely.
|
|
146
|
+
- type: field-filtering
|
|
147
|
+
mapperConfiguration:
|
|
148
|
+
targetField: internal_notes
|
|
149
|
+
# Keep rows where the predicate is true; the rest are dropped.
|
|
150
|
+
# NOT(is_test == "true") is true for every non-test row, so test
|
|
151
|
+
# rows get dropped. (Compare against a real sentinel value — empty
|
|
152
|
+
# strings behave unreliably.)
|
|
153
|
+
- type: row-filtering
|
|
154
|
+
mapperConfiguration:
|
|
155
|
+
conditions:
|
|
156
|
+
type: NOT
|
|
157
|
+
conditions:
|
|
158
|
+
- type: EQUAL
|
|
159
|
+
fieldName: is_test
|
|
160
|
+
comparisonValue: "true"
|
|
161
|
+
# Reversible encryption (RSA or AES). Keys are required.
|
|
162
|
+
- type: encryption
|
|
163
|
+
mapperConfiguration:
|
|
164
|
+
algorithm: AES
|
|
165
|
+
targetField: card_number
|
|
166
|
+
fieldNameSuffix: _enc
|
|
167
|
+
key: ${env.AES_KEY}
|
|
168
|
+
mode: GCM
|
|
169
|
+
padding: NoPadding
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Hashing methods: `MD2`, `MD5`, `SHA-1`, `SHA-224`, `SHA-256`, `SHA-384`, `SHA-512`. AES modes: `CBC`, `CFB`, `OFB`, `CTR`, `GCM`, `ECB`. AES paddings: `NoPadding`, `PKCS5Padding`. Masking is enforced at ingest — even a direct BigQuery query sees only the masked values.
|
|
173
|
+
|
|
174
|
+
A `Cube` carries the full Cube.dev semantic model under `spec.definition`. The cube file's `metadata.name` is the IaC slug; `spec.name` is the Cube.dev cube name (also used inside `${CUBE}` and join references). The CLI mirrors `spec.name` into `spec.definition.name` automatically:
|
|
175
|
+
|
|
176
|
+
```yaml
|
|
177
|
+
apiVersion: revos/v1
|
|
178
|
+
kind: Cube
|
|
179
|
+
metadata:
|
|
180
|
+
name: revenue-metrics
|
|
181
|
+
spec:
|
|
182
|
+
name: revenue_metrics
|
|
183
|
+
definition:
|
|
184
|
+
sql_table: "`my_project.my_dataset.gold_revenue`"
|
|
185
|
+
dimensions:
|
|
186
|
+
id:
|
|
187
|
+
sql: "${CUBE}.id"
|
|
188
|
+
type: string
|
|
189
|
+
primary_key: true
|
|
190
|
+
measures:
|
|
191
|
+
count:
|
|
192
|
+
type: count
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
#### Migrating from legacy auto-generated cubes
|
|
196
|
+
|
|
197
|
+
If your org previously relied on auto-generated cube definitions, you can migrate using Claude Code (or any AI assistant with `revos api` access):
|
|
198
|
+
|
|
199
|
+
> "Fetch `GET /cubes/preview` via `revos api`, convert each cube into an IaC YAML file under `cubes/`, then run `revos apply`."
|
|
200
|
+
|
|
201
|
+
The AI will call the endpoint, transform the JSON response into the correct `apiVersion: revos/v1 / kind: Cube` YAML format, write the files, and push them.
|
|
202
|
+
|
|
203
|
+
Once `revos apply` succeeds, the org switches to reading cubes directly from the database — auto-generation is bypassed.
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
`--dry-run` reports what would change without writing to the API or YAML files. It still reads remote state to detect drift, so authentication is required.
|
|
208
|
+
|
|
209
|
+
The CLI walks up from the current working directory to find `revos.yaml`. Resources are addressed by `kind/metadata.name`; filenames are storage only.
|
|
210
|
+
|
|
211
|
+
> Updates are last-writer-wins. Run `revos diff` first if you want to inspect drift before reconciling.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### Diff local vs API
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
revos diff [path] [--project <path>] [--parallelism <n>] [--json]
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Shows the drift between local YAML and the API without making any changes. For each resource that would be created or updated, prints the changed fields:
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
update Connection/analytics-pipeline
|
|
225
|
+
~ schedule.units: 24 → 6
|
|
226
|
+
+ prefix: analytics_
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Sensitive fields (passwords, tokens, API keys, client secrets) are redacted as `(sensitive value)` so secrets never reach stdout. The same diff data is available via `--json`.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### Pull from API
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
revos pull [path] [--project <path>] [--dry-run] [--force] [--json]
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
The reverse of `apply`. For each registered kind, lists every remote resource:
|
|
240
|
+
|
|
241
|
+
- **Known resources** (matched against local YAML by `metadata.id`) get their `spec:` block rewritten in place when drifted, or marked `unchanged` when the live state already matches local. Sibling documents in multi-doc files, comments, and `metadata` are preserved byte-for-byte; only `spec:` is rewritten.
|
|
242
|
+
- **Unknown resources** are _discovered_ — a fresh YAML file is written under `<kind-lowercase>s/<slug>.yaml`. The slug comes from the server-side `name` field, kebab-cased; collisions against existing local addresses dedupe with `-2`, `-3`, etc.
|
|
243
|
+
- **Local resources whose `metadata.id` doesn't exist on the server** are reported as `skipped (not found)`.
|
|
244
|
+
- **Local resources without `metadata.id`** are reported as `skipped (no id)` — they don't yet exist remotely; run `revos apply` to create them.
|
|
245
|
+
|
|
246
|
+
Discovered Connections carry the server source id in `spec.source.id`, so the YAML you get out is immediately apply-able.
|
|
247
|
+
|
|
248
|
+
Sensitive fields (passwords, secrets, tokens) are dropped from discovered resources, since the server returns redacted placeholders that would corrupt the upstream service on a subsequent apply. For _existing_ resources, the local file's value wins on pull — `password: ${env.PG_PASSWORD}` survives a round-trip without being baked in as the resolved value.
|
|
249
|
+
|
|
250
|
+
Refuses to overwrite local files with uncommitted git changes; pass `--force` to override. Newly-discovered files are always written (they can't conflict with anything on disk). `--dry-run` reports what would be pulled or discovered without writing.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
### Project Status
|
|
255
|
+
|
|
256
|
+
```bash
|
|
257
|
+
revos status [path] [--project <path>] [--columns address,state,id,source] [--json]
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
Lists local revos resources (Connections, Cubes) discovered under the project root, with their state.
|
|
261
|
+
|
|
262
|
+
States:
|
|
263
|
+
|
|
264
|
+
- `pending` — defined locally, not yet applied to the API
|
|
265
|
+
- `ok` — applied and synced to the API
|
|
266
|
+
- `tampered` — `metadata.id` looks malformed; recover by running `revos pull <kind>/<name>` (lands in a follow-up phase)
|
|
267
|
+
- `drifted` — local and remote diverge; run `revos diff` to inspect or `revos apply` to reconcile
|
|
268
|
+
|
|
269
|
+
The CLI walks up from the current working directory to find `revos.yaml` (or set `--project <path>` / `REVOS_PROJECT` to override). Resources are addressed by `kind/metadata.name`; filenames are storage only.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
70
273
|
### Authentication
|
|
71
274
|
|
|
72
275
|
#### Login
|
|
@@ -94,7 +297,7 @@ revos auth status [--json]
|
|
|
94
297
|
#### List organizations
|
|
95
298
|
|
|
96
299
|
```bash
|
|
97
|
-
revos org list [--columns name
|
|
300
|
+
revos org list [--columns id,name] [--json]
|
|
98
301
|
```
|
|
99
302
|
|
|
100
303
|
#### Show current organization
|
|
@@ -110,61 +313,61 @@ revos org current [--json]
|
|
|
110
313
|
revos org switch
|
|
111
314
|
|
|
112
315
|
# Direct by ID
|
|
113
|
-
revos org switch <org-id>
|
|
316
|
+
revos org switch <org-id> [--json]
|
|
114
317
|
```
|
|
115
318
|
|
|
319
|
+
`--json` requires an explicit `<org-id>` (interactive selection needs a TTY).
|
|
320
|
+
|
|
116
321
|
---
|
|
117
322
|
|
|
118
|
-
###
|
|
323
|
+
### Sources
|
|
119
324
|
|
|
120
|
-
|
|
325
|
+
Manage data sources. `list`, `get`, and `delete` hit the API directly. `create` and `update` open the RevOS UI, since source configuration (connector picker, dynamic config schemas, OAuth flows) is not practical to drive from a CLI.
|
|
121
326
|
|
|
122
|
-
|
|
327
|
+
#### List sources
|
|
123
328
|
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
description: My custom overlay
|
|
127
|
-
sql_table: my_table
|
|
128
|
-
dimensions:
|
|
129
|
-
id:
|
|
130
|
-
sql: "${CUBE}.id"
|
|
131
|
-
type: number
|
|
132
|
-
primary_key: true
|
|
133
|
-
measures:
|
|
134
|
-
count:
|
|
135
|
-
type: count
|
|
329
|
+
```bash
|
|
330
|
+
revos sources list [--json]
|
|
136
331
|
```
|
|
137
332
|
|
|
138
|
-
####
|
|
333
|
+
#### Get source
|
|
139
334
|
|
|
140
335
|
```bash
|
|
141
|
-
revos
|
|
336
|
+
revos sources get <id> [--json]
|
|
337
|
+
```
|
|
142
338
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
339
|
+
#### List streams the source exposes
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
revos sources list-streams <id> [--ignore-cache] [--columns a,b,c] [--json]
|
|
146
343
|
```
|
|
147
344
|
|
|
148
|
-
|
|
345
|
+
Discovers the streams (tables, endpoints, etc.) the source advertises and the per-stream metadata you need to fill in a `Connection`: supported sync modes, default cursor field, source-defined primary key, and the list of fields available for selection. Pass `--ignore-cache` to bypass the cached catalog and re-discover.
|
|
149
346
|
|
|
150
347
|
```bash
|
|
151
|
-
revos
|
|
348
|
+
revos sources list-streams src_abc123 --json | jq '.[] | {streamName, syncModes, defaultCursorField}'
|
|
349
|
+
```
|
|
152
350
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
351
|
+
#### Create source
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
revos sources create
|
|
156
355
|
```
|
|
157
356
|
|
|
158
|
-
|
|
357
|
+
Opens the RevOS UI to add a new data source.
|
|
358
|
+
|
|
359
|
+
#### Update source
|
|
159
360
|
|
|
160
361
|
```bash
|
|
161
|
-
revos
|
|
362
|
+
revos sources update <id>
|
|
162
363
|
```
|
|
163
364
|
|
|
164
|
-
|
|
365
|
+
Opens the RevOS UI to edit an existing source.
|
|
366
|
+
|
|
367
|
+
#### Delete source
|
|
165
368
|
|
|
166
369
|
```bash
|
|
167
|
-
revos
|
|
370
|
+
revos sources delete <id>
|
|
168
371
|
```
|
|
169
372
|
|
|
170
373
|
---
|
|
@@ -179,6 +382,8 @@ The CLI exposes every method of `@revos/api-client` as a topic-prefixed command.
|
|
|
179
382
|
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
|
180
383
|
| `tables` | `list`, `get`, `create`, `update`, `delete` |
|
|
181
384
|
| `table-views` | `list`, `create`, `update`, `delete` |
|
|
385
|
+
| `cubes` | `list`, `get`, `create`, `update`, `delete` |
|
|
386
|
+
| `connections` | `list`, `get`, `create`, `update`, `delete` |
|
|
182
387
|
| `scores` | `list`, `create`, `update`, `delete` |
|
|
183
388
|
| `score-groups` | `list`, `get`, `create`, `update`, `delete` |
|
|
184
389
|
| `gservice-accounts` | `list`, `get`, `create`, `delete` |
|
|
@@ -191,12 +396,20 @@ The CLI exposes every method of `@revos/api-client` as a topic-prefixed command.
|
|
|
191
396
|
|
|
192
397
|
#### List flags
|
|
193
398
|
|
|
194
|
-
`list` commands accept `--page-size`, `--page-token`, `--order-by`, `--filter`, and `--
|
|
399
|
+
`list` commands accept `--page-size`, `--page-token`, `--order-by`, `--filter`, `--fields`, and `--columns`. `actions list` adds `--only-used`.
|
|
195
400
|
|
|
196
401
|
```bash
|
|
197
402
|
revos tables list --page-size 50 --order-by 'createdAt desc'
|
|
198
403
|
```
|
|
199
404
|
|
|
405
|
+
Each `list` command ships a curated default column set; use `--columns` to override (comma-separated). Pass `--json` for the full payload.
|
|
406
|
+
|
|
407
|
+
```bash
|
|
408
|
+
revos tables list # default columns
|
|
409
|
+
revos tables list --columns id,name # only id and name
|
|
410
|
+
revos tables list --json # full SDK response
|
|
411
|
+
```
|
|
412
|
+
|
|
200
413
|
#### Request bodies (`--body`)
|
|
201
414
|
|
|
202
415
|
`create` and `update` take a single `--body` flag. Three forms:
|
|
@@ -228,6 +441,37 @@ revos gservice-account-keys reveal key_abc
|
|
|
228
441
|
|
|
229
442
|
---
|
|
230
443
|
|
|
444
|
+
### Raw API access (`revos api`)
|
|
445
|
+
|
|
446
|
+
Call any RevOS REST endpoint directly, reusing your stored auth, API base URL, and organization context. Useful for scripts, debugging, and endpoints not yet covered by typed resource commands.
|
|
447
|
+
|
|
448
|
+
```bash
|
|
449
|
+
revos api <path> [-X <method>] [-H 'Name: value']... [-q 'key=value']... [--body JSON|@file|-] [--json]
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
| Flag | Meaning |
|
|
453
|
+
| -------------- | ------------------------------------------------------------------------- |
|
|
454
|
+
| `-X, --method` | HTTP method (default `GET`; case-insensitive). |
|
|
455
|
+
| `-H, --header` | Extra request header (`'Name: value'`). Repeatable. |
|
|
456
|
+
| `-q, --query` | Query parameter (`'key=value'`). Repeatable; repeated keys become arrays. |
|
|
457
|
+
| `--body` | Request body — inline JSON, `@file`, or `-` (stdin). |
|
|
458
|
+
| `--json` | No-op for content (output is already JSON); changes error formatting. |
|
|
459
|
+
|
|
460
|
+
Output is the pretty-printed response body, including the `{ data, metadata }` envelope that list endpoints use — so `metadata.nextPageToken` stays visible for scripted pagination.
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
revos api /organizations
|
|
464
|
+
revos api /tables -q pageSize=50 -q 'orderBy=createdAt desc'
|
|
465
|
+
revos api /connections -X POST --body '{"name":"my-conn"}'
|
|
466
|
+
revos api /connections -X POST --body @body.json
|
|
467
|
+
revos api /segments/seg_123 -X DELETE
|
|
468
|
+
revos api /organizations -H 'X-Foo: bar'
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
Errors follow the same conventions as other commands: 401 prompts you to run `revos auth login`, 404 reports the missing URL, 5xx surfaces the server error.
|
|
472
|
+
|
|
473
|
+
---
|
|
474
|
+
|
|
231
475
|
## Output Formats
|
|
232
476
|
|
|
233
477
|
Every command supports `--json` for machine-readable output:
|
|
@@ -235,14 +479,15 @@ Every command supports `--json` for machine-readable output:
|
|
|
235
479
|
```bash
|
|
236
480
|
revos org list --json
|
|
237
481
|
revos auth status --json
|
|
238
|
-
revos
|
|
482
|
+
revos status --json
|
|
239
483
|
```
|
|
240
484
|
|
|
241
|
-
List commands
|
|
485
|
+
List commands ship a curated default column set, and accept `--columns` to override:
|
|
242
486
|
|
|
243
487
|
```bash
|
|
488
|
+
revos tables list --columns id,name
|
|
244
489
|
revos org list --columns name
|
|
245
|
-
revos
|
|
490
|
+
revos status --columns address,state,id
|
|
246
491
|
```
|
|
247
492
|
|
|
248
493
|
---
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { i as listCommand } from "../../../../presets-
|
|
1
|
+
import { i as listCommand } from "../../../../presets-CJbFbHlw.mjs";
|
|
2
2
|
//#region src/adapters/oclif/commands/action-runs/list.ts
|
|
3
3
|
var list_default = listCommand({
|
|
4
4
|
resource: "actionRuns",
|
|
5
|
-
description: "List action runs"
|
|
5
|
+
description: "List action runs",
|
|
6
|
+
defaultColumns: [
|
|
7
|
+
"id",
|
|
8
|
+
"actionId",
|
|
9
|
+
"status",
|
|
10
|
+
"createdAt"
|
|
11
|
+
]
|
|
6
12
|
});
|
|
7
13
|
//#endregion
|
|
8
14
|
export { list_default as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { p as unwrap } from "../../../../core-CMrP5BQS.mjs";
|
|
2
|
+
import { r as defineApiCommand } from "../../../../factory-C6XLqhT9.mjs";
|
|
3
3
|
import { Args, Flags } from "@oclif/core";
|
|
4
4
|
//#region src/adapters/oclif/commands/actions/get-input-schema.ts
|
|
5
5
|
var get_input_schema_default = defineApiCommand({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { p as unwrap } from "../../../../core-CMrP5BQS.mjs";
|
|
2
|
+
import { r as defineApiCommand } from "../../../../factory-C6XLqhT9.mjs";
|
|
3
3
|
import { Args, Flags } from "@oclif/core";
|
|
4
4
|
//#region src/adapters/oclif/commands/actions/get-params-schema.ts
|
|
5
5
|
var get_params_schema_default = defineApiCommand({
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { n as defineApiCommand } from "../../../../factory-
|
|
1
|
+
import { p as unwrap } from "../../../../core-CMrP5BQS.mjs";
|
|
2
|
+
import { n as createListRender, r as defineApiCommand } from "../../../../factory-C6XLqhT9.mjs";
|
|
3
3
|
import { Flags } from "@oclif/core";
|
|
4
|
-
//#region src/adapters/oclif/commands/actions/list.ts
|
|
5
4
|
var list_default = defineApiCommand({
|
|
6
5
|
description: "List available actions",
|
|
7
6
|
flags: {
|
|
@@ -10,6 +9,10 @@ var list_default = defineApiCommand({
|
|
|
10
9
|
"order-by": Flags.string({ description: "Field to order results by" }),
|
|
11
10
|
filter: Flags.string({ description: "Filter expression" }),
|
|
12
11
|
fields: Flags.string({ description: "Comma-separated fields to include" }),
|
|
12
|
+
columns: Flags.string({
|
|
13
|
+
description: "Columns to display in table output (comma-separated). Overrides the resource default. Ignored with --json.",
|
|
14
|
+
helpValue: "a,b,c"
|
|
15
|
+
}),
|
|
13
16
|
"only-used": Flags.string({ description: "If set, only returns actions used by the organization" })
|
|
14
17
|
},
|
|
15
18
|
call: async ({ api, flags }) => {
|
|
@@ -21,7 +24,8 @@ var list_default = defineApiCommand({
|
|
|
21
24
|
if (flags.fields !== void 0) params.fields = flags.fields;
|
|
22
25
|
if (flags["only-used"] !== void 0) params.onlyUsed = flags["only-used"];
|
|
23
26
|
return unwrap(await api.actions.list(params));
|
|
24
|
-
}
|
|
27
|
+
},
|
|
28
|
+
render: createListRender(["id", "name"])
|
|
25
29
|
});
|
|
26
30
|
//#endregion
|
|
27
31
|
export { list_default as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as createCommand } from "../../../../presets-
|
|
1
|
+
import { t as createCommand } from "../../../../presets-CJbFbHlw.mjs";
|
|
2
2
|
//#region src/adapters/oclif/commands/ai-instructions/create.ts
|
|
3
3
|
var create_default = createCommand({
|
|
4
4
|
resource: "aiInstructions",
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as deleteCommand } from "../../../../presets-
|
|
1
|
+
import { n as deleteCommand } from "../../../../presets-CJbFbHlw.mjs";
|
|
2
2
|
//#region src/adapters/oclif/commands/ai-instructions/delete.ts
|
|
3
3
|
var delete_default = deleteCommand({
|
|
4
4
|
resource: "aiInstructions",
|
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { i as listCommand } from "../../../../presets-
|
|
1
|
+
import { i as listCommand } from "../../../../presets-CJbFbHlw.mjs";
|
|
2
2
|
//#region src/adapters/oclif/commands/ai-instructions/list.ts
|
|
3
3
|
var list_default = listCommand({
|
|
4
4
|
resource: "aiInstructions",
|
|
5
|
-
description: "List AI instructions"
|
|
5
|
+
description: "List AI instructions",
|
|
6
|
+
defaultColumns: [
|
|
7
|
+
"id",
|
|
8
|
+
"integrationName",
|
|
9
|
+
"actionId",
|
|
10
|
+
"updatedAt"
|
|
11
|
+
]
|
|
6
12
|
});
|
|
7
13
|
//#endregion
|
|
8
14
|
export { list_default as default };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as updateCommand } from "../../../../presets-
|
|
1
|
+
import { a as updateCommand } from "../../../../presets-CJbFbHlw.mjs";
|
|
2
2
|
//#region src/adapters/oclif/commands/ai-instructions/update.ts
|
|
3
3
|
var update_default = updateCommand({
|
|
4
4
|
resource: "aiInstructions",
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as _$_oclif_core0 from "@oclif/core";
|
|
2
|
+
|
|
3
|
+
//#region src/adapters/oclif/commands/api.d.ts
|
|
4
|
+
declare const ALLOWED_METHODS: readonly ["GET", "POST", "PATCH", "PUT", "DELETE"];
|
|
5
|
+
type Method = (typeof ALLOWED_METHODS)[number];
|
|
6
|
+
declare function normalizeMethod(input: string | undefined): Method;
|
|
7
|
+
declare function parseHeaders(values: string[] | undefined): Record<string, string>;
|
|
8
|
+
declare function parseQuery(values: string[] | undefined): Record<string, unknown>;
|
|
9
|
+
declare const _default: typeof _$_oclif_core0.Command;
|
|
10
|
+
//#endregion
|
|
11
|
+
export { ALLOWED_METHODS, Method, _default as default, normalizeMethod, parseHeaders, parseQuery };
|