strata-cli 0.1.0.beta

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 (79) hide show
  1. checksums.yaml +7 -0
  2. data/.standard.yml +3 -0
  3. data/CHANGELOG.md +5 -0
  4. data/CLAUDE.md +65 -0
  5. data/LICENSE +21 -0
  6. data/README.md +465 -0
  7. data/Rakefile +10 -0
  8. data/exe/strata +6 -0
  9. data/lib/strata/cli/ai/client.rb +63 -0
  10. data/lib/strata/cli/ai/configuration.rb +48 -0
  11. data/lib/strata/cli/ai/services/table_generator.rb +282 -0
  12. data/lib/strata/cli/api/client.rb +170 -0
  13. data/lib/strata/cli/api/connection_error_handler.rb +54 -0
  14. data/lib/strata/cli/configuration.rb +135 -0
  15. data/lib/strata/cli/credentials.rb +83 -0
  16. data/lib/strata/cli/descriptions/create/migration.txt +25 -0
  17. data/lib/strata/cli/descriptions/create/relation.txt +14 -0
  18. data/lib/strata/cli/descriptions/create/table.txt +23 -0
  19. data/lib/strata/cli/descriptions/datasource/add.txt +15 -0
  20. data/lib/strata/cli/descriptions/datasource/auth.txt +14 -0
  21. data/lib/strata/cli/descriptions/datasource/exec.txt +7 -0
  22. data/lib/strata/cli/descriptions/datasource/meta.txt +11 -0
  23. data/lib/strata/cli/descriptions/datasource/tables.txt +12 -0
  24. data/lib/strata/cli/descriptions/datasource/test.txt +8 -0
  25. data/lib/strata/cli/descriptions/deploy/deploy.txt +24 -0
  26. data/lib/strata/cli/descriptions/deploy/status.txt +9 -0
  27. data/lib/strata/cli/descriptions/init.txt +14 -0
  28. data/lib/strata/cli/generators/datasource.rb +83 -0
  29. data/lib/strata/cli/generators/group.rb +13 -0
  30. data/lib/strata/cli/generators/migration.rb +71 -0
  31. data/lib/strata/cli/generators/project.rb +190 -0
  32. data/lib/strata/cli/generators/relation.rb +64 -0
  33. data/lib/strata/cli/generators/table.rb +143 -0
  34. data/lib/strata/cli/generators/templates/adapters/athena.yml +53 -0
  35. data/lib/strata/cli/generators/templates/adapters/druid.yml +42 -0
  36. data/lib/strata/cli/generators/templates/adapters/duckdb.yml +36 -0
  37. data/lib/strata/cli/generators/templates/adapters/mysql.yml +45 -0
  38. data/lib/strata/cli/generators/templates/adapters/postgres.yml +48 -0
  39. data/lib/strata/cli/generators/templates/adapters/snowflake.yml +69 -0
  40. data/lib/strata/cli/generators/templates/adapters/sqlserver.yml +45 -0
  41. data/lib/strata/cli/generators/templates/adapters/trino.yml +56 -0
  42. data/lib/strata/cli/generators/templates/datasources.yml +4 -0
  43. data/lib/strata/cli/generators/templates/migration.rename.yml +15 -0
  44. data/lib/strata/cli/generators/templates/migration.swap.yml +13 -0
  45. data/lib/strata/cli/generators/templates/project.yml +36 -0
  46. data/lib/strata/cli/generators/templates/rel.domain.yml +43 -0
  47. data/lib/strata/cli/generators/templates/strata.yml +24 -0
  48. data/lib/strata/cli/generators/templates/table.table_name.yml +118 -0
  49. data/lib/strata/cli/generators/templates/test.yml +34 -0
  50. data/lib/strata/cli/generators/test.rb +48 -0
  51. data/lib/strata/cli/guard.rb +21 -0
  52. data/lib/strata/cli/helpers/color_helper.rb +103 -0
  53. data/lib/strata/cli/helpers/command_context.rb +41 -0
  54. data/lib/strata/cli/helpers/datasource_helper.rb +62 -0
  55. data/lib/strata/cli/helpers/description_helper.rb +18 -0
  56. data/lib/strata/cli/helpers/project_helper.rb +85 -0
  57. data/lib/strata/cli/helpers/prompts.rb +42 -0
  58. data/lib/strata/cli/helpers/table_filter.rb +48 -0
  59. data/lib/strata/cli/main.rb +71 -0
  60. data/lib/strata/cli/sub_commands/audit.rb +262 -0
  61. data/lib/strata/cli/sub_commands/create.rb +419 -0
  62. data/lib/strata/cli/sub_commands/datasource.rb +353 -0
  63. data/lib/strata/cli/sub_commands/deploy.rb +433 -0
  64. data/lib/strata/cli/sub_commands/project.rb +38 -0
  65. data/lib/strata/cli/sub_commands/table.rb +58 -0
  66. data/lib/strata/cli/terminal.rb +102 -0
  67. data/lib/strata/cli/ui/autocomplete.rb +93 -0
  68. data/lib/strata/cli/ui/field_editor.rb +215 -0
  69. data/lib/strata/cli/utils/archive.rb +137 -0
  70. data/lib/strata/cli/utils/deployment_monitor.rb +445 -0
  71. data/lib/strata/cli/utils/git.rb +253 -0
  72. data/lib/strata/cli/utils/import_manager.rb +190 -0
  73. data/lib/strata/cli/utils/test_reporter.rb +131 -0
  74. data/lib/strata/cli/utils/yaml_import_resolver.rb +91 -0
  75. data/lib/strata/cli/utils.rb +39 -0
  76. data/lib/strata/cli/version.rb +7 -0
  77. data/lib/strata/cli.rb +36 -0
  78. data/sig/strata/cli.rbs +6 -0
  79. metadata +306 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: d417b55f20b06dadf03dd915ec77c78ac145a95ee820d3728ef31ba399aadf57
