@skillrecordings/cli 0.18.2 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,375 +1,171 @@
1
1
  # @skillrecordings/cli
2
2
 
3
- CLI for the support platform. Agent-friendly with non-interactive defaults.
3
+ Agent-friendly CLI for the Skill Recordings support platform.
4
4
 
5
- ## Install
5
+ ## Setup (2 minutes)
6
+
7
+ You need: a GitHub account in the `skillrecordings` org.
6
8
 
7
9
  ```bash
10
+ # 1. Install
8
11
  curl -fsSL https://raw.githubusercontent.com/skillrecordings/support/main/packages/cli/install.sh | bash
9
- ```
10
-
11
- Installs to `~/.local/bin/skill`. Add to your PATH if needed:
12
12
 
13
- ```bash
13
+ # 2. Add to PATH (if not already)
14
14
  echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
15
- ```
16
-
17
- After install, run `skill auth setup` to configure credentials.
18
-
19
- ## Usage
20
-
21
- ```bash
22
- bunx @skillrecordings/cli <command> [options]
23
-
24
- # or with direct import
25
- skill <command> [options]
26
- ```
27
15
 
28
- All commands support `--json` for machine-readable output and reliable exit
29
- codes.
30
-
31
- ## 1Password Quickstart (60 seconds)
32
-
33
- If you already have access to the Support vault:
34
-
35
- ```bash
36
- # 1) Install required CLI
37
- brew install 1password-cli
38
-
39
- # 2) Optional but recommended: cache OP token in local secrets CLI
40
- secrets add skill_support_1password_service_account_token
41
-
42
- # 3) Run one setup command
16
+ # 3. Authenticate (opens browser, no other tools needed)
43
17
  skill auth setup
44
18
 
45
- # 4) Verify
19
+ # 4. Verify everything works
46
20
  skill doctor
47
21
  ```
48
22
 
49
- Notes:
50
- - `secrets` CLI is optional. If missing, `skill auth setup` falls back to `op signin`.
51
- - Setup writes `SKILL_AGE_KEY` to `~/.config/skill/age.key` so `.env.encrypted` works without keychain.
23
+ That's it. No 1Password CLI, no age keys, no manual secret management.
52
24
 
53
- ## Adaptive Hints
54
-
55
- The CLI prints adaptive onboarding/discovery hints to `stderr` for new users.
56
- Hints learn from usage and fade as you run more commands.
57
-
58
- **Opt out:**
59
- - Use `--quiet`
60
- - Use `--json`
61
- - Pipe output (non-TTY)
25
+ The CLI authenticates via GitHub device flow → the broker verifies your org
26
+ membership → secrets are delivered encrypted and held in memory only.
62
27
 
63
28
  ## Commands
64
29
 
65
- ### `skill init <name>`
66
-
67
- Initialize a new app integration with webhook secret.
68
-
69
30
  ```bash
70
- # Interactive (terminal only)
71
- skill init
72
-
73
- # Non-interactive (required for agents/scripts)
74
- skill init my-app
75
-
76
- # JSON output
77
- skill init my-app --json
31
+ skill <command> [options]
78
32
  ```
79
33
 
80
- **Options:**
81
- - `--json` - Output result as JSON (machine-readable)
82
-
83
- **Exit codes:**
84
- - `0` - Success
85
- - `1` - Error (name required in non-interactive mode, etc.)
86
-
87
- ### `skill health <slug|url>`
88
-
89
- Test integration endpoint health.
34
+ All commands support `--json` for machine-readable output.
90
35
 
91
- ```bash
92
- # Using database lookup (recommended)
93
- skill health total-typescript
94
-
95
- # Direct URL mode
96
- skill health https://example.com --secret whsec_xxx
36
+ | Command | What it does |
37
+ |---|---|
38
+ | `skill auth setup` | One-command bootstrap (GitHub device flow) |
39
+ | `skill auth status` | Session + provider status |
40
+ | `skill doctor` | Deep health check with remediation hints |
41
+ | `skill health <app>` | Test app webhook endpoint |
42
+ | `skill health --list` | List registered apps |
43
+ | `skill init <name>` | Initialize new app integration |
44
+ | `skill eval routing <dataset>` | Run routing classifier evals |
45
+ | `skill auth oauth-spike` | Inspect broker readiness |
97
46
 
98
- # List registered apps
99
- skill health --list
100
-
101
- # JSON output (for agents)
102
- skill health total-typescript --json
103
- ```
47
+ ## How Auth Works
104
48
 
