@odla-ai/cli 0.4.0 → 0.6.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/package.json CHANGED
@@ -1,11 +1,17 @@
1
1
  {
2
2
  "name": "@odla-ai/cli",
3
- "version": "0.4.0",
4
- "description": "Project-neutral CLI for provisioning odla apps, database schemas, AI settings, and local runtime files.",
3
+ "version": "0.6.0",
4
+ "description": "Agent-operable CLI for odla provisioning, scoped System AI administration, hosted security runs, Worker secrets, and smoke checks.",
5
5
  "license": "MIT",
6
+ "homepage": "https://odla.ai/docs/packages/cli",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/cory/odla-ai.git",
10
+ "directory": "packages/cli"
11
+ },
6
12
  "type": "module",
7
13
  "bin": {
8
- "odla-ai": "./dist/bin.js"
14
+ "odla-ai": "dist/bin.js"
9
15
  },
10
16
  "main": "./dist/index.cjs",
11
17
  "module": "./dist/index.js",
@@ -29,7 +35,8 @@
29
35
  "node": ">=20"
30
36
  },
31
37
  "publishConfig": {
32
- "access": "public"
38
+ "access": "public",
39
+ "provenance": false
33
40
  },
34
41
  "keywords": [
35
42
  "odla",
@@ -38,6 +45,7 @@
38
45
  "provisioning",
39
46
  "cloudflare",
40
47
  "database",
48
+ "observability",
41
49
  "knowledge-graph",
42
50
  "ai"
43
51
  ],
@@ -51,9 +59,10 @@
51
59
  "prepublishOnly": "npm run build && npm run gen:llms"
52
60
  },
53
61
  "dependencies": {
54
- "@odla-ai/ai": "^0.2.1",
62
+ "@odla-ai/ai": "^0.3.1",
55
63
  "@odla-ai/apps": "^0.7.1",
56
- "@odla-ai/db": "^0.5.0"
64
+ "@odla-ai/db": "^0.6.1",
65
+ "@odla-ai/security": "^0.2.0"
57
66
  },
