primitive-admin 1.1.0-alpha.3 → 1.1.0-alpha.31

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 (99) hide show
  1. package/README.md +168 -21
  2. package/assets/skill/skills/primitive-platform/SKILL.md +226 -0
  3. package/dist/bin/primitive.js +198 -15
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/admins.js +107 -0
  6. package/dist/src/commands/admins.js.map +1 -1
  7. package/dist/src/commands/analytics.js +464 -55
  8. package/dist/src/commands/analytics.js.map +1 -1
  9. package/dist/src/commands/apps.js +27 -13
  10. package/dist/src/commands/apps.js.map +1 -1
  11. package/dist/src/commands/auth.js +165 -5
  12. package/dist/src/commands/auth.js.map +1 -1
  13. package/dist/src/commands/blob-buckets.js +354 -0
  14. package/dist/src/commands/blob-buckets.js.map +1 -0
  15. package/dist/src/commands/catalog.js +17 -17
  16. package/dist/src/commands/catalog.js.map +1 -1
  17. package/dist/src/commands/collection-type-configs.js +178 -0
  18. package/dist/src/commands/collection-type-configs.js.map +1 -0
  19. package/dist/src/commands/collections.js +526 -0
  20. package/dist/src/commands/collections.js.map +1 -0
  21. package/dist/src/commands/comparisons.js +6 -6
  22. package/dist/src/commands/comparisons.js.map +1 -1
  23. package/dist/src/commands/cron-triggers.js +364 -0
  24. package/dist/src/commands/cron-triggers.js.map +1 -0
  25. package/dist/src/commands/database-types.js +462 -0
  26. package/dist/src/commands/database-types.js.map +1 -0
  27. package/dist/src/commands/databases.js +1067 -58
  28. package/dist/src/commands/databases.js.map +1 -1
  29. package/dist/src/commands/documents.js +510 -2
  30. package/dist/src/commands/documents.js.map +1 -1
  31. package/dist/src/commands/email-templates.js +281 -0
  32. package/dist/src/commands/email-templates.js.map +1 -0
  33. package/dist/src/commands/env.js +260 -0
  34. package/dist/src/commands/env.js.map +1 -0
  35. package/dist/src/commands/group-type-configs.js +189 -0
  36. package/dist/src/commands/group-type-configs.js.map +1 -0
  37. package/dist/src/commands/groups.js +28 -25
  38. package/dist/src/commands/groups.js.map +1 -1
  39. package/dist/src/commands/init.js +719 -188
  40. package/dist/src/commands/init.js.map +1 -1
  41. package/dist/src/commands/integrations.js +504 -33
  42. package/dist/src/commands/integrations.js.map +1 -1
  43. package/dist/src/commands/prompts.js +17 -16
  44. package/dist/src/commands/prompts.js.map +1 -1
  45. package/dist/src/commands/rule-sets.js +366 -0
  46. package/dist/src/commands/rule-sets.js.map +1 -0
  47. package/dist/src/commands/secrets.js +108 -0
  48. package/dist/src/commands/secrets.js.map +1 -0
  49. package/dist/src/commands/skill.js +29 -0
  50. package/dist/src/commands/skill.js.map +1 -0
  51. package/dist/src/commands/sync.js +2363 -182
  52. package/dist/src/commands/sync.js.map +1 -1
  53. package/dist/src/commands/tokens.js +9 -9
  54. package/dist/src/commands/tokens.js.map +1 -1
  55. package/dist/src/commands/users.js +426 -4
  56. package/dist/src/commands/users.js.map +1 -1
  57. package/dist/src/commands/webhooks.js +386 -0
  58. package/dist/src/commands/webhooks.js.map +1 -0
  59. package/dist/src/commands/workflows.js +614 -64
  60. package/dist/src/commands/workflows.js.map +1 -1
  61. package/dist/src/lib/api-client.js +942 -83
  62. package/dist/src/lib/api-client.js.map +1 -1
  63. package/dist/src/lib/config.js +51 -53
  64. package/dist/src/lib/config.js.map +1 -1
  65. package/dist/src/lib/constants.js +3 -0
  66. package/dist/src/lib/constants.js.map +1 -0
  67. package/dist/src/lib/credentials-store.js +307 -0
  68. package/dist/src/lib/credentials-store.js.map +1 -0
  69. package/dist/src/lib/env-resolver.js +121 -0
  70. package/dist/src/lib/env-resolver.js.map +1 -0
  71. package/dist/src/lib/init-config.js +87 -0
  72. package/dist/src/lib/init-config.js.map +1 -0
  73. package/dist/src/lib/migration-nag.js +163 -0
  74. package/dist/src/lib/migration-nag.js.map +1 -0
  75. package/dist/src/lib/output.js +58 -6
  76. package/dist/src/lib/output.js.map +1 -1
  77. package/dist/src/lib/paginate.js +42 -0
  78. package/dist/src/lib/paginate.js.map +1 -0
  79. package/dist/src/lib/project-config.js +209 -0
  80. package/dist/src/lib/project-config.js.map +1 -0
  81. package/dist/src/lib/refresh-admin-credentials.js +103 -0
  82. package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
  83. package/dist/src/lib/skill-installer.js +135 -0
  84. package/dist/src/lib/skill-installer.js.map +1 -0
  85. package/dist/src/lib/sync-paths.js +102 -0
  86. package/dist/src/lib/sync-paths.js.map +1 -0
  87. package/dist/src/lib/template.js +279 -18
  88. package/dist/src/lib/template.js.map +1 -1
  89. package/dist/src/lib/toml-database-config.js +384 -0
  90. package/dist/src/lib/toml-database-config.js.map +1 -0
  91. package/dist/src/lib/toml-params-validator.js +183 -0
  92. package/dist/src/lib/toml-params-validator.js.map +1 -0
  93. package/dist/src/lib/version-check.js +172 -0
  94. package/dist/src/lib/version-check.js.map +1 -0
  95. package/dist/src/lib/workflow-fragments.js +121 -0
  96. package/dist/src/lib/workflow-fragments.js.map +1 -0
  97. package/dist/src/lib/workflow-toml-validator.js +328 -0
  98. package/dist/src/lib/workflow-toml-validator.js.map +1 -0
  99. package/package.json +7 -4