105
- **Options:**
106
- - `-s, --secret <secret>` - Webhook secret (required for direct URL mode)
107
- - `-l, --list` - List all registered apps
108
- - `--json` - Output result as JSON (machine-readable)
109
-
110
- **Exit codes:**
111
- - `0` - Health check passed
112
- - `1` - Health check failed or error
113
-
114
- **JSON output structure:**
115
- ```json
116
- {
117
- "success": true,
118
- "endpoint": "https://...",
119
- "status": "ok",
120
- "responseTime": 730,
121
- "actions": [
122
- { "name": "lookupUser", "status": "ok" },
123
- { "name": "getPurchases", "status": "ok" }
124
- ],
125
- "summary": { "ok": 4, "notImplemented": 1, "errors": 0 }
126
- }
127
49
  ```
128
-
129
- ### `skill eval <type> <dataset>`
130
-
131
- Run evals against a dataset (e.g., routing classifier, canned response
132
- matcher).
133
-
134
- ```bash
135
- # Run routing eval with defaults
136
- skill eval routing path/to/dataset.json
137
-
138
- # With strict thresholds
139
- skill eval routing dataset.json --min-precision 0.95 --min-recall 0.97
140
-
141
- # JSON output for automation
142
- skill eval routing dataset.json --json
143
-
144
- # Custom thresholds
145
- skill eval routing dataset.json \
146
- --min-precision 0.92 \
147
- --min-recall 0.95 \
148
- --max-fp-rate 0.03 \
149
- --max-fn-rate 0.02
50
+ skill auth setup
51
+ GitHub device flow (approve in browser)
52
+ → Broker verifies skillrecordings org membership
53
+ Short-lived session tokens issued (15min access / 8hr refresh)
54
+ → skill auth exec decrypts secrets in memory per-command
150
55
  ```
151
56
 
152
- **Arguments:**
153
- - `type` - Eval type (e.g., `routing`)
154
- - `dataset` - Path to JSON dataset file
155
-
156
- **Options:**
157
- - `--json` - Output result as JSON (machine-readable)
158
- - `--min-precision <number>` - Minimum precision threshold (default: 0.92)
159
- - `--min-recall <number>` - Minimum recall threshold (default: 0.95)
160
- - `--max-fp-rate <number>` - Maximum false positive rate (default: 0.03)
161
- - `--max-fn-rate <number>` - Maximum false negative rate (default: 0.02)
57
+ **Broker endpoints** (on `skill-support-agent-front.vercel.app`):
162
58
 
163
- **Exit codes:**
164
- - `0` - All metrics passed thresholds
165
- - `1` - One or more metrics below threshold or error
59
+ | Endpoint | Purpose |
60
+ |---|---|
61
+ | `POST /api/auth/device/start` | Start GitHub device flow |
62
+ | `POST /api/auth/device/poll` | Exchange device code for session |
63
+ | `POST /api/auth/session/refresh` | Refresh session, re-check membership |
64
+ | `POST /api/env/materialize` | Age-encrypted env delivery |
166
65
 
167
- **Output includes:**
168
- - Precision, recall, false positive/negative rates
169
- - Latency percentiles (p50, p95, p99)
170
- - Token usage and estimated cost
171
- - Category-level breakdown (if applicable)
66
+ **Legacy path:** 1Password CLI + `skill auth setup --legacy` still works as
67
+ admin/break-glass mode.
172
68
 
173
- ## App Onboarding Workflow
174
-
175
- Typical flow for adding a new app integration:
69
+ ## App Onboarding
176
70
 
177
71
  ```bash
178
- # 1. Initialize with app name
72
+ # 1. Initialize
179
73
  skill init my-app --json
180
- # Returns: { "success": true, "appName": "my-app",
181
- # "webhookSecret": "whsec_xxx" }
182
74
 
183
- # 2. Register webhook endpoint in your app
184
- # Save the webhook secret and configure your endpoint to:
75
+ # 2. Register webhook in your app (use returned secret)
185
76
  # POST /api/support-webhooks with Authorization: Bearer whsec_xxx
186
77
 
187
- # 3. Test health before going live
78
+ # 3. Verify
188
79
  skill health my-app
189
- # Verifies: endpoint reachable, signature verification works,
190
- # actions implemented
191
-
192
- # 4. Run evals (optional, for routing/matching logic)
193
- skill eval routing path/to/labeled-dataset.json --json
194
80
 
195
- # 5. Deploy and monitor
196
- # Check logs via Axiom/Langfuse for inbound messages
81
+ # 4. Run evals (optional)
82
+ skill eval routing labeled-dataset.json --json
197
83
  ```
198
84
 