58
67
  "devDependencies": {
59
68
  "@types/node": "^22.10.0",
@@ -6,6 +6,9 @@ description: >
6
6
  wants to create/scaffold an odla app, add odla-db/ai/auth/o11y to a repo, or
7
7
  "get started with odla". For moving an existing static or GitHub Pages site to
8
8
  odla, use the odla-migrate skill instead.
9
+ runbookOrder:
10
+ - references/build.md
11
+ - references/sdks.md
9
12
  ---
10
13
 
11
14
  # odla
@@ -34,32 +37,60 @@ State which path you're taking and what you'll build in one line; get a nod.
34
37
  `.odla/credentials.local.json`, or `.odla/dev-token.json` — use `ls -l` to
35
38
  confirm they exist (and are `0600`). The only value a human ever pastes is a
36
39
  Clerk **publishable** key (`pk_…`) — public by design.
37
- 2. **Dev before prod.** Keep `envs: ["dev"]` (or `["dev","prod"]`) and verify the
38
- tenant (`<appId>--dev` in dev) before any write or deploy. The first prod
39
- deploy and `secrets push --env prod --yes` are human checkpoints.
40
+ 2. **Dev before prod.** Keep `envs: ["dev"]` and verify the tenant
41
+ (`<appId>--dev`) before any write or deploy. Add `prod` only at the explicit
42
+ production checkpoint. The first prod
43
+ `provision --dry-run` review, `provision --yes --push-secrets`, and deploy
44
+ are human checkpoints.
40
45
  3. **Rules are default-deny.** A namespace with no rule is invisible; a write
41
46
  with no rule is rejected. Never widen a rule just to clear a 403 — edit
42
47
  `src/odla/rules.mjs` deliberately, and flag rule changes to the human.
43
48
  4. Never `git add -A` without reading `git status` first. Never run
44
- `provision --rotate-keys` unless the human explicitly asks.
49
+ `provision --rotate-keys` or `provision --rotate-o11y-token` unless the human
50
+ explicitly asks.
45
51
 
46
52
  ## The flow
47
53
 
48
54
  You reached this skill because the human ran `npx @odla-ai/cli setup`. Then:
49
55
 
56
+ First run `npx @odla-ai/cli capabilities --json`; use that contract instead of
57
+ guessing which platform/credential steps need manual work. Then:
58
+
50
59
  1. **init** — `npx @odla-ai/cli init --app-id <id> --name "<Name>"` scaffolds
51
60
  `odla.config.mjs`, `src/odla/schema.mjs`, `src/odla/rules.mjs` (deny-all).
52
- 2. **provision** `npx odla-ai provision --write-dev-vars`. A device code
53
- prints; the human approves it at https://odla.ai. It creates the app, enables
54
- services, mints keys (db key + o11y ingest token if enabled), pushes schema +
55
- rules, and writes `.dev.vars`.
56
- 3. **build** — install the SDKs and write the app (`references/sdks.md`).
61
+ 2. **build the Worker shell** — install the SDKs, write the app, and create its
62
+ Wrangler config (`references/sdks.md`). With o11y, add `nodejs_compat` and
63
+ `withObservability`. The CLI will refuse secret delivery until the Wrangler
64
+ target exists.
65
+ 3. **provision**
66
+ `npx @odla-ai/cli provision --write-dev-vars --push-secrets`. A device code
67
+ prints; the human approves it at https://odla.ai/studio. It creates the app,
68
+ enables services, issues or reuses configured credentials (db key + o11y
69
+ ingest token when enabled), pushes schema + rules, writes `.dev.vars`, and
70
+ transfers Worker secrets through Wrangler stdin.
57
71
  4. **run** — `npx wrangler dev` (auto-loads `.dev.vars`); verify locally.
58
- 5. **ship** `npx odla-ai secrets push --env prod --yes`, then
72
+ 5. **security** — run the passive `@odla-ai/security` odla profile; inspect
73
+ every lead and keep critical candidate gating enabled. If the human approves
74
+ redacted source disclosure, follow with
75
+ `npx @odla-ai/cli security run . --env dev --ack-redacted-source` for
76
+ app-attributed discovery + independent validation. Never request provider
77
+ keys; the platform selects the routes and returns bounded role grants.
78
+ 6. **ship** ⏸ — after adding `prod`, run `npx @odla-ai/cli provision --dry-run`,
79
+ show the human, then `npx @odla-ai/cli provision --yes --push-secrets` and
59
80
  `npx wrangler deploy`.
60
81
 
61
- `npx odla-ai doctor` is an offline config check anytime; `smoke --env dev`
62
- verifies a live deployment.
82
+ `npx @odla-ai/cli doctor` is an offline config check anytime;
83
+ `npx @odla-ai/cli smoke --env dev` verifies a live deployment.
84
+
85
+ The CLI owns deterministic platform work from `odla.config.mjs`: service
86
+ enablement, credential issuance/storage, `.dev.vars`, and Wrangler secret
87
+ transfer. You own source changes — install `@odla-ai/o11y`, add
88
+ `withObservability`, create the Wrangler config, and choose application-specific
89
+ signals. The human owns device approval, production consent, and explicit
90
+ destructive rotation. If an
91
+ o11y token must be replaced, use
92
+ `provision --rotate-o11y-token --push-secrets` so the cached and deployed values
93
+ move together; Studio rotation is manual recovery only.
63
94
 
64
95
  ## Checkpoint protocol
65
96
 
@@ -15,24 +15,40 @@ deny-all rules from the schema. To turn on auth/observability, add `"o11y"` to
15
15
  `services` and an `auth.clerk` block in `odla.config.mjs` (init leaves it
16
16
  commented).
17
17
 
18
- ## 2. Provision ⏸ device-code approval
18
+ ## 2. Build the Worker shell
19
+
20
+ `npm i` only the SDKs you need and use the local `references/sdks.md` as the
21
+ integration map. Create the Worker entrypoint and `wrangler.jsonc` before any
22
+ deployed-secret transfer. With o11y, install `@odla-ai/o11y`, add
23
+ `"nodejs_compat"` to `compatibility_flags`, and wrap the entrypoint with
24
+ `withObservability`.
25
+
26
+ Each installed package's `node_modules/@odla-ai/<pkg>/llms.txt` is the full API
27
+ contract. The npm artifacts contain everything required for this flow; private
28
+ service source or online documentation is not setup context.
29
+
30
+ ## 3. Provision ⏸ device-code approval
19
31
 
20
32
  ```
21
- npx odla-ai provision --write-dev-vars
33
+ npx @odla-ai/cli provision --write-dev-vars --push-secrets
22
34
  ```
23
35
 
24
- Prints a short device code and a link. ⏸ The human opens https://odla.ai, signs
36
+ Prints a short device code and a link. ⏸ The human opens https://odla.ai/studio, signs
25
37
  in, and approves the code — no secret passes through the chat. Provision then:
26
- creates the app, enables its services, mints the db key (and the o11y ingest
27
- token when o11y is enabled), pushes schema + rules, and writes `.dev.vars`
28
- (`0600`, gitignored). Verify with `npx odla-ai doctor` it prints the app,
29
- envs, services, and flags anything unset.
30
-
31
- ## 3. Build
32
-
33
- `npm i` only the SDKs you need (see `references/sdks.md`) and write the app. Read
34
- each package's `node_modules/@odla-ai/<pkg>/llms.txt` for its full API. The
35
- `examples/saas` app in the odla-ai repo is a complete realtime app to mirror.
38
+ creates the app, enables its services, issues or reuses the db key (and the
39
+ o11y ingest token when o11y is enabled), pushes schema + rules, writes
40
+ `.dev.vars`, and transfers configured Worker secrets through Wrangler stdin.
41
+ Local credential files are `0600` and gitignored. Verify with
42
+ `npx @odla-ai/cli doctor` — it prints the app, envs, services, and flags
43
+ anything unset. `--push-secrets` preflights the Wrangler config and login before
44
+ issuing or rotating a shown-once credential.
45
+
46
+ The CLI stops at the source boundary: it verifies but does not invent your
47
+ application semantics. Do not use Studio to mint a routine o11y token. Manual
48
+ Studio rotation is recovery-only;
49
+ normal replacement is
50
+ `npx @odla-ai/cli provision --rotate-o11y-token --push-secrets` after explicit
51
+ human approval.
36
52
 
37
53
  ## 4. Run locally
38
54
 
@@ -45,14 +61,46 @@ means the namespace has no rule yet — add one in `src/odla/rules.mjs`
45
61
  (deliberately; e.g. `{ notes: { view: "auth.signedIn", create: "auth.signedIn" } }`),
46
62
  re-provision to push it, and retry.
47
63
 
48
- ## 5. Ship ⏸ human checkpoint
64
+ ## 5. Security preflight
65
+
66
+ Install the passive harness and scan before any production secret or deploy:
67
+
68
+ Before installing the exact release, first verify
69
+ `npm view @odla-ai/security@0.2.0 version`. An exact-version `E404` means the
70
+ release is unavailable and blocks this preflight; it is not a clean scan and
71
+ does not prove the package name is absent.
72
+
73
+ ```
74
+ npm i -D --save-exact @odla-ai/security@0.2.0
75
+ npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical
76
+ ```
77
+
78
+ Read `.odla/security/pre-ship/REPORT.md`. The CLI makes no model calls and does
79
+ not execute target code. A `candidate` is a review lead, not a confirmed
80
+ vulnerability; do not suppress one merely to clear the gate. Baseline entries
81
+ need a fingerprint, concrete reason, owner, and expiry.
82
+
83
+ Optional hosted follow-up (human must explicitly approve redacted tracked-source
84
+ disclosure under the configured providers' retention/residency terms):
85
+
86
+ ```
87
+ npx @odla-ai/cli security run . --env dev --ack-redacted-source
88
+ ```
89
+
90
+ Do not ask for Anthropic/OpenAI/Google keys. The CLI obtains app-owner auth;
91
+ the platform fixes separate discovery/validation grants to the admin-configured
92
+ routes, attributes usage to this app/env/run, and retains no source or prompts
93
+ in its accounting ledger. If a rolling early-access ceiling returns `429`,
94
+ surface the CLI's safe retry hint and do not loop or manufacture a provider key.
95
+
96
+ ## 6. Ship ⏸ human checkpoint
49
97
 
50
98
  Add `"prod"` to `envs`, provision again (prod tenant = the bare `appId`), then:
51
99
 
52
100
  ```
53
- npx odla-ai secrets push --env prod --yes # pushes ODLA_API_KEY (+ ODLA_O11Y_TOKEN if o11y)
101
+ npx @odla-ai/cli provision --yes --push-secrets # prod mutation + configured Worker secrets
54
102
  npx wrangler deploy
55
103
  ```
56
104
 
57
- Verify with `npx odla-ai smoke --env prod`. Point env vars at the service custom
58
- domains, never `*.workers.dev` (Workers can't fetch same-account workers.dev).
105
+ Verify with `npx @odla-ai/cli smoke --env prod`. Point env vars at the service
106
+ custom domains, never `*.workers.dev` (Workers can't fetch same-account workers.dev).
@@ -49,9 +49,42 @@ count("http.requests", 1, { "http.route": path }); // metrics
49
49
  recordError(err, { route, code }); // structured errors
50
50
  ```
51
51
 
52
- Set `ODLA_O11Y_ENDPOINT` + `ODLA_O11Y_SERVICE` (vars) and `ODLA_O11Y_TOKEN`
53
- (secret) `provision` mints the token when `o11y` is in `services`. First-party
54
- hosting binds `ODLA_O11Y_COLLECTOR` instead (no endpoint/token).
52
+ When `o11y` is in `services`, run
53
+ `npx @odla-ai/cli provision --write-dev-vars --push-secrets`. The CLI enables
54
+ the service, issues or reuses its token, persists it locally, writes
55
+ `.dev.vars`, and transfers `ODLA_O11Y_TOKEN` to the Worker over Wrangler stdin.
56
+ With a token present, the SDK defaults `ODLA_O11Y_ENDPOINT` to
57
+ `https://o11y.odla.ai` and the service label to
58
+ `ODLA_O11Y_SERVICE ?? ODLA_APP_ID`; both remain overrides. First-party hosting
59
+ binds `ODLA_O11Y_COLLECTOR` instead (no public endpoint/token).
60
+
61
+ Source instrumentation remains your job: install the package, wrap with
62
+ `withObservability`, and select useful signals. Never rotate through Studio as
63
+ routine setup. On explicit human request, use
64
+ `provision --rotate-o11y-token --push-secrets` so local and deployed values stay
65
+ in sync.
66
+
67
+ ## @odla-ai/security — pre-ship vulnerability harness
68
+
69
+ Run the passive CLI in local/CI development; do not import it into the running
70
+ Worker:
71
+
72
+ Before installing the exact release, require
73
+ `npm view @odla-ai/security@0.2.0 version` to succeed before installing it. An
74
+ exact-version `E404` means the release is unavailable, not that the preflight
75
+ passed, and does not prove the package name is absent.
76
+
77
+ ```
78
+ npm i -D --save-exact @odla-ai/security@0.2.0
79
+ npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical
80
+ ```
81
+
82
+ Deterministic rules emit leads. After explicit redacted-source approval, run
83
+ `npx @odla-ai/cli security run . --env dev --ack-redacted-source` for hosted,
84
+ app-attributed discovery and independent validation. It obtains owner auth and
85
+ never asks for provider keys. The lower-level library flow remains available
86
+ for custom orchestrators; active reproduction still requires an explicitly
87
+ injected isolated executor and never falls back to the host shell.
55
88
 
56
89
  ## Others
57
90
 
@@ -5,6 +5,16 @@ description: >
5
5
  phases, then add a database, Clerk login, and AI. Use when the user wants to
6
6
  move a static or GitHub Pages site to Cloudflare/odla, or to add a backend,
7
7
  database, login/auth, or AI features to a static site via odla.
8
+ runbookOrder:
9
+ - references/phase-0-preflight.md
10
+ - references/phase-1-static.md
11
+ - references/phase-2-db.md
12
+ - references/phase-3-auth.md
13
+ - references/phase-3b-user-sync.md
14
+ - references/phase-4-ai.md
15
+ - references/phase-5-cutover.md
16
+ - references/troubleshooting.md
17
+ - references/secrets-map.md
8
18
  ---
9
19
 
10
20
  # odla-migrate
@@ -15,8 +25,8 @@ handshake approval, DNS). You do everything else.
15
25
 
16
26
  ## When NOT to use this skill
17
27
 
18
- Greenfield odla apps (no existing site to migrate): follow the "Typical
19
- agent flow" in https://odla.ai/llms.txt instead.
28
+ Greenfield odla apps (no existing site to migrate): read and follow the sibling
29
+ installed skill at `../odla/SKILL.md` instead.
20
30
 
21
31
  ## Non-negotiable rules
22
32
 
@@ -30,7 +40,11 @@ agent flow" in https://odla.ai/llms.txt instead.
30
40
  4. Never `git add -A` without reading `git status` first.
31
41
  5. Never widen a db rule to silence a 403 — default-deny is the design.
32
42
  Any rules change is a human checkpoint.
33
- 6. Never run `provision --rotate-keys` unless the human explicitly asks.
43
+ 6. Never run `provision --rotate-keys` or
44
+ `provision --rotate-o11y-token` unless the human explicitly asks. Pair any
45
+ approved o11y rotation with `--push-secrets` so the Worker is updated in the
46
+ same run. If the final Wrangler transfer fails, use the CLI's printed
47
+ non-rotating `secrets push` retry; never rotate again just to retry delivery.
34
48
 
35
49
  ## Phase state machine
36
50
 
@@ -42,7 +56,14 @@ Phases run strictly in order; each has a verification gate:
42
56
  `MIGRATION.md` at the user's repo root is the durable state: create it in
43
57
  Phase 0, update it at every gate (phase, what changed, what was verified).
44
58
  In a fresh session, read MIGRATION.md first and resume from the recorded
45
- phase. If the CLI offers `odla-ai status`, run it to confirm.
59
+ phase; `npx @odla-ai/cli doctor` confirms the current config state.
60
+
61
+ ## Auth model (one line)
62
+
63
+ Clerk is the **source of truth** for users; odla-db keeps a mirror in the
64
+ app's reserved `$users` namespace (Phase 3 ships login; Phase 3b enables the
65
+ mirror). That per-app `$users` is distinct from odla.ai's own operator
66
+ access list — don't conflate them.
46
67
 
47
68
  ## Checkpoint protocol (every phase boundary)
48
69
 
@@ -52,18 +73,21 @@ phase. If the CLI offers `odla-ai status`, run it to confirm.
52
73
  approve, value to paste, command to run themselves).
53
74
  3. Wait for explicit approval before entering the next phase.
54
75
 
55
- At the very first checkpoint, have the human sign in at https://odla.ai and
76
+ At the very first checkpoint, have the human sign in at https://odla.ai/studio and
56
77
  open Docs → "Moving your site to odla" — it explains their side of the whole
57
78
  journey in plain language. They need an odla account for the migration anyway,
58
79
  so this is a natural first step.
59
80
 
60
81
  ## Verification tools
61
82
 
62
- - `npx odla-ai doctor` — offline config/schema/rules validation; run
83
+ - `npx @odla-ai/cli capabilities --json` — authoritative automation boundary;
84
+ run once when orienting so source edits and human checkpoints are not confused
85
+ with CLI-owned platform/credential work.
86
+ - `npx @odla-ai/cli doctor` — offline config/schema/rules validation; run
63
87
  after any config edit.
64
- - `npx odla-ai provision --dry-run` — the plan, zero network/file I/O;
88
+ - `npx @odla-ai/cli provision --dry-run` — the plan, zero network/file I/O;
65
89
  show it to the human before the first real provision.
66
- - `npx odla-ai smoke --env dev` — live, read-only: public-config, live
90
+ - `npx @odla-ai/cli smoke --env dev` — live, read-only: public-config, live
67
91
  schema diff, a count aggregate. Run after every provision.
68
92
  - `wrangler dev` + curl — exercise routes locally before deploying.
69
93
  - Parity curls — compare the old and new site on representative paths
@@ -77,6 +101,7 @@ Read the current phase's file when you enter it — not before:
77
101
  - references/phase-1-static.md
78
102
  - references/phase-2-db.md
79
103
  - references/phase-3-auth.md
104
+ - references/phase-3b-user-sync.md (optional: mirror Clerk users into $users)
80
105
  - references/phase-4-ai.md
81
106
  - references/phase-5-cutover.md
82
107
 
@@ -84,8 +109,8 @@ On any failure, read references/troubleshooting.md before improvising.
84
109
 
85
110
  ## Context bootstrap
86
111
 
87
- Before Phase 1, fetch https://odla.ai/llms.txt and
88
- https://odla.ai/llms-migrate.txt (the served copy of this procedure's
89
- reference text). After `npm install`, prefer
90
- `node_modules/@odla-ai/*/llms.txt` over training memory for any
91
- @odla-ai package the packages are newer than you think.
112
+ This installed skill and its `references/` directory are the complete migration
113
+ runbook; do not fetch a website or private source repository to reconstruct it.
114
+ Read only the current phase file as directed above. After `npm install`, prefer
115
+ `node_modules/@odla-ai/*/llms.txt` over training memory for package APIs — the
116
+ installed artifact is the version this project actually uses.
@@ -16,8 +16,6 @@ Human obligation: none.
16
16
  `.github/workflows/*` using deploy-pages.
