@revos/cli 0.1.4 → 0.2.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.
Files changed (145) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +104 -0
  3. package/dist/adapters/oclif/commands/action-runs/get.d.mts +6 -0
  4. package/dist/adapters/oclif/commands/action-runs/get.mjs +8 -0
  5. package/dist/adapters/oclif/commands/action-runs/list.d.mts +6 -0
  6. package/dist/adapters/oclif/commands/action-runs/list.mjs +8 -0
  7. package/dist/adapters/oclif/commands/actions/get-input-schema.d.mts +6 -0
  8. package/dist/adapters/oclif/commands/actions/get-input-schema.mjs +23 -0
  9. package/dist/adapters/oclif/commands/actions/get-params-schema.d.mts +6 -0
  10. package/dist/adapters/oclif/commands/actions/get-params-schema.mjs +23 -0
  11. package/dist/adapters/oclif/commands/actions/get.d.mts +6 -0
  12. package/dist/adapters/oclif/commands/actions/get.mjs +8 -0
  13. package/dist/adapters/oclif/commands/actions/list.d.mts +6 -0
  14. package/dist/adapters/oclif/commands/actions/list.mjs +27 -0
  15. package/dist/adapters/oclif/commands/ai-instructions/create.d.mts +6 -0
  16. package/dist/adapters/oclif/commands/ai-instructions/create.mjs +8 -0
  17. package/dist/adapters/oclif/commands/ai-instructions/delete.d.mts +6 -0
  18. package/dist/adapters/oclif/commands/ai-instructions/delete.mjs +8 -0
  19. package/dist/adapters/oclif/commands/ai-instructions/get.d.mts +6 -0
  20. package/dist/adapters/oclif/commands/ai-instructions/get.mjs +8 -0
  21. package/dist/adapters/oclif/commands/ai-instructions/list.d.mts +6 -0
  22. package/dist/adapters/oclif/commands/ai-instructions/list.mjs +8 -0
  23. package/dist/adapters/oclif/commands/ai-instructions/update.d.mts +6 -0
  24. package/dist/adapters/oclif/commands/ai-instructions/update.mjs +8 -0
  25. package/dist/adapters/oclif/commands/auth/login.d.mts +2 -2
  26. package/dist/adapters/oclif/commands/auth/login.mjs +2 -2
  27. package/dist/adapters/oclif/commands/auth/logout.d.mts +1 -1
  28. package/dist/adapters/oclif/commands/auth/logout.mjs +7 -3
  29. package/dist/adapters/oclif/commands/auth/status.d.mts +2 -2
  30. package/dist/adapters/oclif/commands/auth/status.mjs +2 -2
  31. package/dist/adapters/oclif/commands/gservice-account-keys/get.d.mts +6 -0
  32. package/dist/adapters/oclif/commands/gservice-account-keys/get.mjs +8 -0
  33. package/dist/adapters/oclif/commands/gservice-account-keys/reveal.d.mts +6 -0
  34. package/dist/adapters/oclif/commands/gservice-account-keys/reveal.mjs +14 -0
  35. package/dist/adapters/oclif/commands/gservice-accounts/create.d.mts +6 -0
  36. package/dist/adapters/oclif/commands/gservice-accounts/create.mjs +8 -0
  37. package/dist/adapters/oclif/commands/gservice-accounts/delete.d.mts +6 -0
  38. package/dist/adapters/oclif/commands/gservice-accounts/delete.mjs +8 -0
  39. package/dist/adapters/oclif/commands/gservice-accounts/get.d.mts +6 -0
  40. package/dist/adapters/oclif/commands/gservice-accounts/get.mjs +8 -0
  41. package/dist/adapters/oclif/commands/gservice-accounts/list.d.mts +6 -0
  42. package/dist/adapters/oclif/commands/gservice-accounts/list.mjs +8 -0
  43. package/dist/adapters/oclif/commands/init.d.mts +1 -1
  44. package/dist/adapters/oclif/commands/init.mjs +4 -3
  45. package/dist/adapters/oclif/commands/integrations/create.d.mts +11 -0
  46. package/dist/adapters/oclif/commands/integrations/create.mjs +16 -0
  47. package/dist/adapters/oclif/commands/integrations/get.d.mts +15 -0
  48. package/dist/adapters/oclif/commands/integrations/get.mjs +21 -0
  49. package/dist/adapters/oclif/commands/integrations/list.d.mts +11 -0
  50. package/dist/adapters/oclif/commands/integrations/list.mjs +16 -0
  51. package/dist/adapters/oclif/commands/integrations/update.d.mts +15 -0
  52. package/dist/adapters/oclif/commands/integrations/update.mjs +21 -0
  53. package/dist/adapters/oclif/commands/org/create.d.mts +6 -0
  54. package/dist/adapters/oclif/commands/org/create.mjs +8 -0
  55. package/dist/adapters/oclif/commands/org/current.d.mts +2 -2
  56. package/dist/adapters/oclif/commands/org/current.mjs +2 -2
  57. package/dist/adapters/oclif/commands/org/get.d.mts +6 -0
  58. package/dist/adapters/oclif/commands/org/get.mjs +8 -0
  59. package/dist/adapters/oclif/commands/org/list.d.mts +2 -2
  60. package/dist/adapters/oclif/commands/org/list.mjs +2 -2
  61. package/dist/adapters/oclif/commands/org/switch.d.mts +1 -1
  62. package/dist/adapters/oclif/commands/org/switch.mjs +5 -4
  63. package/dist/adapters/oclif/commands/overlays/diff.d.mts +2 -2
  64. package/dist/adapters/oclif/commands/overlays/diff.mjs +5 -5
  65. package/dist/adapters/oclif/commands/overlays/pull.d.mts +2 -2
  66. package/dist/adapters/oclif/commands/overlays/pull.mjs +4 -3
  67. package/dist/adapters/oclif/commands/overlays/push.d.mts +2 -2
  68. package/dist/adapters/oclif/commands/overlays/push.mjs +2 -2
  69. package/dist/adapters/oclif/commands/overlays/status.d.mts +2 -2
  70. package/dist/adapters/oclif/commands/overlays/status.mjs +2 -2
  71. package/dist/adapters/oclif/commands/score-groups/create.d.mts +6 -0
  72. package/dist/adapters/oclif/commands/score-groups/create.mjs +8 -0
  73. package/dist/adapters/oclif/commands/score-groups/delete.d.mts +6 -0
  74. package/dist/adapters/oclif/commands/score-groups/delete.mjs +8 -0
  75. package/dist/adapters/oclif/commands/score-groups/get.d.mts +6 -0
  76. package/dist/adapters/oclif/commands/score-groups/get.mjs +8 -0
  77. package/dist/adapters/oclif/commands/score-groups/list.d.mts +6 -0
  78. package/dist/adapters/oclif/commands/score-groups/list.mjs +8 -0
  79. package/dist/adapters/oclif/commands/score-groups/update.d.mts +6 -0
  80. package/dist/adapters/oclif/commands/score-groups/update.mjs +8 -0
  81. package/dist/adapters/oclif/commands/scores/create.d.mts +6 -0
  82. package/dist/adapters/oclif/commands/scores/create.mjs +8 -0
  83. package/dist/adapters/oclif/commands/scores/delete.d.mts +6 -0
  84. package/dist/adapters/oclif/commands/scores/delete.mjs +8 -0
  85. package/dist/adapters/oclif/commands/scores/list.d.mts +6 -0
  86. package/dist/adapters/oclif/commands/scores/list.mjs +8 -0
  87. package/dist/adapters/oclif/commands/scores/update.d.mts +6 -0
  88. package/dist/adapters/oclif/commands/scores/update.mjs +8 -0
  89. package/dist/adapters/oclif/commands/segments/create.d.mts +6 -0
  90. package/dist/adapters/oclif/commands/segments/create.mjs +8 -0
  91. package/dist/adapters/oclif/commands/segments/delete.d.mts +6 -0
  92. package/dist/adapters/oclif/commands/segments/delete.mjs +8 -0
  93. package/dist/adapters/oclif/commands/segments/evaluate.d.mts +6 -0
  94. package/dist/adapters/oclif/commands/segments/evaluate.mjs +14 -0
  95. package/dist/adapters/oclif/commands/segments/get-evaluation-history.d.mts +6 -0
  96. package/dist/adapters/oclif/commands/segments/get-evaluation-history.mjs +14 -0
  97. package/dist/adapters/oclif/commands/segments/get-version.d.mts +6 -0
  98. package/dist/adapters/oclif/commands/segments/get-version.mjs +23 -0
  99. package/dist/adapters/oclif/commands/segments/get.d.mts +6 -0
  100. package/dist/adapters/oclif/commands/segments/get.mjs +8 -0
  101. package/dist/adapters/oclif/commands/segments/list-versions.d.mts +6 -0
  102. package/dist/adapters/oclif/commands/segments/list-versions.mjs +29 -0
  103. package/dist/adapters/oclif/commands/segments/list.d.mts +6 -0
  104. package/dist/adapters/oclif/commands/segments/list.mjs +8 -0
  105. package/dist/adapters/oclif/commands/segments/restore-version.d.mts +6 -0
  106. package/dist/adapters/oclif/commands/segments/restore-version.mjs +23 -0
  107. package/dist/adapters/oclif/commands/segments/update.d.mts +6 -0
  108. package/dist/adapters/oclif/commands/segments/update.mjs +8 -0
  109. package/dist/adapters/oclif/commands/table-views/create.d.mts +6 -0
  110. package/dist/adapters/oclif/commands/table-views/create.mjs +8 -0
  111. package/dist/adapters/oclif/commands/table-views/delete.d.mts +6 -0
  112. package/dist/adapters/oclif/commands/table-views/delete.mjs +8 -0
  113. package/dist/adapters/oclif/commands/table-views/list.d.mts +6 -0
  114. package/dist/adapters/oclif/commands/table-views/list.mjs +8 -0
  115. package/dist/adapters/oclif/commands/table-views/update.d.mts +6 -0
  116. package/dist/adapters/oclif/commands/table-views/update.mjs +8 -0
  117. package/dist/adapters/oclif/commands/tables/create.d.mts +6 -0
  118. package/dist/adapters/oclif/commands/tables/create.mjs +8 -0
  119. package/dist/adapters/oclif/commands/tables/delete.d.mts +6 -0
  120. package/dist/adapters/oclif/commands/tables/delete.mjs +8 -0
  121. package/dist/adapters/oclif/commands/tables/get.d.mts +6 -0
  122. package/dist/adapters/oclif/commands/tables/get.mjs +8 -0
  123. package/dist/adapters/oclif/commands/tables/list.d.mts +6 -0
  124. package/dist/adapters/oclif/commands/tables/list.mjs +8 -0
  125. package/dist/adapters/oclif/commands/tables/update.d.mts +6 -0
  126. package/dist/adapters/oclif/commands/tables/update.mjs +8 -0
  127. package/dist/{base.command-DlVQ9Cqa.mjs → base.command-YiwlGlKs.mjs} +1 -1
  128. package/dist/{core-gKJ_V-K5.mjs → core-jpFPylBb.mjs} +31 -7
  129. package/dist/factory-BrFKT8t-.mjs +90 -0
  130. package/dist/{index-B8n2GxTc.d.mts → index-DD2Vr-pu.d.mts} +6 -3
  131. package/dist/index.d.mts +4 -4
  132. package/dist/index.mjs +2 -2
  133. package/dist/presets-D9b6IWKy.mjs +98 -0
  134. package/dist/templates/.devcontainer/devcontainer.json +2 -2
  135. package/dist/templates/AGENTS.md +19 -9
  136. package/dist/templates/skills/create-dbt-transformations/SKILL.md +21 -13
  137. package/dist/templates/skills/create-dbt-transformations/references/edge-cases.md +1 -1
  138. package/dist/templates/skills/create-semantic-model/SKILL.md +11 -11
  139. package/dist/templates/skills/create-semantic-model/references/cube-examples.md +83 -5
  140. package/dist/templates/skills/explore-lakehouse/SKILL.md +7 -3
  141. package/dist/templates/skills/load-sample-data/SKILL.md +119 -0
  142. package/package.json +8 -3
  143. /package/dist/{base.command-BjFWMIzL.d.mts → base.command-d7VW6WTp.d.mts} +0 -0
  144. /package/dist/{types-DmuJzN0Z.d.mts → types-C_p_6rkj.d.mts} +0 -0
  145. /package/dist/{types-DsQtGF-c.d.mts → types-Y_ht_ja5.d.mts} +0 -0
