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.
- package/README.md +168 -21
- package/assets/skill/skills/primitive-platform/SKILL.md +226 -0
- package/dist/bin/primitive.js +198 -15
- package/dist/bin/primitive.js.map +1 -1
- package/dist/src/commands/admins.js +107 -0
- package/dist/src/commands/admins.js.map +1 -1
- package/dist/src/commands/analytics.js +464 -55
- package/dist/src/commands/analytics.js.map +1 -1
- package/dist/src/commands/apps.js +27 -13
- package/dist/src/commands/apps.js.map +1 -1
- package/dist/src/commands/auth.js +165 -5
- package/dist/src/commands/auth.js.map +1 -1
- package/dist/src/commands/blob-buckets.js +354 -0
- package/dist/src/commands/blob-buckets.js.map +1 -0
- package/dist/src/commands/catalog.js +17 -17
- package/dist/src/commands/catalog.js.map +1 -1
- package/dist/src/commands/collection-type-configs.js +178 -0
- package/dist/src/commands/collection-type-configs.js.map +1 -0
- package/dist/src/commands/collections.js +526 -0
- package/dist/src/commands/collections.js.map +1 -0
- package/dist/src/commands/comparisons.js +6 -6
- package/dist/src/commands/comparisons.js.map +1 -1
- package/dist/src/commands/cron-triggers.js +364 -0
- package/dist/src/commands/cron-triggers.js.map +1 -0
- package/dist/src/commands/database-types.js +462 -0
- package/dist/src/commands/database-types.js.map +1 -0
- package/dist/src/commands/databases.js +1067 -58
- package/dist/src/commands/databases.js.map +1 -1
- package/dist/src/commands/documents.js +510 -2
- package/dist/src/commands/documents.js.map +1 -1
- package/dist/src/commands/email-templates.js +281 -0
- package/dist/src/commands/email-templates.js.map +1 -0
- package/dist/src/commands/env.js +260 -0
- package/dist/src/commands/env.js.map +1 -0
- package/dist/src/commands/group-type-configs.js +189 -0
- package/dist/src/commands/group-type-configs.js.map +1 -0
- package/dist/src/commands/groups.js +28 -25
- package/dist/src/commands/groups.js.map +1 -1
- package/dist/src/commands/init.js +719 -188
- package/dist/src/commands/init.js.map +1 -1
- package/dist/src/commands/integrations.js +504 -33
- package/dist/src/commands/integrations.js.map +1 -1
- package/dist/src/commands/prompts.js +17 -16
- package/dist/src/commands/prompts.js.map +1 -1
- package/dist/src/commands/rule-sets.js +366 -0
- package/dist/src/commands/rule-sets.js.map +1 -0
- package/dist/src/commands/secrets.js +108 -0
- package/dist/src/commands/secrets.js.map +1 -0
- package/dist/src/commands/skill.js +29 -0
- package/dist/src/commands/skill.js.map +1 -0
- package/dist/src/commands/sync.js +2363 -182
- package/dist/src/commands/sync.js.map +1 -1
- package/dist/src/commands/tokens.js +9 -9
- package/dist/src/commands/tokens.js.map +1 -1
- package/dist/src/commands/users.js +426 -4
- package/dist/src/commands/users.js.map +1 -1
- package/dist/src/commands/webhooks.js +386 -0
- package/dist/src/commands/webhooks.js.map +1 -0
- package/dist/src/commands/workflows.js +614 -64
- package/dist/src/commands/workflows.js.map +1 -1
- package/dist/src/lib/api-client.js +942 -83
- package/dist/src/lib/api-client.js.map +1 -1
- package/dist/src/lib/config.js +51 -53
- package/dist/src/lib/config.js.map +1 -1
- package/dist/src/lib/constants.js +3 -0
- package/dist/src/lib/constants.js.map +1 -0
- package/dist/src/lib/credentials-store.js +307 -0
- package/dist/src/lib/credentials-store.js.map +1 -0
- package/dist/src/lib/env-resolver.js +121 -0
- package/dist/src/lib/env-resolver.js.map +1 -0
- package/dist/src/lib/init-config.js +87 -0
- package/dist/src/lib/init-config.js.map +1 -0
- package/dist/src/lib/migration-nag.js +163 -0
- package/dist/src/lib/migration-nag.js.map +1 -0
- package/dist/src/lib/output.js +58 -6
- package/dist/src/lib/output.js.map +1 -1
- package/dist/src/lib/paginate.js +42 -0
- package/dist/src/lib/paginate.js.map +1 -0
- package/dist/src/lib/project-config.js +209 -0
- package/dist/src/lib/project-config.js.map +1 -0
- package/dist/src/lib/refresh-admin-credentials.js +103 -0
- package/dist/src/lib/refresh-admin-credentials.js.map +1 -0
- package/dist/src/lib/skill-installer.js +135 -0
- package/dist/src/lib/skill-installer.js.map +1 -0
- package/dist/src/lib/sync-paths.js +102 -0
- package/dist/src/lib/sync-paths.js.map +1 -0
- package/dist/src/lib/template.js +279 -18
- package/dist/src/lib/template.js.map +1 -1
- package/dist/src/lib/toml-database-config.js +384 -0
- package/dist/src/lib/toml-database-config.js.map +1 -0
- package/dist/src/lib/toml-params-validator.js +183 -0
- package/dist/src/lib/toml-params-validator.js.map +1 -0
- package/dist/src/lib/version-check.js +172 -0
- package/dist/src/lib/version-check.js.map +1 -0
- package/dist/src/lib/workflow-fragments.js +121 -0
- package/dist/src/lib/workflow-fragments.js.map +1 -0
- package/dist/src/lib/workflow-toml-validator.js +328 -0
- package/dist/src/lib/workflow-toml-validator.js.map +1 -0
- 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
|
|
158
|
-
primitive users invitations
|
|
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
|
|
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
|
-
|
|
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
|
|
289
|
-
primitive databases
|
|
290
|
-
primitive databases
|
|
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
|
-
|
|
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
|
-
|
|
326
|
-
primitive analytics
|
|
327
|
-
primitive analytics
|
|
328
|
-
primitive analytics
|
|
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
|
-
**
|
|
332
|
-
- `--window-days <n>` - Time window (default
|
|
333
|
-
- `--limit <n>` - Result limit
|
|
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
|
|
549
|
-
commands.test.ts
|
|
550
|
-
tokens.test.ts
|
|
551
|
-
databases.test.ts
|
|
552
|
-
|
|
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>`"
|