17
17
  - Dynamic wishes: forms posting to third parties, `mailto:` contact,
18
18
  localStorage used as a database, TODOs mentioning login/db.
19
- - If your installed CLI has `npx odla-ai inspect`, run it instead of
20
- hand-checking; it also does the secret scan below.
21
19
  2. Ensure the build outputs to a DEDICATED directory (`dist/`, `_site/`,
22
20
  `build/`). If the site is served from the repo root, restructure so a
23
21
  build step (even a copy script) produces a clean output dir first.
@@ -10,9 +10,7 @@ in this session).
10
10
  ## Steps
11
11
 
12
12
  1. `npm i -D wrangler`
13
- 2. If your installed CLI has `npx odla-ai scaffold worker`, use it.
14
- Otherwise write `wrangler.jsonc` by hand, modeled on
15
- `examples/demo-app/wrangler.jsonc` in the odla-ai monorepo:
13
+ 2. Write `wrangler.jsonc` by hand using this documented shape:
16
14
  - `name`: kebab-case app id; `main`: `src/worker.ts`
17
15
  - `compatibility_date` (today), `compatibility_flags: ["nodejs_compat"]`
18
16
  - `assets: { "directory": "<buildDir>", "binding": "ASSETS",
@@ -45,4 +43,4 @@ Rollback: delete the dev worker in the Cloudflare dashboard. Pages was
45
43
  never touched.
46
44
 
47
45
  Done when: parity recorded and the human approves Phase 2 (their next
48
- obligation: sign in at https://odla.ai and approve a handshake code).
46
+ obligation: sign in at https://odla.ai/studio and approve a handshake code).
@@ -4,15 +4,22 @@ Goal: the app registered on the platform, a dev odla-db tenant with
4
4
  schema + deny-all rules, the db key in the dev worker, and first
5
5
  `/api/*` routes live in dev.
6
6
 
7
- Human obligation: sign in at https://odla.ai and approve the handshake
7
+ Human obligation: sign in at https://odla.ai/studio and approve the handshake
8
8
  code when the provision run prints it (it also opens the approval page
9
9
  in the browser in interactive terminals).
10
10
 
11
11
  ## Steps
12
12
 
13
- 1. `npm i -D @odla-ai/cli` and `npm i @odla-ai/db`
14
- 2. `npx odla-ai init --app-id <id> --name "<Name>" --env dev --services db`
15
- Review `odla.config.mjs`. Keep `envs: ["dev"]` prod is Phase 5.
13
+ 1. Require `npm view @odla-ai/cli@0.6.0 version` to succeed, then run
14
+ `npm i -D --save-exact @odla-ai/cli@0.6.0` and `npm i @odla-ai/db`.
15
+ 2. `npx @odla-ai/cli init --app-id <id> --name "<Name>" --env dev --services db`
16
+ Review `odla.config.mjs`. Keep `envs: ["dev"]` — prod is Phase 5. Set
17
+ `links.dev` to the URL the Phase 1 `wrangler deploy` **actually printed** —
18
+ copy it from that output and `curl` it (200) before pasting. NEVER predict or
19
+ remember a workers.dev URL; the worker name and account subdomain must match
20
+ exactly or Studio links to a dead URL. Provision records it so Studio and
21
+ public-config show where the app runs. (`links.prod` is set the same way at
22
+ Phase 5, from the prod deploy's printed URL.)
16
23
  3. STOP before touching schema: read "Porting relational code" in
17
24
  `node_modules/@odla-ai/db/llms.txt`. The traps are silent: entity ids
18
25
  are not attrs (mirror an id attr), there is no NULL (omit on write,
@@ -23,16 +30,15 @@ in the browser in interactive terminals).
23
30
  generated deny-all `src/odla/rules.mjs`: the worker mediates all
24
31
  access with its app key (which bypasses rules); browsers get nothing
25
32
  directly. Loosening a rule is a human checkpoint.
26
- 5. `npx odla-ai doctor` until clean.
27
- 6. `npx odla-ai provision --dry-run` — show the plan to the human.
28
- 7. `npx odla-ai provision --write-dev-vars` — handshake, app
29
- registration, dev db key, schema + rules push; writes
30
- `.odla/credentials.local.json` (0600) and `.dev.vars`. Both are
31
- gitignored by init confirm with `git status`.
32
- 8. Push the key to the dev worker without echoing it:
33
- `npx odla-ai secrets push --env dev` it pipes the value from the
34
- credentials file straight into wrangler over stdin (details and the
35
- manual fallback: references/secrets-map.md).
33
+ 5. `npx @odla-ai/cli doctor` until clean.
34
+ 6. `npx @odla-ai/cli provision --dry-run` — show the plan to the human.
35
+ 7. `npx @odla-ai/cli provision --write-dev-vars --push-secrets` — handshake,
36
+ app registration, dev db key, schema + rules push; writes
37
+ `.odla/credentials.local.json` (0600) and `.dev.vars`, then pipes configured
38
+ Worker secrets to Wrangler over stdin. Both local files are gitignored by
39
+ init confirm with `git status`. Use
40
+ `npx @odla-ai/cli secrets push --env dev` only to retry the secret-transfer
41
+ portion (details and manual fallback: references/secrets-map.md).
36
42
  9. Add to `wrangler.jsonc` `env.dev.vars`: `ODLA_ENDPOINT`
37
43
  ("https://db.odla.ai"), `ODLA_TENANT` ("<appId>--dev"),
38
44
  `ODLA_PLATFORM` ("https://odla.ai"), `ODLA_APP_ID`, `ODLA_ENV`
@@ -40,15 +46,17 @@ in the browser in interactive terminals).
40
46
  Phase 5. These are vars, not secrets.
41
47
  10. Add `/api/*` routes before the assets fall-through, using
42
48
  `init({ appId: env.ODLA_TENANT, adminToken: env.ODLA_API_KEY,
43
- endpoint: env.ODLA_ENDPOINT })` from `@odla-ai/db`. Reference:
44
- `examples/demo-app/src/routes.ts`.
49
+ endpoint: env.ODLA_ENDPOINT })` from `@odla-ai/db`. Read the installed
50
+ package's `node_modules/@odla-ai/db/llms.txt` for query, transaction, and
51
+ error contracts.
45
52
  11. `wrangler dev` + curl each route; then `npm run deploy:app:dev` and
46
53
  curl the workers.dev URL.
47
54
 
48
55
  ## Verification checklist
49
56
 
50
- - [ ] `npx odla-ai smoke --env dev` passes (public-config, schema, aggregate)
57
+ - [ ] `npx @odla-ai/cli smoke --env dev` passes (public-config, schema, aggregate)
51
58
  - [ ] Routes work locally and on the deployed dev worker
59
+ - [ ] `links.dev` set — public-config carries the URL and Studio shows it
52
60
  - [ ] `git status` shows no credential files staged
53
61
  - [ ] MIGRATION.md updated with tenant id + route list
54
62