@@ -11,12 +11,22 @@ This is a RevOS data engineering project for **<%=orgName%>** organization.
11
11
 
12
12
  ## Key Commands
13
13
 
14
- | Command | Description |
15
- | --------------------- | -------------------------------- |
16
- | `revos auth login` | Authenticate with RevOS |
17
- | `revos overlays push` | Push Cube overlays to RevOS |
18
- | `revos overlays pull` | Pull Cube overlays from RevOS |
19
- | `revos overlays diff` | Compare local vs remote overlays |
20
- | `dbt run` | Run dbt models |
21
- | `dbt test` | Test dbt models |
22
- | `bq ls` | List BigQuery datasets/tables |
14
+ | Command | Description |
15
+ | -------------------------------- | ------------------------------------- |
16
+ | `revos auth login` | Authenticate with RevOS |
17
+ | `revos overlays push` | Push Cube overlays to RevOS |
18
+ | `revos overlays pull` | Pull Cube overlays from RevOS |
19
+ | `revos overlays diff` | Compare local vs remote overlays |
20
+ | `revos integrations list` | Open integrations page in RevOS UI |
21
+ | `revos integrations create` | Open RevOS UI to add a data source |
22
+ | `revos integrations update <id>` | Open RevOS UI to edit an integration |
23
+ | `dbt run` | Run dbt models |
24
+ | `dbt test` | Test dbt models |
25
+ | `bq ls` | List BigQuery datasets/tables |
26
+
27
+ ## Data Sources
28
+
29
+ When the user wants to add or manage data sources (integrations):
30
+ - To add a new data source: suggest `revos integrations create`
31
+ - To view existing integrations: suggest `revos integrations list`
32
+ - If a BigQuery dataset is empty or has no tables, mention that integrations can be configured with `revos integrations create`, or sample data can be loaded if available
@@ -5,7 +5,7 @@ description: Create new dbt transformations (bronze/silver/gold models) in the R
5
5
 