4
+ data.tar.gz: 929ee748ca1082a29ac9de3a348768e93aaa4ec494a9d6033fba2de3f4d12966
5
+ SHA512:
6
+ metadata.gz: d821fe082a53140b3ae66bd7d612198dbba107d5c7bfccb3bee530fb30e831f3be8c86066062463a1ee79347910d6d3e006dc8f8bf4988c5860de9272e0016dc
7
+ data.tar.gz: 298ec8199c214af514816a2f8dc00068a9f5f073c3cf395cf3904b213875d55719eb558c24a79f22f3fc2c4e8fe790ea98c811ac8155c061262f5a60645dcea0
data/.standard.yml ADDED
@@ -0,0 +1,3 @@
1
+ # For available configuration options, see:
2
+ # https://github.com/standardrb/standard
3
+ ruby_version: 3.4.4
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-01-22
4
+
5
+ - Initial release
data/CLAUDE.md ADDED
@@ -0,0 +1,65 @@
1
+ # Project Context
2
+
3
+ ## Project Overview
4
+
5
+ This project is a Ruby CLI app built with the Thor gem. Its primary purpose is to provide to manage the Semantic Layer hosted in a Strata Server app. It will used by Data Engineers to configure datasource connection and define the the semantic model.
6
+
7
+ ## Tech Stack
8
+
9
+ - **Language**: [Ruby]
10
+ - **Framework**: Strata Server is a Ruby on Rails app
11
+ - **Key Libraries**: [dwh]
12
+
13
+ ## Project Structure
14
+
15
+ ```
16
+ /lib # Source code
17
+ /tests # Test files
18
+ /docs # Documentation
19
+ ```
20
+
21
+ ## Development Guidelines
22
+
23
+ ### Code Style
24
+
25
+ - Follow [standardrb style]
26
+ - Be succinct and optimize for readability
27
+ - Reuse existing code as much as possible
28
+ - Do not unnecessarily split a method into multiple methods
29
+ - Split the method when the new method will be used in more than one place
30
+ - Split the method if the method gets to long to maintain readability.
31
+ - Use meaningful variable names
32
+ - Comment complex logic
33
+
34
+ ### Testing
35
+
36
+ - Write tests for new features
37
+ - Maintain test coverage above [X]%
38
+ - Run tests before commits
39
+
40
+ ### Git Workflow
41
+
42
+ - Use conventional commits
43
+ - Create feature branches from main
44
+ - Squash commits before merging
45
+
46
+ ## Key Files & Directories
47
+
48
+ - `[.strata]` - [This CLI will create a .strata file based strata.yml that will contain secrets necessary to access various endpoints. It will also have config that lets the project connect to the right Strata server.]
49
+ - `[cli.rb]` - [main application file]
50
+
51
+ ## Common Tasks
52
+
53
+ ## Architecture Notes
54
+
55
+ - [Support ruby >= 3.4.4. Cli can be installed as a gem or via shell script.]
56
+ - [Follow the style of Ruby on Rails CLI where possible]
57
+
58
+ ## Current Priorities
59
+
60
+ ## Debugging & Troubleshooting
61
+
62
+ - **Common issue**: Database endpoints are not reachable. This is because we either need to run the requisite docker image or setup a cloud connection to aws snowflake, google etc.
63
+ - **Environment setup**: docker compose as needed
64
+
65
+ ## External Resources
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Strata
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,465 @@
1
+ # Strata CLI
2
+
3
+ Command-line interface for the Strata Semantic Analytics System. Create, manage, and deploy Strata projects with ease.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ gem install strata-cli
9
+ ```
10
+
11
+ Or add to your Gemfile:
12
+
13
+ ```bash
14
+ bundle add strata-cli
15
+ ```
16
+
17
+ ## Requirements
18
+
19
+ - Ruby >= 3.4.4
20
+ - Git (for deployment features)
21
+ - Access to a Strata server
22
+
23
+ ## Quick Start
24
+
25
+ ```bash
26
+ # Initialize a new project
27
+ strata init my-project
28
+
29
+ # Add a datasource
30
+ strata datasource add
31
+
32
+ # Create a semantic table model
33
+ strata create table customers
34
+
35
+ # Deploy to server
36
+ strata deploy
37
+ ```
38
+
39
+ ## Commands Overview
40
+
41
+ > 💡 **Tip:** Run `strata COMMAND --help` for detailed help, options, and examples on any command. The CLI help system provides comprehensive documentation for each command.
42
+
43
+ <details>
44
+ <summary><strong>Project Management</strong></summary>
45
+
46
+ ### `strata init [PROJECT_NAME]`
47
+
48
+ Initialize a new Strata project or clone from an existing repository.
49
+
50
+ **Options:**
51
+ - `-d, --datasource ADAPTER` - Add datasource adapters (repeatable)
52
+ - `-s, --source URL` - Clone existing project from URL
53
+ - `-a, --api-key KEY` - API key (required with `--source`)
54
+
55
+ **Examples:**
56
+ ```bash
57
+ strata init my-project
58
+ strata init my-project -d postgres -d snowflake
59
+ strata init --source https://github.com/org/project.git --api-key YOUR_KEY
60
+ ```
61
+
62
+ ### `strata project link PROJECT_ID`
63
+
64
+ Link local project to an existing project on the Strata server.
65
+
66
+ **Examples:**
67
+ ```bash
68
+ strata project link 12345
69
+ ```
70
+
71
+ </details>
72
+
73
+ <details>
74
+ <summary><strong>Datasource Management</strong> (alias: `ds`)</summary>
75
+
76
+ ### `strata datasource adapters`
77
+ List all supported data warehouse adapters.
78
+
79
+ ### `strata datasource list`
80
+ List all configured datasources with their keys and display names.
81
+
82
+ ### `strata datasource add [ADAPTER]`
83
+ Add a new datasource interactively. `ADAPTER` is optional - prompts if omitted.
84
+
85
+ **Examples:**
86
+ ```bash
87
+ strata datasource add # Interactive mode
88
+ strata datasource add postgres # Direct selection
89
+ strata ds add snowflake # Using alias
90
+ ```
91
+
92
+ ### `strata datasource auth DS_KEY`
93
+ Set credentials for a datasource. Credentials stored in `.strata` file.
94
+
95
+ **Options:** `-r, --remote` - Set credentials on remote server
96
+
97
+ **Examples:**
98
+ ```bash
99
+ strata datasource auth my_db
100
+ strata ds auth postgres_db --remote
101
+ ```
102
+
103
+ ### `strata datasource test DS_KEY`
104
+ Test connection to a datasource.
105
+
106
+ **Examples:**
107
+ ```bash
108
+ strata datasource test my_db
109
+ ```
110
+
111
+ ### `strata datasource tables [DS_KEY]`
112
+ List all tables in a datasource with interactive filtering.
113
+
114
+ **Options:** `-p, --pattern PATTERN`, `-c, --catalog CATALOG`, `-s, --schema SCHEMA`
115
+
116
+ **Examples:**
117
+ ```bash
118
+ strata datasource tables my_db
119
+ strata datasource tables my_db -p user -s dbo
120
+ ```
121
+
122
+ ### `strata datasource meta DS_KEY TABLE_NAME`
123
+ Show the schema/structure of a specific table.
124
+
125
+ **Options:** `-c, --catalog CATALOG`, `-s, --schema SCHEMA`
126
+
127
+ **Examples:**
128
+ ```bash
129
+ strata datasource meta my_db customers
130
+ strata datasource meta my_db dbo.orders
131
+ ```
132
+
133
+ ### `strata datasource exec DS_KEY`
134
+ Execute SQL queries on a datasource.
135
+
136
+ **Options:** `-q, --query QUERY`, `-f, --file PATH`
137
+
138
+ **Examples:**
139
+ ```bash
140
+ strata datasource exec my_db -q "SELECT * FROM customers LIMIT 10"
141
+ strata datasource exec my_db -f queries/analysis.sql
142
+ ```
143
+
144
+ </details>
145
+
146
+ <details>
147
+ <summary><strong>Model Creation</strong></summary>
148
+
149
+ ### `strata create table [TABLE_PATH]`
150
+ Create a semantic table model from a datasource table.
151
+
152
+ **Options:** `-d, --datasource DS_KEY`
153
+
154
+ **Examples:**
155
+ ```bash
156
+ strata create table # Interactive mode
157
+ strata create table call_center # Simple path
158
+ strata create table games/event_details # Nested path
159
+ strata create table contact/dse.call_center_d # With schema
160
+ ```
161
+
162
+ **Process:** Checks table existence → Fetches metadata → AI suggests fields → Interactive editor → Generates model file
163
+
164
+ ### `strata create relation RELATION_PATH`
165
+ Create a relation (join) definition file.
166
+
167
+ **Options:** `-d, --datasource DS_KEY`
168
+
169
+ **Examples:**
170
+ ```bash
171
+ strata create relation customer/orders # Creates models/customer/rel.orders.yml
172
+ strata create relation customer # Creates models/rel.customer.yml
173
+ ```
174
+
175
+ ### `strata create migration rename`
176
+ Create a migration file to rename an entity.
177
+
178
+ **Options:** `-e, --entity TYPE` (required), `-f, --from NAME` (required), `-t, --to NAME` (required)
179
+
180
+ **Entity types:** `dimension`, `measure`, `table`, `datasource`
181
+
182
+ **Examples:**
183
+ ```bash
184
+ strata create migration rename -e dimension -f old_name -t new_name
185
+ strata create migration rename -e table -f old_table -t new_table
186
+ ```
187
+
188
+ ### `strata create migration swap`
189
+ Create a migration file to swap entity references.
190
+
191
+ **Options:** `-e, --entity TYPE` (required), `-f, --from NAME` (required), `-t, --to NAME` (required)
192
+
193
+ **Entity types:** `dimension`, `measure`, `table` (datasource not supported)
194
+
195
+ **Examples:**
196
+ ```bash
197
+ strata create migration swap -e measure -f measure_a -t measure_b
198
+ ```
199
+
200
+ </details>
201
+
202
+ <details>
203
+ <summary><strong>Table Management</strong> (aliases: `t`, `tbl`)</summary>
204
+
205
+ ### `strata table list`
206
+ List all semantic table models in the project.
207
+
208
+ **Examples:**
209
+ ```bash
210
+ strata table list
211
+ strata t list
212
+ ```
213
+
214
+ </details>
215
+
216
+ <details>
217
+ <summary><strong>Deployment</strong></summary>
218
+
219
+ ### `strata deploy`
220
+ Deploy project to Strata server for the current branch.
221
+
222
+ **Options:**
223
+ - `-e, --environment ENV` - Deploy to specific environment
224
+ - `--skip-audit` - Skip pre-deployment audit checks
225
+ - `--yes, -y` - Skip confirmation prompts (CI/CD mode)
226
+ - `-f, --force` - Force deploy even if no files changed
227
+
228
+ **Examples:**
229
+ ```bash
230
+ strata deploy
231
+ strata deploy -e production
232
+ strata deploy --skip-audit --yes # CI/CD mode
233
+ strata deploy --force
234
+ ```
235
+
236
+ **Process:** Audit checks → Git status → Create archive → Upload → Monitor progress
237
+
238
+ ### `strata deploy status`
239
+ Show current deployment status for the active branch.
240
+
241
+ **Options:** `-e, --environment ENV`
242
+
243
+ **Examples:**
244
+ ```bash
245
+ strata deploy status
246
+ strata deploy status -e production
247
+ ```
248
+
249
+ </details>
250
+
251
+ <details>
252
+ <summary><strong>Audit & Validation</strong> (alias: `a`)</summary>
253
+
254
+ ### `strata audit` or `strata audit all`
255
+ Run all audit checks (syntax, models, connections). This is the default command.
256
+
257
+ ### `strata audit syntax`
258
+ Check YAML syntax of all configuration files.
259
+
260
+ ### `strata audit models`
261
+ Validate model definitions and schema structure.
262
+
263
+ ### `strata audit connections`
264
+ Test all datasource connections.
265
+
266
+ **Examples:**
267
+ ```bash
268
+ strata audit # Run all checks
269
+ strata audit syntax # Check YAML syntax only
270
+ strata a models # Validate models only
271
+ ```
272
+
273
+ </details>
274
+
275
+ <details>
276
+ <summary><strong>Utilities</strong></summary>
277
+
278
+ ### `strata version`
279
+ Print the CLI version.
280
+
281
+ ### `strata adapters`
282
+ List all supported data warehouse adapters.
283
+
284
+ </details>
285
+
286
+ ## Configuration
287
+
288
+ ### Project Configuration (`project.yml`)
289
+
290
+ Main project configuration file:
291
+
292
+ ```yaml
293
+ name: My Project
294
+ uid: my-project
295
+ description: Description of my project
296
+ server: https://strata.example.com
297
+ production_branch: main
298
+ git: https://github.com/org/project.git
299
+ project_id: 123 # Auto-populated after first deployment
300
+ ```
301
+
302
+ **Multi-Environment Configuration:**
303
+
304
+ ```yaml
305
+ # Default environment
306
+ server: http://localhost:3000
307
+
308
+ # Environment-specific configs
309
+ dev:
310
+ server: http://localhost:3000
311
+ api_key: dev-key
312
+
313
+ production:
314
+ server: https://app.strata.com
315
+ api_key: prod-key
316
+ ```
317
+
318
+ ### Local Configuration (`.strata`)
319
+
320
+ Stores sensitive credentials. **Never committed to git** (automatically excluded).
321
+
322
+ ```yaml
323
+ api_key: your-api-key-here
324
+
325
+ # Datasource credentials
326
+ my_db:
327
+ username: user
328
+ password: pass
329
+
330
+ # AI configuration (optional)
331
+ ai_provider: openai
332
+ ai_api_key: your-ai-key
333
+ ```
334
+
335
+ **Security:** The `.strata` file automatically has restrictive permissions (0600) for security.
336
+
337
+ ### Datasources Configuration (`datasources.yml`)
338
+
339
+ Defines all datasource connections:
340
+
341
+ ```yaml
342
+ my_postgres:
343
+ adapter: postgres
344
+ name: PostgreSQL Database
345
+ host: localhost
346
+ port: 5432
347
+ database: mydb
348
+ schema: public
349
+ ssl: false
350
+ tier: warm
351
+ query_timeout: 3600
352
+
353
+ my_snowflake:
354
+ adapter: snowflake
355
+ name: Snowflake Warehouse
356
+ account_identifier: myorg-myaccount
357
+ database: ANALYTICS_DB
358
+ warehouse: COMPUTE_WH
359
+ schema: PUBLIC
360
+ role: ACCOUNTADMIN
361
+ auth_mode: pat
362
+ ```
363
+
364
+ ## Supported Data Warehouse Adapters
365
+
366
+ - **PostgreSQL** - Full support
367
+ - **MySQL** - Full support
368
+ - **SQL Server** - Full support (including Azure)
369
+ - **Snowflake** - Full support (PAT, Key Pair, OAuth)
370
+ - **Athena** - AWS Athena support
371
+ - **Trino** - Trino/Presto support
372
+ - **DuckDB** - Embedded analytics database
373
+ - **Druid** - Apache Druid support
374
+
375
+ ## Security
376
+
377
+ - ✅ Credentials stored in `.strata` with restrictive permissions (0600)
378
+ - ✅ API keys never accepted via command line arguments
379
+ - ✅ File paths validated to prevent path traversal attacks
380
+ - ✅ Git commit hashes validated before use
381
+ - ✅ YAML files loaded safely to prevent code execution
382
+
383
+ ## Troubleshooting
384
+
385
+ <details>
386
+ <summary><strong>Common Issues</strong></summary>
387
+
388
+ ### "Permission denied" errors
389
+
390
+ Ensure you have write permissions in the project directory. The `.strata` file permissions are automatically set to 0600.
391
+
392
+ ### "Server URL not configured"
393
+
394
+ Add the `server` field to your `project.yml`:
395
+
396
+ ```yaml
397
+ server: https://your-strata-server.com
398
+ ```
399
+
400
+ ### "API key not found"
401
+
402
+ Run `strata deploy` and enter your API key when prompted, or manually add to `.strata`:
403
+
404
+ ```yaml
405
+ api_key: your-api-key
406
+ ```
407
+
408
+ ### "Uncommitted changes" during deploy
409
+
410
+ Commit or stash your changes:
411
+
412
+ ```bash
413
+ git add .
414
+ git commit -m "Your changes"
415
+ strata deploy
416
+ ```
417
+
418
+ ### "Table not found" when creating model
419
+
420
+ - Verify the table exists in the datasource
421
+ - Check schema/catalog settings
422
+ - Use `strata datasource tables DS_KEY` to list available tables
423
+ - Use `strata datasource meta DS_KEY TABLE_NAME` to verify table structure
424
+
425
+ ### Connection test failures
426
+
427
+ - Verify credentials with `strata datasource auth DS_KEY`
428
+ - Check network connectivity
429
+ - Verify datasource configuration in `datasources.yml`
430
+ - Test connection with `strata datasource test DS_KEY`
431
+
432
+ </details>
433
+
434
+ ## Development
435
+
436
+ After checking out the repo:
437
+
438
+ ```bash
439
+ bin/setup
440
+ ```
441
+
442
+ Run tests:
443
+
444
+ ```bash
445
+ rake test
446
+ ```
447
+
448
+ Install locally:
449
+
450
+ ```bash
451
+ bundle exec rake install
452
+ ```
453
+
454
+ Release a new version:
455
+
456
+ 1. Update version in `lib/strata/cli/version.rb`
457
+ 2. Run `bundle exec rake release`
458
+
459
+ ## Contributing
460
+
461
+ Bug reports and pull requests welcome on GitHub at https://github.com/stratasite/strata-cli.
462
+
463
+ ## License
464
+
465
+ The gem is available as open source under the terms of the [MIT License](LICENSE).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "minitest/test_task"
5
+
6
+ Minitest::TestTask.create
7
+
8
+ require "standard/rake"
9
+
10
+ task default: %i[test standard]
data/exe/strata ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require_relative "../lib/strata/cli"
5
+
6
+ Strata::CLI.start(ARGV)
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "ruby_llm"
4
+ require_relative "configuration"
5
+
6
+ module Strata
7
+ module CLI
8
+ module AI
9
+ # Custom error class for AI-related errors
10
+ class AIError < StandardError; end
11
+
12
+ # Client wraps ruby_llm gem for unified LLM access.
13
+ class Client
14
+ attr_reader :config, :chat
15
+
16
+ def initialize(config = Configuration.new)
17
+ @config = config
18
+ configure_ruby_llm if enabled?
19
+ end
20
+
21
+ # Check if AI is enabled and configured
22
+ def enabled?
23
+ @config.enabled?
24
+ end
25
+
26
+ # Complete a prompt using the configured provider
27
+ # @param prompt [String] The user prompt
28
+ # @param system_prompt [String, nil] Optional system context
29
+ # @return [String] The AI response
30
+ def complete(prompt, system_prompt: nil)
31
+ raise AIError, "AI is not enabled. Configure ai_api_key in .strata" unless enabled?
32
+
33
+ chat = RubyLLM.chat(model: @config.model_or_default)
34
+ chat.with_instructions(system_prompt) if system_prompt
35
+ response = chat.ask(prompt)
36
+ response.content
37
+ rescue RubyLLM::Error => e
38
+ raise AIError, "LLM error: #{e.message}"
39
+ end
40
+
41
+ private
42
+
43
+ def configure_ruby_llm
44
+ RubyLLM.configure do |c|
45
+ # Dynamically set the API key for the configured provider
46
+ # e.g. c.gemini_api_key = ... or c.openai_api_key = ...
47
+ provider_key_method = "#{@config.provider}_api_key="
48
+
49
+ if c.respond_to?(provider_key_method)
50
+ c.public_send(provider_key_method, @config.api_key)
51
+ else
52
+ # Fallback or error if the provider setter doesn't exist on the config object
53
+ # This might happen if 'provider' string doesn't match the config accessor
54
+ # but RubyLLM conventions usually align.
55
+ raise AIError,
56
+ "Could not configure RubyLLM for provider '#{@config.provider}'. Check if helper method '#{provider_key_method}' exists."
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Strata
4
+ module CLI
5
+ module AI
6
+ class Configuration
7
+ require "ruby_llm"
8
+ PROVIDERS = RubyLLM::Providers.constants.map { |c| c.to_s.downcase }.sort.freeze
9
+
10
+ attr_reader :provider, :api_key, :model
11
+
12
+ def initialize
13
+ @provider = CLI.config["ai_provider"] || default_provider
14
+ @api_key = CLI.config["ai_api_key"]
15
+ @model = CLI.config["ai_model"]
16
+ end
17
+
18
+ def enabled?
19
+ CLI.config["ai_enabled"] != false && !@api_key.nil? && !@api_key.empty?
20
+ end
21
+
22
+ def default_provider
23
+ "gemini"
24
+ end
25
+
26
+ def default_model
27
+ case @provider
28
+ when "gemini" then "gemini-2.0-flash"
29
+ when "openai" then "gpt-4o-mini"
30
+ when "anthropic" then "claude-sonnet-4-20250514"
31
+ when "mistral" then "mistral-large-latest"
32
+ when "deepseek" then "deepseek-chat"
33
+ else
34
+ # For other providers, we don't have a specific default.
35
+ # The user should specify a model in .strata or via CLI if needed.
36
+ # Returning nil here might cause issues if a default is expected,
37
+ # so we'll return a safe fallback or let the provider helper handle it.
38
+ nil
39
+ end
40
+ end
41
+
42
+ def model_or_default
43
+ @model || default_model
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end