199
- All commands work non-interactively and report errors with exit codes
200
- (0=success, 1=error).
85
+ ## Health Check
201
86
 
202
- ## Agent Usage
203
-
204
- All commands support `--json` for machine-readable output and
205
- non-interactive operation:
206
-
207
- **init command:**
208
- - Requires `name` argument (non-interactive mode)
209
- - Returns JSON: `{ "success": true, "appName": "...",
210
- "webhookSecret": "whsec_..." }`
211
- - Use `--json` for reliable parsing
212
-
213
- **health command:**
214
- - Use `--json` for JSON output (structured for parsing)
215
- - Use `--list` to discover all registered apps
216
- - Returns exit code 0 if healthy, 1 if any check fails
217
-
218
- **eval command:**
219
- - Requires `type` and `dataset` arguments
220
- - Accepts custom threshold gates (precision, recall, false
221
- positive/negative rates)
222
- - Returns exit code 0 if all metrics pass, 1 otherwise
223
- - Use `--json` for machine-readable report
224
-
225
- **Error handling:**
226
- - All commands output `{ "success": false, "error": "message" }` on
227
- JSON mode
228
- - Check exit codes: 0 = success, 1 = error
229
- - Never interactive in non-TTY environments (CI/CD safe)
230
-
231
- ## Secrets Management
232
-
233
- The CLI uses a layered secrets system:
234
-
235
- 1. **1Password (preferred)** - Service account token resolves secrets directly
236
- 2. **Encrypted `.env.encrypted`** - Age-encrypted env file for offline/CI use
237
- 3. **Plain `.env.local`** - Local development fallback
87
+ ```bash
88
+ # Quick check
89
+ skill health total-typescript
238
90
 
239
- ### Secret Resolution Order
91
+ # All apps
92
+ skill health --list
240
93
 
241
- ```
242
- 1Password (OP_SERVICE_ACCOUNT_TOKEN set?)
243
- ↓ yes → resolve from 1Password vault
244
- ↓ no
245
- .env.encrypted exists + SKILL_AGE_KEY available?
246
- ↓ yes → decrypt and load
247
- ↓ no
248
- .env.local exists?
249
- ↓ yes → load plain env vars
250
- ↓ no → error: missing secrets
94
+ # Deep system check
95
+ skill doctor --json
251
96
  ```
252
97
 
253
- ### Adding a New Secret
98
+ ## Agent Usage
254
99
 
255
- **Step 1: Add to `secret-refs.ts`**
100
+ - `--json` on every command for structured output
101
+ - `--quiet` suppresses adaptive hints
102
+ - Exit codes: `0` = success, `1` = error
103
+ - Non-interactive in non-TTY environments (CI/CD safe)
104
+ - Error shape: `{ "success": false, "error": "message" }`
256
105
 
257
- ```typescript
258
- // packages/cli/src/core/secret-refs.ts
259
- export const SECRET_REFS = {
260
- // ... existing secrets
261
- MY_NEW_KEY: 'op://Support/skill-cli/MY_NEW_KEY',
262
- } as const
263
- ```
106
+ ## Secrets Management
264
107
 
265
- **Step 2: Add to 1Password**
108
+ The broker handles secrets for most users. Admins who need direct access:
266
109
 
267
- ```bash
268
- # Using op CLI
269
- op item edit "skill-cli" --vault "Support" "MY_NEW_KEY=your-secret-value"
110
+ ### Resolution Order
270
111
 
271
- # Or via 1Password UI:
272
- # 1. Open Support vault → skill-cli item
273
- # 2. Add new field: MY_NEW_KEY = your-value
274
112
  ```
275
-
276
- **Step 3: Update `.env.encrypted`**
277
-
278
- ```bash
279
- # Decrypt current secrets
280
- AGE_KEY=$(op read "op://Support/skill-cli-age-key/private_key")
281
- age -d -i <(echo "$AGE_KEY") .env.encrypted > .env.local
282
-
283
- # Add new secret to .env.local
284
- echo "MY_NEW_KEY=your-secret-value" >> .env.local
285
-
286
- # Re-encrypt
287
- AGE_PUB=$(echo "$AGE_KEY" | age-keygen -y)
288
- age -r "$AGE_PUB" .env.local > .env.encrypted
289
-
290
- # Verify
291
- age -d -i <(echo "$AGE_KEY") .env.encrypted | grep MY_NEW_KEY
113
+ OAuth Broker (default, v0.19.0+)
114
+ GitHub auth → broker decrypts → ephemeral age envelope → memory only
115
+ 1Password (admin/break-glass)
116
+ → OP_SERVICE_ACCOUNT_TOKEN → resolve from vault
117
+ .env.encrypted (CI fallback)
118
+ SKILL_AGE_KEY → decrypt and load
119
+ .env.local (local dev fallback)
120
+ → load plain env vars
292
121
  ```
293
122
 
294
- **Step 4: Commit changes**
123
+ ### Adding a Secret
295
124
 
296
- ```bash
297
- git add packages/cli/src/core/secret-refs.ts packages/cli/.env.encrypted
298
- git commit -m "chore(cli): add MY_NEW_KEY secret"
299
- ```
125
+ 1. Add ref to `packages/cli/src/core/secret-refs.ts`
126
+ 2. Add value to 1Password: `op item edit "skill-cli" --vault "Support" "MY_KEY=value"`
127
+ 3. Update `.env.encrypted` (see below)
128
+ 4. Commit: `git add secret-refs.ts .env.encrypted`
300
129
 
301
- ### Updating an Existing Secret
130
+ ### Updating `.env.encrypted`
302
131
 
303
132
  ```bash