6
6
  # Create dbt Transformations
7
7
 
8
- Use this skill to generate SQL models, declare sources, update `schema.yml`, and validate models with `revos dbt run` / `revos dbt test`.
8
+ Use this skill to generate SQL models, declare sources, update `schema.yml`, and validate models with `dbt run` / `dbt test`.
9
9
 
10
10
  For BigQuery exploration (listing datasets, inspecting raw tables, previewing rows, null rates), load the `explore-lakehouse` skill. If that skill is not installed, fall back to:
11
11
 
@@ -72,15 +72,13 @@ Always declare raw tables as sources before referencing them. Do not use bare fu
72
72
 
73
73
  ## Standard dbt Commands
74
74
 
75
- Always use the `revos` wrapper:
76
-
77
75
  ```bash
78
- revos dbt parse # validate syntax (no warehouse)
79
- revos dbt compile --select <model> # resolve refs, produce compiled SQL
80
- revos dbt run --select <model> # execute against warehouse
81
- revos dbt test --select <model> # run tests
82
- revos dbt build --select <model> # run + test
83
- revos dbt build --select path:models/<layer> # entire layer
76
+ dbt parse # validate syntax (no warehouse)
77
+ dbt compile --select <model> # resolve refs, produce compiled SQL
78
+ dbt run --select <model> # execute against warehouse
79
+ dbt test --select <model> # run tests
80
+ dbt build --select <model> # run + test
81
+ dbt build --select path:models/<layer> # entire layer
84
82
  ```
