@bagdock/cli 0.2.0 → 0.4.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,9 +1,29 @@
1
1
  # @bagdock/cli
2
2
 
3
- Developer CLI for building, testing, and deploying apps and edges on the Bagdock platform.
3
+ The official CLI for Bagdock. Built for humans, AI agents, and CI/CD pipelines.
4
4
 
5
5
  ## Install
6
6
 
7
+ ### cURL (macOS / Linux)
8
+
9
+ ```bash
10
+ curl -fsSL https://bdok.dev/install.sh | bash
11
+ ```
12
+
13
+ ### PowerShell (Windows)
14
+
15
+ ```powershell
16
+ irm https://bdok.dev/install.ps1 | iex
17
+ ```
18
+
19
+ ### Homebrew (macOS / Linux)
20
+
21
+ ```bash
22
+ brew install bagdock/cli/bagdock
23
+ ```
24
+
25
+ ### Node.js
26
+
7
27
  ```bash
8
28
  # npm
9
29
  npm install -g @bagdock/cli
@@ -26,12 +46,89 @@ bunx @bagdock/cli --help
26
46
  pnpm dlx @bagdock/cli --help
27
47
  ```
28
48
 
49
+ ### Agent skills
50
+
51
+ This CLI ships with an agent skill that teaches AI coding agents (Cursor, Claude Code, Codex, Conductor, etc.) how to use the Bagdock CLI effectively — including non-interactive flags, output formats, and common pitfalls.
52
+
53
+ To install skills for Bagdock's full platform (API, CLI, adapters) from the central skills repository:
54
+
55
+ ```bash
56
+ npx skills add bagdock/bagdock-skills
57
+ ```
58
+
59
+ See [bagdock/bagdock-skills](https://github.com/bagdock/bagdock-skills) for all available skills and plugin manifests.
60
+
61
+ ## Local development
62
+
63
+ Use this when you want to change the CLI and run your build locally.
64
+
65
+ ### Prerequisites
66
+
67
+ - Node.js 20+
68
+ - Bun (for building)
69
+
70
+ ### Setup
71
+
72
+ Clone the repo:
73
+
74
+ ```bash
75
+ git clone https://github.com/bagdock/bagdock-cli.git
76
+ cd bagdock-cli
77
+ ```
78
+
79
+ Install dependencies:
80
+
81
+ ```bash
82
+ bun install
83
+ ```
84
+
85
+ Build locally:
86
+
87
+ ```bash
88
+ bun run build
89
+ ```
90
+
91
+ Output: `./dist/bagdock.js`
92
+
93
+ ### Running the CLI locally
94
+
95
+ Use the dev script:
96
+
97
+ ```bash
98
+ bun run dev -- --version
99
+ bun run dev -- doctor
100
+ bun run dev -- keys list --json
101
+ ```
102
+
103
+ Or run the built JS bundle:
104
+
105
+ ```bash
106
+ node dist/bagdock.js --version
107
+ ```
108
+
109
+ ### Making changes
110
+
111
+ After editing source files, rebuild:
112
+
113
+ ```bash
114
+ bun run build
115
+ ```
116
+
117
+ ### Running tests
118
+
119
+ ```bash
120
+ bun run test
121
+ ```
122
+
29
123
  ## Quick start
30
124
 
31
125
  ```bash
32
- # Authenticate with your Bagdock account
126
+ # Authenticate
33
127
  bagdock login
34
128
 
129
+ # Check your environment
130
+ bagdock doctor
131
+
35
132
  # Scaffold a new project
36
133
  bagdock init
37
134
 
@@ -50,34 +147,639 @@ bagdock deploy
50
147
 
51
148
  Both deploy to the Bagdock platform via the CLI. You don't need to manage any infrastructure.
52
149
 
150
+ ## Authentication
151
+
152
+ The CLI resolves your API key using the following priority chain:
153
+
154
+ | Priority | Source | How to set |
155
+ |----------|--------|-----------|
156
+ | 1 (highest) | `--api-key` flag | `bagdock --api-key sk_live_xxx deploy ...` |
157
+ | 2 | `BAGDOCK_API_KEY` env var | `export BAGDOCK_API_KEY=sk_live_xxx` |
158
+ | 3 | `BAGDOCK_TOKEN` env var | `export BAGDOCK_TOKEN=<jwt>` |
159
+ | 4 (lowest) | Config file | `bagdock login` |
160
+
161
+ If no key is found from any source, the CLI errors with code `auth_error`.
162
+
53
163
  ## Commands
54
164
 
55
- | Command | Description |
56
- |---------|-------------|
57
- | `bagdock login` | Authenticate via Device Authorization Grant (opens browser) |
58
- | `bagdock logout` | Clear stored credentials |
59
- | `bagdock whoami` | Show current authenticated user |
60
- | `bagdock init` | Scaffold a new project with `bagdock.json` |
61
- | `bagdock dev` | Start local dev server |
62
- | `bagdock deploy` | Build and deploy to Bagdock |
63
- | `bagdock env set` | Set an environment variable for your project |
64
- | `bagdock env list` | List environment variables |
65
- | `bagdock submit` | Submit for marketplace review |
165
+ ### `bagdock login`
66
166
 
67
- ## Authentication
167
+ Authenticate by starting an OAuth 2.0 Device Authorization Grant flow. The CLI opens your browser to the Bagdock dashboard where you approve access.
168
+
169
+ #### Interactive mode (default in terminals)
68
170
 
69
- The CLI uses the OAuth 2.0 Device Authorization Grant. When you run `bagdock login`, it will:
171
+ When run in a terminal, the CLI:
70
172
 
71
- 1. Display a one-time code
72
- 2. Open your browser to the Bagdock dashboard
73
- 3. Ask you to enter the code and approve access
74
- 4. Store credentials locally at `~/.bagdock/credentials.json`
173
+ 1. Requests a device code from the API
174
+ 2. Displays a one-time code and opens your browser
175
+ 3. Waits for you to enter the code and approve
176
+ 4. Stores credentials at `~/.bagdock/credentials.json`
177
+
178
+ #### Non-interactive mode (CI, pipes, scripts)
179
+
180
+ For headless environments, use an API key instead of interactive login:
181
+
182
+ ```bash
183
+ export BAGDOCK_API_KEY=sk_live_xxx
184
+ bagdock deploy --production --yes
185
+ ```
186
+
187
+ #### Output
188
+
189
+ ```bash
190
+ # JSON output
191
+ bagdock login --json
192
+ # => {"success":true,"config_path":"/Users/you/.bagdock/credentials.json","profile":"default"}
193
+ ```
194
+
195
+ #### Error codes
196
+
197
+ | Code | Cause |
198
+ |------|-------|
199
+ | `auth_error` | Device code request failed |
200
+ | `expired_token` | Device code expired before approval |
201
+ | `access_denied` | User denied authorization |
202
+
203
+ ---
204
+
205
+ ### `bagdock logout`
206
+
207
+ Clear stored credentials for the active profile.
208
+
209
+ ```bash
210
+ bagdock logout
211
+ ```
212
+
213
+ ---
214
+
215
+ ### `bagdock whoami`
216
+
217
+ Show the current authenticated user.
218
+
219
+ ```bash
220
+ bagdock whoami
221
+ # => Logged in as you@example.com
222
+ # Operator: op_abc123
223
+ # Profile: default
224
+ ```
225
+
226
+ JSON output:
227
+
228
+ ```bash
229
+ bagdock whoami --json
230
+ # => {"email":"you@example.com","operator_id":"op_abc123","profile":"default"}
231
+ ```
232
+
233
+ ---
234
+
235
+ ### `bagdock doctor`
236
+
237
+ Run environment diagnostics. Verifies your CLI version, API key, project config, and detects AI agent integrations.
238
+
239
+ ```bash
240
+ bagdock doctor
241
+ ```
242
+
243
+ #### Checks performed
244
+
245
+ | Check | Pass | Warn | Fail |
246
+ |-------|------|------|------|
247
+ | CLI Version | Running latest | Update available or registry unreachable | — |
248
+ | API Key | Key found (shows masked key + source) | — | No key found |
249
+ | Project Config | Valid `bagdock.json` found | No config or incomplete | — |
250
+ | AI Agents | Lists detected agents (or none) | — | — |
251
+
252
+ The API key is always masked in output (e.g. `sk_live_...xxxx`).
253
+
254
+ #### Interactive mode
255
+
256
+ Shows status icons with colored output:
257
+
258
+ ```
259
+ Bagdock Doctor
260
+
261
+ ✔ CLI Version: v0.3.0 (latest)
262
+ ✔ API Key: sk_live_...xxxx (source: env)
263
+ ✔ Project Config: smart-entry (edge/adapter)
264
+ ✔ AI Agents: Detected: Cursor, Claude Desktop
265
+ ```
266
+
267
+ #### JSON mode
268
+
269
+ ```bash
270
+ bagdock doctor --json
271
+ ```
272
+
273
+ ```json
274
+ {
275
+ "ok": true,
276
+ "checks": [
277
+ { "name": "CLI Version", "status": "pass", "message": "v0.3.0 (latest)" },
278
+ { "name": "API Key", "status": "pass", "message": "sk_live_...xxxx (source: env)" },
279
+ { "name": "Project Config", "status": "pass", "message": "smart-entry (edge/adapter)" },
280
+ { "name": "AI Agents", "status": "pass", "message": "Detected: Cursor" }
281
+ ]
282
+ }
283
+ ```
284
+
285
+ Each check has a `status` of `pass`, `warn`, or `fail`. The top-level `ok` is `false` if any check is `fail`.
286
+
287
+ #### Detected AI agents
288
+
289
+ | Agent | Detection method |
290
+ |-------|-----------------|
291
+ | Cursor | `~/.cursor` directory exists |
292
+ | Claude Desktop | Platform-specific config file exists |
293
+ | VS Code | `.vscode/mcp.json` in current directory |
294
+ | Windsurf | `~/.windsurf` directory exists |
295
+ | OpenClaw/Codex | `~/clawd/skills` or `~/.codex` directory exists |
296
+
297
+ #### Exit code
298
+
299
+ Exits `0` when all checks pass or warn. Exits `1` if any check fails.
300
+
301
+ ---
302
+
303
+ ### Switch between profiles
304
+
305
+ If you work across multiple Bagdock operators, the CLI supports named profiles.
306
+
307
+ #### List profiles
308
+
309
+ ```bash
310
+ bagdock auth list
311
+ ```
312
+
313
+ #### Switch active profile
314
+
315
+ ```bash
316
+ bagdock auth switch production
317
+ ```
318
+
319
+ You can also use the global `--profile` (or `-p`) flag on any command to run it with a specific profile:
320
+
321
+ ```bash
322
+ bagdock --profile production deploy --yes
323
+ bagdock -p staging keys list
324
+ ```
325
+
326
+ ---
327
+
328
+ ### `bagdock init [dir]`
329
+
330
+ Scaffold a new project with a `bagdock.json` config file.
331
+
332
+ | Flag | Description |
333
+ |------|-------------|
334
+ | `--type <edge\|app>` | Deployment target |
335
+ | `--kind <adapter\|comms\|webhook\|ui-extension\|microfrontend>` | Specific project kind |
336
+ | `--category <name>` | Marketplace category |
337
+ | `--slug <name>` | Unique project slug (kebab-case) |
338
+ | `--name <name>` | Display name |
339
+
340
+ #### Examples
341
+
342
+ ```bash
343
+ # Interactive scaffolding
344
+ bagdock init
345
+
346
+ # Non-interactive
347
+ bagdock init --type edge --kind adapter --category access_control --slug smart-entry --name "Smart Entry"
348
+ ```
349
+
350
+ ---
351
+
352
+ ### `bagdock deploy`
353
+
354
+ Build and deploy to the Bagdock platform.
355
+
356
+ | Flag | Description |
357
+ |------|-------------|
358
+ | `--production` | Deploy to production (default: staging) |
359
+ | `--preview` | Create an ephemeral preview deployment |
360
+ | `--yes` | Skip confirmation prompts (required in non-TTY) |
361
+
362
+ #### Examples
363
+
364
+ ```bash
365
+ # Deploy to staging
366
+ bagdock deploy
367
+
368
+ # Deploy to production
369
+ bagdock deploy --production --yes
370
+
371
+ # Preview deployment
372
+ bagdock deploy --preview --json
373
+ ```
374
+
375
+ #### Error codes
376
+
377
+ | Code | Cause |
378
+ |------|-------|
379
+ | `auth_error` | Not authenticated |
380
+ | `no_config` | No `bagdock.json` found |
381
+ | `build_error` | Build failed |
382
+ | `deploy_error` | API rejected the deployment |
383
+
384
+ ---
385
+
386
+ ### `bagdock submit`
387
+
388
+ Submit your app for marketplace review. Transitions `review_status` from `draft` to `submitted`.
389
+
390
+ ```bash
391
+ bagdock submit
392
+ ```
393
+
394
+ ---
395
+
396
+ ### `bagdock validate`
397
+
398
+ Run local pre-submission checks on `bagdock.json` and your bundle before submitting.
399
+
400
+ ```bash
401
+ bagdock validate
402
+ ```
403
+
404
+ Checks performed:
405
+
406
+ | Check | Pass | Warn | Fail |
407
+ |-------|------|------|------|
408
+ | bagdock.json | Found and parsed | — | Missing or invalid JSON |
409
+ | Required fields | All present | — | Missing name, slug, version, type, category, or main |
410
+ | Type | Valid type | — | Invalid type value |
411
+ | Kind | — | Unknown kind | — |
412
+ | Entry point | File exists (shows size) | — | File not found |
413
+ | Bundle size | Under 10 MB | Approaching limit (>80%) | Over 10 MB |
414
+ | Project link | — | Slug mismatch with linked project | — |
415
+
416
+ ```bash
417
+ # JSON output
418
+ bagdock validate --json
419
+ # => {"ok":true,"checks":[...]}
420
+ ```
421
+
422
+ Exit code `0` if all checks pass or warn. Exit code `1` if any check fails.
423
+
424
+ ---
425
+
426
+ ### `bagdock submission list`
427
+
428
+ List submission history for the current app.
429
+
430
+ ```bash
431
+ bagdock submission list
432
+ bagdock submission list --app my-adapter --json
433
+ ```
434
+
435
+ | Flag | Description |
436
+ |------|-------------|
437
+ | `--app <slug>` | App slug (defaults to `bagdock.json` or linked project) |
438
+
439
+ ### `bagdock submission status <id>`
440
+
441
+ Fetch detailed review state for a specific submission.
442
+
443
+ ```bash
444
+ bagdock submission status iadpv_abc123
445
+ bagdock submission status iadpv_abc123 --json
446
+ ```
447
+
448
+ | Flag | Description |
449
+ |------|-------------|
450
+ | `--app <slug>` | App slug |
451
+
452
+ ### `bagdock submission withdraw <id>`
453
+
454
+ Cancel a pending submission before approval. Only works when `review_status` is `submitted`.
455
+
456
+ ```bash
457
+ bagdock submission withdraw iadpv_abc123
458
+ ```
459
+
460
+ | Flag | Description |
461
+ |------|-------------|
462
+ | `--app <slug>` | App slug |
463
+
464
+ #### Error codes
465
+
466
+ | Code | Cause |
467
+ |------|-------|
468
+ | `not_found` | Submission or app not found |
469
+ | `invalid_status` | App is not in `submitted` state |
470
+
471
+ ---
472
+
473
+ ### `bagdock open [slug]`
474
+
475
+ Open the current project in the Bagdock dashboard.
476
+
477
+ ```bash
478
+ bagdock open
479
+ bagdock open my-adapter
480
+ ```
481
+
482
+ Reads the slug from `bagdock.json`, linked project, or the argument.
483
+
484
+ ---
485
+
486
+ ### `bagdock inspect [slug]`
487
+
488
+ Show deployment details and status for an app.
489
+
490
+ ```bash
491
+ bagdock inspect
492
+ bagdock inspect my-adapter --json
493
+ ```
494
+
495
+ Displays: name, slug, type, version, review status, worker URL, namespace, timestamps.
496
+
497
+ ---
498
+
499
+ ### `bagdock link`
500
+
501
+ Link the current directory to a Bagdock app or edge. Other commands use the linked slug as a fallback.
502
+
503
+ ```bash
504
+ # Interactive: select from your apps
505
+ bagdock link
506
+
507
+ # Non-interactive
508
+ bagdock link --slug my-adapter
509
+ ```
510
+
511
+ | Flag | Description |
512
+ |------|-------------|
513
+ | `--slug <slug>` | Project slug (required in non-interactive mode) |
514
+
515
+ Stores the link in `.bagdock/link.json` in the current directory.
516
+
517
+ ---
518
+
519
+ ### `bagdock env list`
520
+
521
+ List environment variables for the current app.
522
+
523
+ ```bash
524
+ bagdock env list
525
+ bagdock env list --json
526
+ ```
527
+
528
+ ### `bagdock env set <key> <value>`
529
+
530
+ Set an environment variable. Takes effect on next deploy.
531
+
532
+ ```bash
533
+ bagdock env set VENDOR_API_KEY sk_live_abc123
534
+ ```
535
+
536
+ ### `bagdock env remove <key>`
537
+
538
+ Remove an environment variable.
539
+
540
+ ```bash
541
+ bagdock env remove VENDOR_API_KEY
542
+ ```
543
+
544
+ ### `bagdock env pull [file]`
545
+
546
+ Pull remote env var keys to a local `.env` file for development.
547
+
548
+ ```bash
549
+ bagdock env pull
550
+ bagdock env pull .env.development
551
+ ```
552
+
553
+ The API does not expose secret values. The file is created with keys and empty values — fill them in for local dev.
554
+
555
+ ---
556
+
557
+ ### `bagdock keys create`
558
+
559
+ Create a new API key. The raw key is shown **once** on creation.
560
+
561
+ | Flag | Required | Description |
562
+ |------|----------|-------------|
563
+ | `--name <name>` | Yes | Display name for the key |
564
+ | `--environment <live\|test>` | No | Environment (default: `live`) |
565
+ | `--type <secret\|publishable>` | No | Key type (default: `secret`) |
566
+ | `--category <full_access\|restricted>` | No | Access level (default: `full_access`) |
567
+ | `--scopes <scope...>` | No | Permission scopes (for restricted keys) |
568
+
569
+ #### Examples
570
+
571
+ ```bash
572
+ # Create a live secret key
573
+ bagdock keys create --name "GitHub Actions" --environment live
574
+
575
+ # Create a restricted test key
576
+ bagdock keys create --name "Read-Only" --environment test --category restricted --scopes units:read contacts:read
577
+
578
+ # JSON output (capture the raw key)
579
+ bagdock keys create --name "CI Deploy" --json
580
+ ```
581
+
582
+ #### Output
583
+
584
+ ```json
585
+ {
586
+ "id": "ak_abc123",
587
+ "name": "CI Deploy",
588
+ "key": "sk_live_abc123def456...",
589
+ "key_prefix": "sk_live_abc123de",
590
+ "environment": "live",
591
+ "key_type": "secret",
592
+ "created_at": "2026-04-04T12:00:00Z"
593
+ }
594
+ ```
595
+
596
+ ### `bagdock keys list`
597
+
598
+ List API keys (prefix and metadata only — raw keys are never stored).
599
+
600
+ | Flag | Description |
601
+ |------|-------------|
602
+ | `--environment <live\|test>` | Filter by environment |
603
+
604
+ ```bash
605
+ bagdock keys list
606
+ bagdock keys list --environment live --json
607
+ ```
608
+
609
+ ### `bagdock keys delete <id>`
610
+
611
+ Revoke an API key permanently.
612
+
613
+ | Flag | Description |
614
+ |------|-------------|
615
+ | `--yes` | Skip confirmation (required in non-TTY) |
616
+ | `--reason <text>` | Reason for revocation (optional, recorded) |
617
+
618
+ ```bash
619
+ bagdock keys delete ak_abc123 --yes --reason "Key compromised"
620
+ ```
621
+
622
+ #### Error codes
623
+
624
+ | Code | Cause |
625
+ |------|-------|
626
+ | `auth_error` | Not authenticated |
627
+ | `not_found` | Key ID does not exist |
628
+ | `forbidden` | Insufficient permissions |
629
+
630
+ ---
631
+
632
+ ### `bagdock apps list`
633
+
634
+ List deployed apps and edges.
635
+
636
+ ```bash
637
+ bagdock apps list
638
+ bagdock apps list --json
639
+ ```
640
+
641
+ ### `bagdock apps get <slug>`
642
+
643
+ Get details for a specific deployed app.
644
+
645
+ ```bash
646
+ bagdock apps get smart-entry
647
+ bagdock apps get smart-entry --json
648
+ ```
649
+
650
+ ---
651
+
652
+ ### `bagdock logs list`
653
+
654
+ List recent execution log entries.
655
+
656
+ | Flag | Description |
657
+ |------|-------------|
658
+ | `--app <slug>` | Filter by app slug |
659
+ | `--limit <n>` | Number of entries (default: 50, max: 200) |
660
+
661
+ ```bash
662
+ bagdock logs list --app smart-entry --limit 20
663
+ ```
664
+
665
+ ### `bagdock logs tail`
666
+
667
+ Stream logs in real-time.
668
+
669
+ | Flag | Description |
670
+ |------|-------------|
671
+ | `--app <slug>` | App to stream logs for |
672
+
673
+ ```bash
674
+ bagdock logs tail --app smart-entry
675
+ ```
676
+
677
+ ### `bagdock logs get <id>`
678
+
679
+ Get a single log entry by ID.
680
+
681
+ | Flag | Description |
682
+ |------|-------------|
683
+ | `--app <slug>` | App the log belongs to |
684
+
685
+ ```bash
686
+ bagdock logs get log_abc123 --app smart-entry
687
+ ```
688
+
689
+ ---
690
+
691
+ ## Global options
692
+
693
+ These flags work on every command and are passed before the subcommand:
694
+
695
+ ```
696
+ bagdock [global options] <command> [command options]
697
+ ```
698
+
699
+ | Flag | Description |
700
+ |------|-------------|
701
+ | `--api-key <key>` | Override API key for this invocation (takes highest priority) |
702
+ | `-p, --profile <name>` | Profile to use (overrides `BAGDOCK_PROFILE` env var) |
703
+ | `--json` | Force JSON output even in interactive terminals |
704
+ | `-q, --quiet` | Suppress spinners and status output (implies `--json`) |
705
+ | `--version` | Print version and exit |
706
+ | `--help` | Show help text |
707
+
708
+ ## Output behavior
709
+
710
+ The CLI has two output modes:
711
+
712
+ | Mode | When | Stdout | Stderr |
713
+ |------|------|--------|--------|
714
+ | Interactive | Terminal (TTY) | Formatted text | Spinners, prompts |
715
+ | Machine | Piped, CI, or `--json` | JSON | Nothing |
716
+
717
+ Switching is automatic — pipe to another command and JSON output activates:
718
+
719
+ ```bash
720
+ bagdock doctor | jq '.checks[].name'
721
+ bagdock keys list | jq '.[].key_prefix'
722
+ ```
723
+
724
+ ### Error output
725
+
726
+ Errors always exit with code `1` and output structured JSON to stdout:
727
+
728
+ ```json
729
+ { "error": { "code": "auth_error", "message": "No API key found" } }
730
+ ```
731
+
732
+ ## API keys
733
+
734
+ API keys follow a Stripe-style prefix convention:
735
+
736
+ | Prefix | Meaning |
737
+ |--------|---------|
738
+ | `sk_live_` | Secret key, live environment |
739
+ | `sk_test_` | Secret key, test/sandbox environment |
740
+ | `pk_live_` | Publishable key, live |
741
+ | `pk_test_` | Publishable key, test |
742
+ | `rk_live_` | Restricted key, live |
743
+ | `rk_test_` | Restricted key, test |
744
+
745
+ The raw key is shown **once** on creation. Only the prefix and metadata are stored and displayed after that.
746
+
747
+ ## Agent & CI/CD usage
748
+
749
+ ### CI/CD
750
+
751
+ Set `BAGDOCK_API_KEY` as an environment variable — no `bagdock login` needed:
752
+
753
+ ```yaml
754
+ # GitHub Actions
755
+ env:
756
+ BAGDOCK_API_KEY: ${{ secrets.BAGDOCK_API_KEY }}
757
+ steps:
758
+ - run: |
759
+ bagdock deploy --production --yes --json
760
+ ```
761
+
762
+ ### AI agents
763
+
764
+ Agents calling the CLI as a subprocess automatically get JSON output (non-TTY detection). The contract:
765
+
766
+ - **Input**: All required flags must be provided (no interactive prompts)
767
+ - **Output**: JSON to stdout, nothing to stderr
768
+ - **Exit code**: `0` success, `1` error
769
+ - **Errors**: Always include `message` and `code` fields
75
770
 
76
771
  ## Configuration
77
772
 
78
- Each project uses a `bagdock.json` file. All config lives here — no `wrangler.toml` needed. A temporary one is auto-generated for local dev and should be gitignored.
773
+ | Item | Path | Notes |
774
+ |------|------|-------|
775
+ | Config directory | `~/.bagdock/` | Respects `BAGDOCK_INSTALL` |
776
+ | Credentials | `~/.bagdock/credentials.json` | `0600` permissions (owner read/write) |
777
+ | Active profile | Stored in credentials file | Overridden by `--profile` or `BAGDOCK_PROFILE` |
778
+ | Project config | `./bagdock.json` | Per-project, in repo root |
779
+
780
+ ### bagdock.json examples
79
781
 
80
- ### Edge example
782
+ #### Edge (backend worker)
81
783
 
82
784
  ```json
83
785
  {
@@ -90,7 +792,7 @@ Each project uses a `bagdock.json` file. All config lives here — no `wrangler.
90
792
  }
91
793
  ```
92
794
 
93
- ### App example
795
+ #### App (UI extension)
94
796
 
95
797
  ```json
96
798
  {