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