@odla-ai/cli 0.3.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.
@@ -0,0 +1,58 @@
1
+ # Build a new odla app (greenfield)
2
+
3
+ Exact commands, verified against `@odla-ai/cli`. ⏸ marks a human step.
4
+
5
+ ## 1. Scaffold
6
+
7
+ ```
8
+ npx @odla-ai/cli init --app-id my-app --name "My App"
9
+ ```
10
+
11
+ Writes `odla.config.mjs`, `src/odla/schema.mjs`, `src/odla/rules.mjs`, and adds
12
+ `.odla/*` + `.dev.vars` to `.gitignore`. Edit `schema.mjs` to declare your
13
+ namespaces (e.g. `notes`). Leave `rules.mjs` as-is for now — provision generates
14
+ deny-all rules from the schema. To turn on auth/observability, add `"o11y"` to
15
+ `services` and an `auth.clerk` block in `odla.config.mjs` (init leaves it
16
+ commented).
17
+
18
+ ## 2. Provision ⏸ device-code approval
19
+
20
+ ```
21
+ npx odla-ai provision --write-dev-vars
22
+ ```
23
+
24
+ Prints a short device code and a link. ⏸ The human opens https://odla.ai, signs
25
+ 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.
36
+
37
+ ## 4. Run locally
38
+
39
+ ```
40
+ npx wrangler dev
41
+ ```
42
+
43
+ `wrangler dev` auto-loads `.dev.vars`. Exercise the app. A default-deny `403`
44
+ means the namespace has no rule yet — add one in `src/odla/rules.mjs`
45
+ (deliberately; e.g. `{ notes: { view: "auth.signedIn", create: "auth.signedIn" } }`),
46
+ re-provision to push it, and retry.
47
+
48
+ ## 5. Ship ⏸ human checkpoint
49
+
50
+ Add `"prod"` to `envs`, provision again (prod tenant = the bare `appId`), then:
51
+
52
+ ```
53
+ npx odla-ai secrets push --env prod --yes # pushes ODLA_API_KEY (+ ODLA_O11Y_TOKEN if o11y)
54
+ npx wrangler deploy
55
+ ```
56
+
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).
@@ -0,0 +1,64 @@
1
+ # odla SDK cheat-sheet
2
+
3
+ Install only what the app needs. Every package ships an `llms.txt` in
4
+ `node_modules/@odla-ai/<pkg>/` with the full, current API — read it. Minimal
5
+ real usage below.
6
+
7
+ ## @odla-ai/db — realtime graph database
8
+
9
+ Data is **namespaces** of rows, declared in `src/odla/schema.mjs`, gated by
10
+ default-deny `src/odla/rules.mjs`. Isomorphic (browser + Worker).
11
+
12
+ ```ts
13
+ // browser client — token from your IdP (Clerk):
14
+ const db = init({ appId, endpoint, getToken });
15
+ const { data } = useQuery({ notes: { $: { order: { createdAt: "asc" } } } });
16
+ transact(db.tx.notes[crypto.randomUUID()].update({ text, createdAt: Date.now() }));
17
+ ```
18
+
19
+ Worker/admin side: `init({ appId: tenantId, adminToken: env.ODLA_API_KEY, endpoint })`
20
+ — the admin key bypasses rules, so a worker-mediated backend needs none.
21
+
22
+ ## @odla-ai/auth-clerk — sign-in (Clerk; runs on Preact or React)
23
+
24
+ ```tsx
25
+ <ClerkGate publishableKey={pk} appearance={clerkAppearanceFromTokens()}>
26
+ <SignedOut><SignIn routing="hash" /></SignedOut>
27
+ <SignedIn>{/* useClerkAuth().getToken → db init; <UserButton/> signs out */}</SignedIn>
28
+ </ClerkGate>
29
+ ```
30
+
31
+ The publishable key is public; `provision` stores it (`setAuth`). Rules evaluate
32
+ the signed-in user's JWT as `auth` — e.g. `auth.signedIn`, `auth.email`.
33
+
34
+ ## @odla-ai/ai — inference (Claude / GPT / Gemini)
35
+
36
+ ```ts
37
+ const { ai } = await initFromPlatform({ platform, appId, env, db });
38
+ await ai.chat({ messages }); // provider/model + key resolved from the platform vault
39
+ ```
40
+
41
+ No API key in your code or env — it lives in the tenant vault; `provision`
42
+ stores it when the configured `ai.keyEnv` is set at provision time.
43
+
44
+ ## @odla-ai/o11y — observability (Cloudflare Workers)
45
+
46
+ ```ts
47
+ export default withObservability(handler); // traces fetch/cron/bindings
48
+ count("http.requests", 1, { "http.route": path }); // metrics
49
+ recordError(err, { route, code }); // structured errors
50
+ ```
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).
55
+
56
+ ## Others
57
+
58
+ - **@odla-ai/ui** — design system: CSS tokens, five themes, component styles,
59
+ chart helpers.
60
+ - **@odla-ai/kg** — ontology-driven knowledge graph: source connectors, LLM
61
+ extraction, provenance-preserving writes.
62
+ - **@odla-ai/blog** — static-first blogging; files in, site out.
63
+ - **@odla-ai/apps** — control-plane SDK (create apps, toggle services); the CLI
64
+ and registry usually handle this for you.