304
- # 1. Update in 1Password
305
- op item edit "skill-cli" --vault "Support" "MY_KEY=new-value"
306
-
307
- # 2. Update .env.encrypted (same process as adding)
308
133
  AGE_KEY=$(op read "op://Support/skill-cli-age-key/private_key")
309
134
  age -d -i <(echo "$AGE_KEY") .env.encrypted > .env.local
310
-
311
- # Edit .env.local with new value
312
- sed -i '' 's/MY_KEY=.*/MY_KEY=new-value/' .env.local
313
-
314
- # Re-encrypt
135
+ # edit .env.local
315
136
  AGE_PUB=$(echo "$AGE_KEY" | age-keygen -y)
316
137
  age -r "$AGE_PUB" .env.local > .env.encrypted
317
- ```
318
-
319
- ### Auth Commands
320
-
321
- ```bash
322
- # Check current auth status
323
- skill auth status
324
-
325
- # Validate 1Password token
326
- skill auth login
327
-
328
- # Show service account info
329
- skill auth whoami
330
-
331
- # Interactive setup wizard
332
- skill auth setup
138
+ rm .env.local
333
139
  ```
334
140
 
335
141
  ### Key Locations
336
142
 
337
143
  | Item | Location |
338
- |------|----------|
144
+ |---|---|
339
145
  | Secrets | `op://Support/skill-cli/*` |
340
146
  | Age keypair | `op://Support/skill-cli-age-key/private_key` |
341
147
  | Encrypted env | `packages/cli/.env.encrypted` |
342
148
  | Secret refs | `packages/cli/src/core/secret-refs.ts` |
343
149
 
344
- ### CI/CD Usage
345
-
346
- For CI environments without 1Password:
150
+ ### CI/CD
347
151
 
348
152
  ```bash
349
- # Set age key as CI secret, then:
153
+ # With 1Password service account
154
+ export OP_SERVICE_ACCOUNT_TOKEN="$OP_TOKEN"
155
+ skill auth status
156
+
157
+ # Or with age key
350
158
  echo "$SKILL_AGE_KEY" > /tmp/age.key
351
159
  age -d -i /tmp/age.key .env.encrypted > .env.local
352
160
  rm /tmp/age.key
353
161
  ```
354
162
 
355
- Or use 1Password service account:
163
+ ## Adaptive Hints
356
164
 
357
- ```bash
358
- export OP_SERVICE_ACCOUNT_TOKEN="$OP_TOKEN"
359
- skill auth status # Verifies connection
360
- skill front inbox # Commands auto-resolve secrets
361
- ```
165
+ New users see contextual onboarding hints on `stderr`. They fade with usage.
166
+ Suppress with `--quiet`, `--json`, or piped output.
362
167
 
363
168
  ## Implementation
364
169
 
365
- - `packages/cli/src/commands/` - Command implementations
366
- - `packages/cli/src/index.ts` - CLI entry point
367
- - Entry point: `#!/usr/bin/env bun` (runs with Bun directly)
368
-
369
- ## Do / Don't
370
-
371
- - Do use `--json` flag for automation/agents/scripts
372
- - Do check exit codes in shell scripts
373
- - Do pass `name` argument to `init` in CI/CD (non-interactive required)
374
- - Don't rely on interactive prompts outside terminal
375
- - Don't parse stdout (use `--json` for structured output)
170
+ - `packages/cli/src/commands/` command implementations
171
+ - `packages/cli/src/index.ts` entry point (`#!/usr/bin/env bun`)