package/README.md CHANGED
@@ -150,12 +150,13 @@ Manage users within an app.
150
150
 
151
151
  ```bash
152
152
  primitive users list [app-id] # List users
153
+ primitive users create <email> [--role admin|member] # Create/add user by email
153
154
  primitive users invite [app-id] <email> [--role admin] # Invite user
154
155
  primitive users remove [app-id] <user-id> # Remove user
155
156
  primitive users set-role [app-id] <user-id> <role> # Change role
156
157
  primitive users transfer-owner [app-id] <new-owner-id> # Transfer ownership
157
- primitive users invitations list [app-id] # List pending invitations
158
- primitive users invitations delete [app-id] <inv-id> # Delete invitation
158
+ primitive users mint-jwt <user-id> [--role <role>] # Mint test JWT (dev/test only)
159
+ primitive users invitations [app-id] # List pending invitations
159
160
  ```
160
161
 
161
162
  ### Waitlist
@@ -197,6 +198,26 @@ primitive integrations secrets add <id> --data '{"apiKey":"..."}'
197
198
  primitive integrations secrets archive <id> <secret-id>
198
199
  ```
199
200
 
201
+ ### Secrets
202
+
203
+ Manage encrypted app secrets (API keys, tokens, credentials). Values are encrypted at rest and never displayed after creation.
204
+
205
+ ```bash
206
+ primitive secrets list [--app <app-id>] # List secrets (values never shown)
207
+ primitive secrets set <KEY> --value <value> [--summary <text>] # Create or update a secret
208
+ primitive secrets delete <KEY> # Delete a secret
209
+ ```
210
+
211
+ **Examples:**
212
+ ```bash
213
+ primitive secrets set OPENAI_API_KEY --value "sk-..." --summary "Production key"
214
+ primitive secrets set STRIPE_SECRET --value "sk_live_..."
215
+ primitive secrets list --json
216
+ primitive secrets delete STRIPE_SECRET
217
+ ```
218
+
219
+ Keys must be uppercase letters, digits, and underscores (e.g., `OPENAI_API_KEY`). Max 100 secrets per app, 2 KB per value. The `set` command is an upsert — it creates or updates automatically. Use `{{secrets.KEY}}` in workflows and `secrets.KEY` in CEL rules.
220
+
200
221
  ### Prompts
201
222
 
202
223
  Manage LLM prompt configurations.
@@ -248,6 +269,20 @@ primitive workflows runs list <workflow-id>
248
269
  primitive workflows runs status <workflow-id> <run-id>
249
270
  ```