85
83
 
86
84
  ---
@@ -99,8 +97,8 @@ For each transformation (one at a time — do not batch):
99
97
  6. Generate `dbt/models/<layer>/<model_name>.sql`.
100
98
  7. Detect the primary key (Checkpoint 3 if ambiguous).
101
99
  8. Add model entry to `dbt/models/<layer>/schema.yml` with PK and FK tests. See [schema-conventions.md](references/schema-conventions.md).
102
- 9. Run `revos dbt run --select <model_name>` and report result.
103
- 10. Run `revos dbt test --select <model_name>` and report result.
100
+ 9. Run `dbt run --select <model_name>` and report result.
101
+ 10. Run `dbt test --select <model_name>` and report result.
104
102
  11. Summarize (see Final Response Format).
105
103
 
106
104
  For multiple transformations in one request: repeat steps 1–11 per model in order.
@@ -169,6 +167,16 @@ If none produce a clear answer → Checkpoint 3.
169
167
 
170
168
  A column is a FK candidate if it matches `<entity>_id` where `<entity>` ≠ model's own entity, is not part of the PK, and is not nullable by design. Add `not_null` test only (no `relationships` tests by default).
171
169
 
170
+ ## Timestamp Column Propagation (Gold Models)
171
+
172
+ Every gold model **must** propagate at least one timestamp column so downstream Cube overlays can use SQL-based `refresh_key` (see `create-semantic-model` skill). Priority:
173
+
174
+ 1. `_airbyte_extracted_at` — present on all Airbyte sources; always propagate if available in upstream.
175
+ 2. `updated_at` / `modified_at` — CDC-friendly streams.
176
+ 3. `created_at` — insert-only fact tables.
177
+
178
+ If the upstream source has none of these, document it in a SQL comment: `-- no timestamp column available from source`.
179
+
172
180
  ## SQL File Generation
173
181
 
174
182
  See [sql-templates.md](references/sql-templates.md) for:
@@ -206,8 +214,8 @@ Tests:
206
214
  - not_null on <fk>: added
207
215
 
208
216
  Validation:
209
- - revos dbt run: passed | failed
210
- - revos dbt test: passed | failed
217
+ - dbt run: passed | failed
218
+ - dbt test: passed | failed
211
219
 
212
220
  Physical table after run:
213
221
  `<resolved_dataset>.<model_name>`
@@ -34,7 +34,7 @@ Declare it as a source in `dbt/models/bronze/schema.yml` first (see [schema-conv
34
34
 
35
35
  1. Show the error verbatim — do not paraphrase warehouse errors.
36
36
  2. Offer to fix the SQL based on the error message.
37
- 3. Do not proceed to `revos dbt test` until run succeeds.
37
+ 3. Do not proceed to `dbt test` until run succeeds.
38
38
 
39
39
  ## test fails
40
40
 
@@ -15,8 +15,7 @@ project layout, finding gold models, resolving dbt model names to BigQuery table
15
15
  creating bridge models from JSON arrays, and dbt validation commands.
16
16
 
17
17
  If `create-dbt-transformations` is not installed: discover gold models directly via
18
- `find dbt/models/gold -name "*.sql"`, run dbt commands without the `revos` wrapper
19
- (`dbt parse`, `dbt run`, `dbt test`), and skip bridge model delegation.
18
+ `find dbt/models/gold -name "*.sql"` and skip bridge model delegation.
20
19
  Warn the user: "The `create-dbt-transformations` skill is not installed — bridge model creation and dbt validation are limited."
21
20
 
22
21
  If BigQuery exploration is needed (listing tables, inspecting schemas, previewing rows),
@@ -95,7 +94,7 @@ Follow these phases in order. Do not skip ahead.
95
94
 
96
95
  1. Discover gold models via `find dbt/models/gold -name "*.sql"`.
97
96
  2. If none exist, stop and tell the user to create gold models first via `create-dbt-transformations`.
98
- 3. Inspect 1-2 existing overlays in `semantic/` to detect conventions (map-style vs list-style, `extends:`, `public:`, `refresh_key` style). Apply detected conventions to new overlays.
97
+ 3. Inspect 1-2 existing overlays in `semantic/` to detect conventions (`extends:`, `public:`, `refresh_key` style). Apply detected conventions to new overlays. Always use flat single-cube YAML (never `cubes:` or `views:` root).
99
98
  4. If the user named a specific model, find it. If not found, stop.
100
99
  5. Otherwise list all discovered gold models and ask which should participate (Checkpoint 1).
101
100
  6. Keep the full discovered list available for connector search in Phase 3.
@@ -238,13 +237,14 @@ Create Cube.dev YAML files in `semantic/`. Follow the existing style detected in
238
237
 
239
238
  Key rules:
240
239
 
241
- 1. File name = cube `name` (no `gold_` prefix) + `.yml`.
242
- 2. `sql_table` uses fully qualified BigQuery reference with `gold_` prefix.
243
- 3. Every confirmed relationship gets joins in both directions.
244
- 4. Bridge/junction cubes use `public: false`.
245
- 5. Every overlay includes `refresh_key`. Prefer `_airbyte_extracted_at`, fall back to other timestamps, then `every: 1 hour`.
246
- 6. `refresh_key.sql` references the same table as `sql_table`.
247
- 7. Tag unvalidated joins with `# UNVALIDATED: <reason>`.
240
+ 1. **One cube per file, flat YAML.** Each overlay file contains a single cube starting with `name:` at the root level. Never wrap with `cubes:` or `views:` at the root.
241
+ 2. File name = cube `name` (no `gold_` prefix) + `.yml`.
242
+ 3. `sql_table` uses fully qualified BigQuery reference with `gold_` prefix.
243
+ 4. Every confirmed relationship gets joins in both directions.
244
+ 5. Bridge/junction cubes use `public: false`.
245
+ 6. Every overlay **must** include a SQL-based `refresh_key`. Use `SELECT MAX(<timestamp_col>)` with columns in this priority: `_airbyte_extracted_at` (present on all Airbyte sources), `updated_at`/`modified_at` (CDC streams), `created_at` (insert-only facts). Only use `every: <interval>` as absolute last resort when **no timestamp column exists in the table** add a YAML comment explaining why (e.g. `# no timestamp column available`).
246
+ 7. `refresh_key.sql` references the same table as `sql_table`.
247
+ 8. Tag unvalidated joins with `# UNVALIDATED: <reason>`.
248
248
 
249
249
  See [references/cube-examples.md](references/cube-examples.md) for canonical standard cube, bridge cube, join direction examples, and refresh key variants.
250
250
 
@@ -252,7 +252,7 @@ See [references/cube-examples.md](references/cube-examples.md) for canonical sta
252
252
 
253
253
  ## Phase 9: Validate Generated Files
254
254
 
255
- 1. If `create-dbt-transformations` was invoked (bridge model), it already validated dbt models. Otherwise run `revos dbt parse`.
255
+ 1. If `create-dbt-transformations` was invoked (bridge model), it already validated dbt models. Otherwise run `dbt parse`.
256
256
  2. Verify physical tables exist in BigQuery: `bq show <dataset>.<table_name>`. If missing, document as pending.
257
257
  3. Verify generated overlays match conventions: flat YAML, correct naming, correct `sql_table`, all dimensions present, `refresh_key` included, joins in both directions.
258
258
 
@@ -9,6 +9,7 @@
9
9
  - [Refresh Key Variants](#refresh-key-variants)
10
10
  - [Type Mapping](#type-mapping)
11
11
  - [Measure Suggestions](#measure-suggestions)
12
+ - [Common Mistakes](#common-mistakes)
12
13
 
13
14
  ---
14
15
 
@@ -215,24 +216,68 @@ joins:
215
216
 
216
217
  ## Refresh Key Variants
217
218
 
218
- Priority order:
219
+ SQL-based refresh keys are **required**. They ensure caches invalidate only when data actually changes, instead of on a fixed timer.
220
+
221
+ Priority — use the first available timestamp column:
219
222
 
220
223
  ```yaml
221
- # 1. Airbyte timestamp (preferred)
224
+ # 1. Airbyte timestamp (preferred — present on all Airbyte sources)
222
225
  refresh_key:
223
226
  sql: "SELECT MAX(_airbyte_extracted_at) FROM `<dataset>.<gold_model>`"
224
227
 
225
- # 2. Other reliable timestamp
228
+ # 2. CDC / update timestamp
226
229
  refresh_key:
227
230
  sql: "SELECT MAX(updated_at) FROM `<dataset>.<gold_model>`"
228
231
 
229
- # 3. Default fallback
232
+ # 3. Insert-only fact table
230
233
  refresh_key:
231
- every: 1 hour
234
+ sql: "SELECT MAX(created_at) FROM `<dataset>.<gold_model>`"
235
+
236
+ # 4. Last resort — ONLY when the table has no timestamp column at all
237
+ # Add a comment explaining why:
238
+ refresh_key:
239
+ every: 1 hour # no timestamp column available in this table
232
240
  ```
233
241
 
234
242
  `refresh_key.sql` must reference the same fully qualified table as the cube's `sql_table`.
235
243
 
244
+ ### Common Mistakes
245
+
246
+ ```yaml
247
+ # BAD — fixed cadence, ignores actual data changes.
248
+ # This forces cache rebuild every hour even when data hasn't changed.
249
+ refresh_key:
250
+ every: 1 hour
251
+
252
+ # GOOD — only invalidates when new rows arrive
253
+ refresh_key:
254
+ sql: "SELECT MAX(_airbyte_extracted_at) FROM `<dataset>.<gold_model>`"
255
+ ```
256
+
257
+ ```yaml
258
+ # BAD — omitting refresh_key entirely (cube uses default, which may be too aggressive)
259
+ name: my_cube
260
+ sql_table: ...
261
+
262
+ # GOOD — always include an explicit refresh_key
263
+ name: my_cube
264
+ sql_table: ...
265
+ refresh_key:
266
+ sql: "SELECT MAX(_airbyte_extracted_at) FROM `<dataset>.<gold_model>`"
267
+ ```
268
+
269
+ ```yaml
270
+ # BAD — refresh_key.sql references a different table than sql_table
271
+ sql_table: "`project.dataset.gold_orders`"
272
+ refresh_key:
273
+ sql: "SELECT MAX(_airbyte_extracted_at) FROM `project.dataset.gold_customers`"
274
+
275
+ # GOOD — same table in both
276
+ sql_table: "`project.dataset.gold_orders`"
277
+ refresh_key:
278
+ sql: "SELECT MAX(_airbyte_extracted_at) FROM `project.dataset.gold_orders`"
279
+ ```
280
+
236
281
  ---
237
282
 
238
283
  ## Type Mapping
@@ -265,3 +310,36 @@ updated_at -> last_updated_at (max)
265
310
  ```
266
311
 
267
312
  `count_distinct` on FK columns: define inside the cube that owns the FK, not the parent cube. Joins can produce row fan-out that distorts distinct counts.
313
+
314
+ ---
315
+
316
+ ## Common Mistakes
317
+
318
+ ### Wrapping with `cubes:` or `views:` at the root
319
+
320
+ RevOS expects one cube per file with flat YAML — `name:` at the root level. The Cube.dev docs show a multi-cube `cubes:` list format, but RevOS does not use it.
321
+
322
+ ```yaml
323
+ # BAD — multi-cube list format
324
+ cubes:
325
+ - name: hubspot_companies
326
+ sql_table: "`dataset.gold_hubspot_companies`"
327
+ dimensions:
328
+ id:
329
+ sql: "${CUBE}.id"
330
+ type: string
331
+ primary_key: true
332
+ ```
333
+
334
+ ```yaml
335
+ # GOOD — flat single-cube format
336
+ name: hubspot_companies
337
+ sql_table: "`dataset.gold_hubspot_companies`"
338
+ dimensions:
339
+ id:
340
+ sql: "${CUBE}.id"
341
+ type: string
342
+ primary_key: true
343
+ ```
344
+
345
+ Same applies to `views:` — never use it as a root key.
@@ -85,9 +85,13 @@ FROM \`$GOOGLE_CLOUD_PROJECT.$REVOS_BQ_DATASET.<table>\`
85
85
  ### "What's in my database?" / general overview
86
86
 
87
87
  1. List tables in the org's dataset: `bq ls $REVOS_BQ_DATASET`
88
- 2. Infer the data source and domain from table name prefixes (e.g. `salesforce_*`, `stripe_*`, `hubspot_*`)
89
- 3. Group tables by source/domain
90
- 4. Return: sources found, table count per source, table types (TABLE/VIEW), one-line description per group
88
+ 2. If the dataset is empty (no tables), tell the user:
89
+ - They can add data sources by running `revos integrations create` to open the RevOS UI
90
+ - They can view existing integrations with `revos integrations list`
91
+ - Stop here — no further exploration is possible without data
92
+ 3. Infer the data source and domain from table name prefixes (e.g. `salesforce_*`, `stripe_*`, `hubspot_*`)
93
+ 4. Group tables by source/domain
94
+ 5. Return: sources found, table count per source, table types (TABLE/VIEW), one-line description per group
91
95
 
92
96
  ### "What layer is this data?" / bronze–silver–gold assessment
93
97
 
@@ -0,0 +1,119 @@
1
+ ---
2
+ name: load-sample-data
3
+ description: >
4
+ Populate a BigQuery dataset with sample data from public datasets using bq cp.
5
+ Use when asked to: load sample data, populate the lakehouse, add demo data, seed the dataset,
6
+ get started with sample tables, or when the user needs data to explore.
7
+ ---
8
+
9
+ # Load Sample Data
10
+
11
+ Copy sample tables from `bigquery-public-data` into the user's dataset using `bq cp`. All copied tables are prefixed with `sample_` so they can be easily identified and cleaned up later.
12
+
13
+ ## Environment
14
+
15
+ Verify env vars before running any command. If either is empty, ask the user to set it.
16
+
17
+ ```bash
18
+ echo "Project: $GOOGLE_CLOUD_PROJECT"
19
+ echo "Dataset: $REVOS_BQ_DATASET"
20
+ ```
21
+
22
+ - `$GOOGLE_CLOUD_PROJECT` — BQ project ID
23
+ - `$REVOS_BQ_DATASET` — target dataset
24
+
25
+ ## Step 1: Check Existing Tables
26
+
27
+ ```bash
28
+ bq ls $REVOS_BQ_DATASET
29
+ ```
30
+
31
+ If tables exist, list them. They will be relevant in Step 3 for collision handling.
32
+
33
+ ## Step 2: Present Sample Dataset Catalog
34
+
35
+ ```text
36
+ Available sample datasets:
37
+
38
+ 1. thelook_ecommerce (default) — B2C e-commerce data
39
+ Tables: sample_users, sample_orders, sample_order_items, sample_products, sample_events, sample_inventory_items, sample_distribution_centers
40
+ Rows: ~100K users, ~300K orders
41
+ Good for: customer analytics, purchase funnels, product performance
42
+
43
+ 2. google_analytics_sample — Web analytics session data
44
+ Tables: sample_ga_sessions (single table, one day snapshot)
45
+ Rows: ~900K sessions
46
+ Good for: web traffic analysis, user behavior, channel attribution
47
+
48
+ 3. austin_bikeshare — Bikeshare trip and station data
49
+ Tables: sample_bikeshare_trips, sample_bikeshare_stations
50
+ Rows: ~1.3M trips
51
+ Good for: geospatial analysis, demand forecasting, utilization metrics
52
+ ```
53
+
54
+ ## Step 3: Copy Tables
55
+
56
+ If any table names from the chosen sample dataset collide with existing tables (from Step 1), ask the user whether to **overwrite** or **skip** each collision before copying. Skip collisions the user chose not to overwrite.
57
+
58
+ ### thelook_ecommerce
59
+
60
+ ```bash
61
+ for table in users orders order_items products events inventory_items distribution_centers; do
62
+ echo "Copying sample_$table..."
63
+ bq cp -f bigquery-public-data:thelook_ecommerce.$table \
64
+ $GOOGLE_CLOUD_PROJECT:$REVOS_BQ_DATASET.sample_$table
65
+ done
66
+ ```
67
+
68
+ ### google_analytics_sample
69
+
70
+ The `ga_sessions` table is date-sharded. Copy a representative day:
71
+
72
+ ```bash
73
+ echo "Copying sample_ga_sessions..."
74
+ bq cp -f bigquery-public-data:google_analytics_sample.ga_sessions_20170801 \
75
+ $GOOGLE_CLOUD_PROJECT:$REVOS_BQ_DATASET.sample_ga_sessions
76
+ ```
77
+
78
+ ### austin_bikeshare
79
+
80
+ ```bash
81
+ for table in bikeshare_trips bikeshare_stations; do
82
+ echo "Copying sample_$table..."
83
+ bq cp -f bigquery-public-data:austin_bikeshare.$table \
84
+ $GOOGLE_CLOUD_PROJECT:$REVOS_BQ_DATASET.sample_$table
85
+ done
86
+ ```
87
+
88
+ ## Step 4: Verify
89
+
90
+ ```bash
91
+ for table in <copied_tables>; do
92
+ echo -n "$table: "
93
+ bq query --nouse_legacy_sql --format=csv \
94
+ "SELECT COUNT(*) FROM \`$GOOGLE_CLOUD_PROJECT.$REVOS_BQ_DATASET.$table\`" 2>/dev/null | tail -1
95
+ done
96
+ ```
97
+
98
+ ## Final Response
99
+
100
+ ```text
101
+ Sample data loaded into $REVOS_BQ_DATASET.
102
+
103
+ Source: bigquery-public-data:<dataset_name>
104
+ Tables copied:
105
+ - <table_1>: <row_count> rows
106
+ - <table_2>: <row_count> rows
107
+
108
+ Next steps:
109
+ - Run "explore lakehouse" to inspect the data
110
+ - Run "create dbt transformations" to build bronze/silver/gold models
111
+ - Run "create semantic model" to generate Cube overlays
112
+ ```
113
+
114
+ ## Rules
115
+
116
+ - Use `bq cp -f` (not `CREATE TABLE AS SELECT`) — faster, no query costs, preserves schema. The `-f` flag is required to avoid cross-region confirmation prompts that block non-interactive shells.
117
+ - Show progress for each table being copied.
118
+ - Report any failures clearly with the `bq` error message.
119
+ - Always prefix destination tables with `sample_` — this allows easy identification and cleanup of sample data.
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@revos/cli",
3
- "version": "0.1.4",
3
+ "version": "0.2.1",
4
4
  "description": "RevOS CLI for managing RevOS platform resources",
5
+ "license": "MIT",
5
6
  "type": "module",
6
7
  "main": "dist/index.js",
7
8
  "types": "dist/index.d.ts",
@@ -31,12 +32,16 @@
31
32
  },
32
33
  "overlays": {
33
34
  "description": "Manage Cube overlays"
35
+ },
36
+ "integrations": {
37
+ "description": "Manage integrations (opens RevOS UI)"
34
38
  }
35
39
  }
36
40
  },
37
41
  "files": [
38
42
  "dist",
39
- "bin"
43
+ "bin",
44
+ "LICENSE"
40
45
  ],
41
46
  "dependencies": {
42
47
  "@inquirer/search": "^4.1.7",
@@ -57,7 +62,7 @@
57
62
  "jest": "^29.7.0",
58
63
  "tsdown": "^0.21.9",
59
64
  "typescript": "^5.7.2",
60
- "@revosai/config-eslint": "0.0.0"
65
+ "@revos/config-eslint": "0.0.0"
61
66
  },
62
67
  "publishConfig": {
63
68
  "registry": "https://registry.npmjs.org",