250
271
 
272
+ **Workflow TOML push-time validation (issue #685):** Every command that
273
+ pushes a workflow TOML (`workflows create --from-file`,
274
+ `workflows draft update --from-file`, `workflows configs create --from-file`,
275
+ `workflows configs update --from-file`, and `primitive sync push`) runs the
276
+ file through `cli/src/lib/workflow-toml-validator.ts` before sending it to
277
+ the server. The validator rejects any step with a top-level field outside
278
+ the universal-and-consumed allowlist — most commonly catching the footgun
279
+ where `[steps.<id>.request]` is written under `[[steps]]` (TOML places the
280
+ sub-table under `steps[N][<id>]`, not the intended `steps[N].request`, so
281
+ the runtime silently runs the step with an empty `request` block). The
282
+ correct form for the most-recent step is `[steps.request]`. When adding a
283
+ new step kind that consumes a new top-level field, add the field name to
284
+ `ALLOWLISTED_FIELDS` in that file.
285
+
251
286
  ### Tokens
252
287
 
253
288
  Manage long-lived API access tokens for headless/server authentication.
@@ -267,12 +302,13 @@ primitive tokens revoke <token-id> [app-id] # Revoke t
267
302
 
268
303
  ### Databases
269
304
 
270
- Manage online databases, permissions, and group permissions.
305
+ Manage online databases and permissions. `list` returns databases the user has direct access to; group-shared databases are listed via `primitive groups databases`.
271
306
 
272
307
  ```bash
273
- primitive databases list [app-id] # List databases
308
+ primitive databases list [app-id] # List databases (direct access)
274
309
  primitive databases create <title> [app-id] # Create database
275
310
  primitive databases get <database-id> [app-id] # Get details
311
+ primitive databases update <database-id> [options] # Update title or type
276
312
  primitive databases delete <database-id> [app-id] # Delete database
277
313
  ```
278
314
 
@@ -283,14 +319,68 @@ primitive databases permissions grant <database-id> --user-id <uid> --permission
283
319
  primitive databases permissions revoke <database-id> <user-id> [app-id]
284
320
  ```
285
321
 
286
- **Group permissions:**
322
+ Permission values: `owner` (set at creation), `manager`
323
+
324
+ **Metadata:**
325
+ ```bash
326
+ primitive databases metadata update <database-id> --data '{"key":"value"}' # Merge-update metadata
327
+ ```
328
+
329
+ **Operations:**
287
330
  ```bash
288
- primitive databases group-permissions list <database-id> [app-id]
289
- primitive databases group-permissions grant <database-id> --group-type <type> --group-id <id> --permission <perm> [app-id]
290
- primitive databases group-permissions revoke <database-id> <group-type> <group-id> [app-id]
331
+ primitive databases operations list <database-id> [app-id] # List registered operations
332
+ primitive databases operations execute <database-id> <op-name> --params '{}' # Execute operation
333
+ primitive databases operations execute <database-id> <op-name> --token <jwt> # Execute as specific user
291
334
  ```
292
335
 
293
- Permission values: `owner`, `read-write`, `reader`
336
+ The `--token` flag lets you execute an operation as a specific user using a test JWT from `users mint-jwt`. Useful for testing access rules.
337
+
338
+ **Records (schema introspection):**
339
+ ```bash
340
+ primitive databases records models <database-id> [app-id] # List model names
341
+ primitive databases records describe <database-id> <model> [app-id] # Show inferred schema
342
+ ```
343
+
344
+ **Indexes:**
345
+ ```bash
346
+ primitive databases indexes list <database-id> [--model <name>] # List indexes
347
+ primitive databases indexes create <database-id> <model> <field> [options] # Create index
348
+ primitive databases indexes drop <database-id> <model> <field> # Drop index
349
+ ```
350
+
351
+ **Export / Import:**
352
+ ```bash
353
+ primitive databases export [app-id] <database-id> --output <dir> # Export records, indexes, constraints
354
+ primitive databases import [app-id] <path> --overwrite --dry-run # Import from export directory
355
+ ```
356
+
357
+ Export creates a directory with `metadata.json`, `records.jsonl`, `indexes.json`, and `constraints.json`. Import restores records and indexes into a new or existing database. Database type config (operations, triggers, access rules) is managed separately via `primitive sync` — run `sync push` on the target app before importing.
358
+
359
+ ### Documents
360
+
361
+ Manage document ownership, group permissions, and export/import.
362
+
363
+ ```bash
364
+ primitive documents transfer-owner [app-id] <document-id> <new-owner-id> # Transfer ownership
365
+ ```
366
+
367
+ **Group permissions on documents:**
368
+ ```bash
369
+ primitive documents group-permissions list <document-id>
370
+ primitive documents group-permissions grant <document-id> --group-type <type> --group-id <id> --permission <perm>
371
+ primitive documents group-permissions revoke <document-id> <group-type> <group-id>
372
+ ```
373
+
374
+ Permission values: `read-write`, `reader`
375
+
376
+ **Export / Import:**
377
+ ```bash
378
+ primitive documents export [app-id] <document-id> --output <dir> # Export Yjs state, blobs, permissions, aliases
379
+ primitive documents export-all [app-id] --user-id <id> --owned-only # Export all docs for a user
380
+ primitive documents import [app-id] <path> --overwrite --aliases overwrite|skip --dry-run # Import from export
381
+ ```
382
+
383
+ Export creates a directory per document with `metadata.json`, `document.yjs` (Yjs state), `permissions.json` (for reference), and `blobs/` (attachments). Permissions are exported for reference but not restored during import — the importing admin is the new owner and manages sharing in the target app. Document IDs are preserved across import. User-scoped aliases can be restored with `--aliases overwrite` (update existing) or `--aliases skip` (keep existing, default).
294
384
 
295
385
  ### Groups
296
386
 
@@ -317,20 +407,46 @@ primitive groups members set-role <group-type> <group-id> <user-id> <role> [app-
317
407
  primitive groups memberships <user-id> [app-id] # List user's group memberships
318
408
  ```
319
409
 
410
+ **Group resource access:**
411
+ ```bash
412
+ primitive groups documents <group-type> <group-id> # List documents a group can access
413
+ ```
414
+
415
+ Group permissions on documents are managed via `primitive documents group-permissions` (see [Documents](#documents) above).
416
+
320
417
  ### Analytics
321
418
 
322
419
  View usage analytics for an app.
323
420
 
324
421
  ```bash
325
- primitive analytics overview [app-id] # Activity overview
326
- primitive analytics top-users [app-id] # Most active users
327
- primitive analytics user [app-id] <user-ulid> # User activity details
328
- primitive analytics integrations [app-id] # Integration metrics
422
+ # Overview & active users
423
+ primitive analytics overview [app-id] # DAU / WAU / MAU + growth
424
+ primitive analytics daily-active [app-id] # Daily active users time series
425
+ primitive analytics rolling-active [app-id] # Rolling active users (28 points)
426
+ primitive analytics cohort-retention [app-id] # Weekly cohort retention matrix
427
+
428
+ # Users
429
+ primitive analytics top-users [app-id] # Most active users
430
+ primitive analytics user-search [app-id] --query <q> # Search by email or ULID
431
+ primitive analytics user-detail <user-ulid> [app-id] # User activity breakdown
432
+ primitive analytics user-snapshot <user-ulid> [app-id] # Latest context snapshot
433
+
434
+ # Events
435
+ primitive analytics events [app-id] # Paginated event feed
436
+ primitive analytics events-grouped [app-id] # Events grouped by dimension
437
+
438
+ # Features
439
+ primitive analytics integrations [app-id] # Integration usage metrics
440
+ primitive analytics workflows [app-id] # Top workflows by runs
441
+ primitive analytics prompts [app-id] # Top prompts by executions
329
442
  ```
330
443
 
331
- **Options:**
332
- - `--window-days <n>` - Time window (default: 30)
333
- - `--limit <n>` - Result limit for top-users
444
+ **Common options:**
445
+ - `--window-days <n>` - Time window in days (default varies per command)
446
+ - `--limit <n>` - Result limit (top-users, workflows, prompts)
447
+ - `--group-by <dim>` - Dimension for events-grouped (action, feature, route, country, deviceType, plan, day)
448
+ - `--page <n>` - Page number for events feed (0-based)
449
+ - `--json` - Output raw JSON
334
450
 
335
451
  ### Admins (Super-Admin Only)
336
452
 
@@ -475,6 +591,35 @@ primitive apps list
475
591
  primitive apps list --json | jq '.[0].appId'
476
592
  ```
477
593
 
594
+ ### Stdout vs. stderr
595
+
596
+ The CLI follows the same convention as `git`, `kubectl`, `aws`, and `gh`:
597
+
598
+ - **stdout** carries the *data* the command produced — JSON documents under
599
+ `--json`, tabular listings (`apps list`), raw values (`primitive token`),
600
+ and the primary `label: value` fields a `get` / `show` / `describe` command
601
+ emits (e.g. `primitive integrations get <id>`).
602
+ - **stderr** carries *diagnostics* — status text (`✓ Created…`,
603
+ `i Waiting for completion...`), warnings (`!` markers), progress lines, and
604
+ the `key: value` summaries shown *after* a side-effecting command runs
605
+ (e.g. the `Webhook ID: …` confirmation printed by `webhooks create`).
606
+
607
+ This means `primitive <cmd> --json | jq` always works, regardless of any
608
+ status / warning / progress text the command may print along the way.
609
+ It also means `primitive integrations get <id> > out.txt` writes the
610
+ integration's fields to `out.txt` while the status diagnostics still appear
611
+ on the terminal via stderr.
612
+
613
+ Conversely, redirecting stderr (`primitive <cmd> 2>/dev/null`) silences
614
+ diagnostics — including success checkmarks like `✓ Pushed 3 changes` — so
615
+ prefer `2>&1 >file.txt` if you want the full transcript.
616
+
617
+ For contributors writing new commands, the output helpers in
618
+ `cli/src/lib/output.ts` make the data-vs-diagnostic split explicit: use
619
+ `json()` and `result(label, value)` for data the caller asked for, and
620
+ `success()` / `info()` / `warn()` / `keyValue()` / `divider()` / `heading()`
621
+ for diagnostics about what the command did.
622
+
478
623
  ## Exit Codes
479
624
 
480
625
  - `0` - Success
@@ -545,11 +690,13 @@ cli/tests/
545
690
  config.test.ts # Credentials and config management
546
691
  output.test.ts # Output formatting functions
547
692
  integration/
548
- api-client.test.ts # API client HTTP tests
549
- commands.test.ts # CLI command tests
550
- tokens.test.ts # Token lifecycle tests
551
- databases.test.ts # Database CRUD, permissions, group permissions tests
552
- groups.test.ts # Group CRUD, members, memberships tests
693
+ api-client.test.ts # API client HTTP tests
694
+ commands.test.ts # CLI command tests
695
+ tokens.test.ts # Token lifecycle tests
696
+ databases.test.ts # Database CRUD, permissions, group permissions tests
697
+ documents.test.ts # Document group permissions, group resource listing tests
698
+ groups.test.ts # Group CRUD, members, memberships tests
699
+ classroom-e2e.test.ts # End-to-end classroom app workflow (types, rules, operations, access)
553
700
  ```
554
701
 
555
702
  ## Troubleshooting
@@ -0,0 +1,226 @@
1
+ ---
2
+ name: primitive-platform
3
+ description: >
4
+ Expert guide for building applications on the Primitive platform. MUST be used whenever the user
5
+ is writing code that uses js-bao, js-bao-wss-client, primitive-app components, or any Primitive
6
+ platform feature (documents, databases, workflows, prompts, integrations, blobs, authentication,
7
+ users/groups). Also trigger whenever about to run any `primitive` CLI command (e.g., primitive sync, primitive integrations, primitive apps, primitive env) to ensure Step 0 CLI verification is performed first. After writing or modifying code that touches Primitive
8
+ APIs, this skill cross-references the implementation against official guides and automatically
9
+ corrects common mistakes. Use this skill even if the user doesn't explicitly ask for it —
10
+ any Primitive-related code should be validated against current best practices.
11
+ allowed-tools: Bash, Read, Edit, Write, Glob, Grep, Agent
12
+ ---
13
+
14
+ # Primitive Platform Development Guide
15
+
16
+ You are an expert on the Primitive platform. Your job is to help developers write correct,
17
+ idiomatic Primitive code by leveraging the CLI's built-in guide system and enforcing best practices.
18
+
19
+ **The CLI guides are the single source of truth.** Never hardcode or memorize guide content —
20
+ always fetch the latest from the CLI.
21
+
22
+ ## Step 0: Verify CLI Configuration
23
+
24
+ The Primitive CLI is **project-scoped**. Each project has a `.primitive/config.json` (committed to
25
+ the repo) that defines named environments (`dev`, `prod`, `staging`, …), where each environment
26
+ binds an `apiUrl` and (optionally) an `appId`. Per-environment auth tokens live in
27
+ `.primitive/credentials.json` (gitignored). There is no global "currently active app" — the active
28
+ environment determines the server *and* the app.
29
+
30
+ **Before running any CLI commands**, your *first* check is whether the project is in project mode:
31
+
32
+ ```bash
33
+ ls .primitive/config.json # exists at project root or any ancestor?
34
+ ```
35
+
36
+ The two branches below are not equivalent — pick the one that matches reality and follow it.
37
+
38
+ ### Branch A — `.primitive/config.json` exists (project mode)
39
+
40
+ The active environment is resolved in this order:
41
+ 1. `--env <name>` flag on the command
42
+ 2. `PRIMITIVE_ENV` environment variable
43
+ 3. `defaultEnvironment` in `.primitive/config.json`
44
+ 4. The sole environment, if exactly one is defined
45
+
46
+ Confirm you're targeting the correct environment:
47
+
48
+ 1. **Read the CLI header.** Every command prints `Env | App | Server` at the top of its output —
49
+ verify these match the project's intended target.
50
+ 2. **Inspect the project config:**
51
+
52
+ ```bash
53
+ primitive env list # All environments (default marked with *)
54
+ primitive env show # Details for the currently-resolved env
55
+ primitive whoami # Authenticated user + resolved server/app
56
+ ```
57
+
58
+ **To switch environments** for a one-off command, pass `--env <name>`. To change the project
59
+ default, run `primitive env use <name>`. To switch the *app* an env points at, edit the env's
60
+ `appId` in `.primitive/config.json` (or re-run `primitive env add`). `primitive use <app>` is a
61
+ no-op when the active env already pins an `appId`.
62
+
63
+ ### Branch B — no `.primitive/config.json` (project mode NOT set up)
64
+
65
+ In this branch the CLI silently falls back to global state in `~/.primitive/credentials.json`
66
+ (legacy mode). Commands will run against whatever app/server happens to be globally active —
67
+ which the agent didn't set and the user may have forgotten about. **This is a footgun.** Do not
68
+ proceed silently.
69
+
70
+ **Surface the gap to the user before running mutating commands.** Say something like:
71
+
72
+ > "This project doesn't have a `.primitive/config.json`, so the CLI will use your global state
73
+ > (`<server>` / `<app from `whoami`>`). I'd recommend setting up project-scoped config with
74
+ > `primitive env add <name> --api-url <url> [--app-id <id>]` so this project pins its own
75
+ > environment. Want me to set that up, or proceed against global state for now?"
76
+
77
+ `primitive env add` is additive — it only writes an entry to `.primitive/config.json` (creating
78
+ the file if needed). It does not touch source code, create apps on the server, or install
79
+ dependencies, so it's safe to run in any existing project.
80
+
81
+ Do not rely on `.env` files like `PRIMITIVE_API_URL` to control CLI targeting — those are not
82
+ read by the CLI in project mode, and the project config is the source of truth.
83
+
84
+ **Why this matters:** If the CLI is pointed at the wrong environment (e.g., prod instead of dev),
85
+ commands like `primitive sync push` will modify the wrong server. Silent fallback to global state
86
+ makes this exact mistake easy to commit. Always verify — and surface — before running mutating
87
+ operations.
88
+
89
+ ## Step 1: Discover Available Guides
90
+
91
+ Before writing or reviewing any Primitive code, run:
92
+
93
+ ```bash
94
+ primitive guides list
95
+ ```
96
+
97
+ This returns the full list of available guide topics with descriptions, keywords, and use cases.
98
+ Use this output to determine which guides are relevant to the current task.
99
+
100
+ ## Step 2: Fetch the Relevant Guides
101
+
102
+ For each relevant topic identified in Step 1, fetch the full guide:
103
+
104
+ ```bash
105
+ primitive guides get <topic>
106
+ ```
107
+
108
+ **Always fetch guide(s) BEFORE writing code.** If multiple features are involved, fetch multiple
109
+ guides. The guides contain:
110
+ - Complete API documentation with method signatures
111
+ - Working code examples (TypeScript/JavaScript)
112
+ - Common patterns and anti-patterns
113
+ - Configuration examples (TOML files for `primitive sync`)
114
+ - Decision frameworks for architecture choices
115
+
116
+ **Do not guess or assume API patterns.** If you're unsure about a method signature, parameter,
117
+ or pattern, fetch the guide. The guides are comprehensive and authoritative.
118
+
119
+ ## Step 3: Write Code Following Guide Patterns
120
+
121
+ When writing Primitive code:
122
+
123
+ 1. **Follow the patterns from the fetched guides exactly** — method names, argument order, lifecycle patterns
124
+ 2. **Use `primitive sync`** for all backend configuration (workflows, prompts, integrations, databases)
125
+ 3. **Configuration lives in TOML files** in version control, pushed via `primitive sync push`
126
+ 4. **Run `pnpm codegen`** after creating or modifying js-bao models
127
+
128
+ ## Step 4: Post-Code Review (Automatic)
129
+
130
+ After writing or modifying Primitive-related code, **automatically perform this review**:
131
+
132
+ ### 4a. Identify What Was Written
133
+ Determine which Primitive features the new/modified code touches by scanning for:
134
+ - Import statements from `js-bao`, `js-bao-wss-client`, or `primitive-app`
135
+ - Primitive API calls (documents.open, databases.connect, workflows, etc.)
136
+ - Model definitions, schemas, queries
137
+ - Configuration files (TOML for sync)
138
+
139
+ ### 4b. Fetch and Cross-Reference
140
+ Run `primitive guides list` to identify which guides cover the features used, then fetch each one:
141
+ ```bash
142
+ primitive guides get <topic>
143
+ ```
144
+
145
+ Compare the written code against the guide content:
146
+ - **API usage patterns** — Are methods called correctly with proper arguments?
147
+ - **Lifecycle management** — Are documents opened before queries? Is auth checked first?
148
+ - **Access control** — Are CEL expressions or permissions configured properly?
149
+ - **Anti-patterns** — Does the code do anything the guide explicitly warns against?
150
+ - **Missing steps** — Does the code need `pnpm codegen`, `primitive sync push`, or other follow-up?
151
+
152
+ ### 4c. Report and Fix
153
+ If issues are found:
154
+ 1. **Explain the issue** — cite the specific guide section that applies
155
+ 2. **Show the fix** — provide corrected code
156
+ 3. **Apply the fix** — edit the file directly (don't just suggest, actually fix it)
157
+ 4. **Note any CLI commands needed** — e.g., `pnpm codegen` or `primitive sync push`
158
+
159
+ If no issues are found, briefly confirm the code follows best practices.
160
+
161
+ ## CLI Quick Reference
162
+
163
+ Remind users of these essential commands when relevant:
164
+
165
+ ```bash
166
+ # Verify current configuration (DO THIS FIRST)
167
+ primitive env list # List environments in .primitive/config.json (default marked *)
168
+ primitive env show # Details for the currently-resolved env (api URL, app ID)
169
+ primitive whoami # Authenticated user + resolved server/app
170
+
171
+ # Switching environments
172
+ primitive env use <name> # Change the project's default environment
173
+ primitive --env <name> <command> # One-off override for a single command
174
+ PRIMITIVE_ENV=<name> <command> # Override via env var (useful in scripts/CI)
175
+
176
+ # Setup — existing project (most common: adopting Primitive in an existing repo)
177
+ npm install -g primitive-admin # Install CLI
178
+ primitive env add dev --api-url <url> --app-id <id> # Add env to .primitive/config.json
179
+ primitive env add prod --api-url <url> --app-id <id> # (creates the file if missing)
180
+ primitive login # Authenticate (tokens stored per-env)
181
+
182
+ # Setup — brand-new project (greenfield only)
183
+ primitive init my-new-app # Scaffolds template, creates a new app
184
+ # on the server, runs pnpm install.
185
+ # Do NOT run inside an existing repo.
186
+
187
+ # Guides (the most important commands for development)
188
+ primitive guides list # See all available guides with topics and descriptions
189
+ primitive guides get <topic> # Read detailed guide for a specific topic
190
+
191
+ # Configuration as Code
192
+ primitive sync init --dir ./config # Initialize config directory
193
+ primitive sync pull --dir ./config # Pull config from server
194
+ primitive sync push --dir ./config # Push config to server
195
+ primitive sync diff --dir ./config # Preview changes before push
196
+
197
+ # Common operations
198
+ primitive apps list # List apps on the active env's server
199
+ primitive apps create "Name" # Create an app (does NOT auto-bind to an env;
200
+ # edit .primitive/config.json or use `env add` to bind)
201
+ ```
202
+
203
+ ## When the User is Starting a New Feature
204
+
205
+ If the user describes a new feature they want to build:
206
+
207
+ 1. **Verify CLI configuration** per Step 0 — confirm the active environment in
208
+ `.primitive/config.json` (and its bound `apiUrl` / `appId`) match the project's intended target
209
+ before running any commands
210
+ 2. **Run `primitive guides list`** to discover available topics
211
+ 3. **Identify which guides are relevant** to their feature from the list output
212
+ 4. **Fetch those guides** with `primitive guides get <topic>`
213
+ 5. **Recommend a data modeling approach** based on the guide content. If requirements are unclear or ambiguous, **ask the user clarifying questions before proceeding** — it's much easier to get the data model right upfront than to migrate later
214
+ 6. **Outline the implementation steps** referencing specific patterns from the guides
215
+ 7. **Write the code** following the patterns exactly
216
+ 8. **Review automatically** per Step 4 above
217
+
218
+ ## When the User Asks "How Do I...?"
219
+
220
+ For any question about Primitive platform capabilities:
221
+
222
+ 1. **Run `primitive guides list`** to find the relevant topic
223
+ 2. **Fetch the guide**: `primitive guides get <topic>`
224
+ 3. **Answer from the guide content** — don't guess or make up APIs
225
+ 4. **Include working code examples** from the guide
226
+ 5. **Point the user to the guide** for further reading: "You can see more examples by running `primitive guides get <topic>`"