@odla-ai/cli 0.8.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -8
- package/REQUIREMENTS.md +14 -0
- package/dist/bin.cjs +806 -56
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-BHAEDEL2.js → chunk-WDKBW4BE.js} +824 -64
- package/dist/chunk-WDKBW4BE.js.map +1 -0
- package/dist/index.cjs +826 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +232 -282
- package/dist/index.d.ts +232 -282
- package/dist/index.js +21 -1
- package/llms.txt +315 -291
- package/package.json +3 -3
- package/skills/odla/SKILL.md +12 -3
- package/skills/odla/references/build.md +19 -0
- package/skills/odla/references/sdks.md +29 -0
- package/skills/odla-migrate/SKILL.md +8 -2
- package/skills/odla-migrate/references/phase-2-db.md +2 -2
- package/skills/odla-migrate/references/phase-2b-calendar.md +42 -0
- package/skills/odla-migrate/references/phase-3b-user-sync.md +15 -8
- package/skills/odla-migrate/references/secrets-map.md +16 -2
- package/dist/chunk-BHAEDEL2.js.map +0 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
Project-neutral provisioning CLI for odla apps. It creates and validates an
|
|
9
9
|
`odla.config.mjs`, then uses that config to register an app, enable services,
|
|
10
10
|
push odla-db schema/rules, configure per-app BYOK AI, configure Clerk auth, record
|
|
11
|
-
deployment links, provision o11y ingest credentials, and transfer local or
|
|
11
|
+
deployment links, connect read-only Google Calendar mirrors, provision o11y ingest credentials, and transfer local or
|
|
12
12
|
deployed Worker secrets without printing them. It also gives platform admins a
|
|
13
13
|
scoped System AI control surface and gives app owners a provider-key-free
|
|
14
14
|
hosted security command.
|
|
@@ -29,8 +29,8 @@ For a project you keep working in, install it as a dev dependency so the
|
|
|
29
29
|
shorter `npx odla-ai` form works and the version is pinned by your lockfile:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
npm view @odla-ai/cli@0.
|
|
33
|
-
npm i -D --save-exact @odla-ai/cli@0.
|
|
32
|
+
npm view @odla-ai/cli@0.10.0 version
|
|
33
|
+
npm i -D --save-exact @odla-ai/cli@0.10.0
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
## Prerequisites
|
|
@@ -53,12 +53,19 @@ npm i -D --save-exact @odla-ai/cli@0.8.0
|
|
|
53
53
|
npx odla-ai setup
|
|
54
54
|
npx odla-ai init --app-id my-app --name "My App"
|
|
55
55
|
npx odla-ai doctor
|
|
56
|
+
npx odla-ai calendar status --env dev
|
|
57
|
+
npx odla-ai calendar calendars --env dev
|
|
58
|
+
npx odla-ai calendar connect --env dev
|
|
59
|
+
npx odla-ai calendar resync --env dev
|
|
60
|
+
npx odla-ai calendar disconnect --env dev --yes
|
|
56
61
|
npx odla-ai capabilities --json
|
|
57
62
|
# install SDKs, write the Worker, and create wrangler.jsonc before secret push
|
|
58
63
|
npx odla-ai provision --dry-run
|
|
59
64
|
npx odla-ai provision --write-dev-vars --push-secrets
|
|
60
65
|
npx odla-ai smoke --env dev
|
|
61
66
|
npx odla-ai secrets push --env dev
|
|
67
|
+
npx odla-ai secrets set clerk_webhook_secret --env dev --stdin
|
|
68
|
+
npx odla-ai secrets set-clerk-key --env dev --from-env CLERK_SECRET_KEY
|
|
62
69
|
npx odla-ai security run . --env dev --ack-redacted-source
|
|
63
70
|
npx odla-ai security github connect --env dev # infers owner/name from git origin
|
|
64
71
|
npx odla-ai security plan --env dev
|
|
@@ -101,14 +108,20 @@ shown-once credential.
|
|
|
101
108
|
non-interactive shell, or `--no-open` to suppress it. Browser launch is
|
|
102
109
|
best-effort; the printed URL and code always remain the fallback.
|
|
103
110
|
2. Creates the platform app if needed.
|
|
104
|
-
3. Enables configured services in every configured environment.
|
|
111
|
+
3. Enables configured services in every configured environment. Calendar
|
|
112
|
+
config is normalized per env and fixed to Google read-only access.
|
|
105
113
|
4. Mints or reuses each env's configured service credentials: an odla-db app
|
|
106
114
|
key for `db` and an ingest token for `o11y`.
|
|
107
115
|
5. Pushes the configured schema and rules.
|
|
108
116
|
6. Configures platform AI and stores provider keys in the tenant vault when the
|
|
109
117
|
configured key env var is set.
|
|
110
|
-
7.
|
|
111
|
-
|
|
118
|
+
7. For calendar, reads owner-visible connection status and, when needed, asks
|
|
119
|
+
the platform for a state-bound Google authorization URL and opens only the
|
|
120
|
+
exact Google OAuth endpoint (or a same-platform interstitial). The human completes consent there;
|
|
121
|
+
provision follows the exact attempt through initial sync. OAuth codes and
|
|
122
|
+
refresh tokens never enter the CLI, repo, chat, or app.
|
|
123
|
+
8. Writes `.odla/credentials.local.json` with mode `0600`.
|
|
124
|
+
9. With `--write-dev-vars`, writes the local Worker values to `.dev.vars`; with
|
|
112
125
|
`--push-secrets`, transfers the configured service secrets to the matching
|
|
113
126
|
deployed Worker environment over Wrangler stdin.
|
|
114
127
|
|
|
@@ -131,6 +144,48 @@ odla-db schema with the tenant key, compares expected schema entities, and runs
|
|
|
131
144
|
a count aggregate against the first entity. It fails early with a clear message
|
|
132
145
|
when provisioning has not written `.odla/credentials.local.json`.
|
|
133
146
|
|
|
147
|
+
### Read-only Google Calendar
|
|
148
|
+
|
|
149
|
+
Calendar is a platform-custodied connector, not a Google credential stored by
|
|
150
|
+
the application. Enable both `db` and `calendar`, configure calendar ids per
|
|
151
|
+
environment, then run normal provision. The first run has two distinct human
|
|
152
|
+
checkpoints: the odla device code establishes app-owner authority, and the
|
|
153
|
+
subsequent server-issued Google page grants `calendar.events.readonly` consent.
|
|
154
|
+
|
|
155
|
+
For parity with a static Google Appointment Schedule embed/link, set the public
|
|
156
|
+
`bookingPageUrl` per environment. Provision applies it through the owner-only
|
|
157
|
+
calendar settings route; it is public configuration, not a credential.
|
|
158
|
+
|
|
159
|
+
`calendar status` returns the safe connection/sync projection; add `--json` for
|
|
160
|
+
agent automation. Once connected, `calendar calendars` lists ids visible to the
|
|
161
|
+
Google identity so the checked-in selection can be refined. `calendar connect`
|
|
162
|
+
applies the checked-in booking-page setting and starts consent when the
|
|
163
|
+
connection is absent, failed, disconnected, or degraded (so an agent can
|
|
164
|
+
repair revoked credentials); a healthy connection is reused. A `needs_sync`
|
|
165
|
+
connection already has provider credentials, so connect/provision resyncs it
|
|
166
|
+
without requesting Google consent again; an existing authorization or initial
|
|
167
|
+
sync is awaited instead of creating a duplicate attempt.
|
|
168
|
+
`calendar resync` asks the hosted connector to sync immediately; `calendar
|
|
169
|
+
disconnect --yes` stops watches and deletes this app/environment connection's
|
|
170
|
+
encrypted platform token and cursors without purging retained mirror rows,
|
|
171
|
+
which may therefore remain readable but stale. It does not revoke the shared
|
|
172
|
+
user-to-Google-OAuth-project grant, because that could invalidate other odla
|
|
173
|
+
connections for the same user. A future explicitly global revoke command would
|
|
174
|
+
need cross-connection accounting and warning. Production resync requires
|
|
175
|
+
`--yes`, as does a direct production connect. None of these commands accepts a
|
|
176
|
+
Google authorization code, client secret, access token, or refresh token.
|
|
177
|
+
|
|
178
|
+
The SDK uses the existing server-side db values (`ODLA_ENDPOINT`,
|
|
179
|
+
`ODLA_TENANT`, `ODLA_API_KEY`), so calendar adds no Worker secret. Never expose
|
|
180
|
+
`ODLA_API_KEY` to a browser. Trusted Worker code can initialize
|
|
181
|
+
`@odla-ai/calendar`; browser code reads `$bookings` through `@odla-ai/db/client`
|
|
182
|
+
under explicit rules or imports pure helpers from `@odla-ai/calendar/client`.
|
|
183
|
+
|
|
184
|
+
These commands operate the current read/embed reconciliation slice. The CLI has
|
|
185
|
+
no native slot-picker or create/reschedule/cancel command, and exposes no
|
|
186
|
+
rolling-window/age-out, quota-backoff, retention/purge, or provider-derived
|
|
187
|
+
mutation-id control. Public health remains aggregate rather than per calendar.
|
|
188
|
+
|
|
134
189
|
The bundled build/migration skills add a passive pre-ship gate with
|
|
135
190
|
`@odla-ai/security`: after the exact-version availability check, run
|
|
136
191
|
`npm i -D --save-exact @odla-ai/security@0.2.2`, then
|
|
@@ -261,11 +316,28 @@ redacted plan without spawning anything. For the normal path, use
|
|
|
261
316
|
`provision --write-dev-vars --push-secrets` so service enablement, credential
|
|
262
317
|
issuance, local config, and deployed secret transfer stay one composition.
|
|
263
318
|
|
|
319
|
+
`secrets set <name> --env <env>` stores one named secret in that env's tenant
|
|
320
|
+
vault — the same write-only slot Studio's Secrets panel fills (for example
|
|
321
|
+
`clerk_webhook_secret` for synced auth). The value may come only from
|
|
322
|
+
`--from-env <NAME>` or `--stdin`, so a producer command pipes straight into the
|
|
323
|
+
vault without the secret ever appearing on argv, in output, or in an agent's
|
|
324
|
+
transcript; it is encrypted at rest and readable back only by that tenant's
|
|
325
|
+
app API key, never by the CLI, Studio, or the developer token. `$`-prefixed
|
|
326
|
+
names are platform-reserved. `secrets set-clerk-key --env <env>` stores the
|
|
327
|
+
app's Clerk secret key in the reserved `$clerk_secret` slot so the platform can
|
|
328
|
+
resolve the app's users (invites, member lookups); reserved secrets are never
|
|
329
|
+
readable by app keys. It refuses an `sk_test_` key for a prod-named env and
|
|
330
|
+
requires `--yes` to put an `sk_live_` key into a non-prod env, since live users
|
|
331
|
+
would sync into a non-prod tenant. Both commands authenticate with the
|
|
332
|
+
developer token (`$ODLA_DEV_TOKEN`, the cached token, or a fresh device
|
|
333
|
+
approval), and prod-named envs require `--yes`, matching `secrets push`.
|
|
334
|
+
|
|
264
335
|
## Who does what
|
|
265
336
|
|
|
266
337
|
If a change is deterministic from `odla.config.mjs`, the CLI owns it: app and
|
|
267
338
|
service enablement, credential issuance and local persistence, `.dev.vars`,
|
|
268
|
-
schema/rules/auth/AI configuration,
|
|
339
|
+
schema/rules/auth/AI/calendar configuration, owner-safe consent orchestration,
|
|
340
|
+
and Wrangler secret transfer. The coding
|
|
269
341
|
agent owns application semantics: installing `@odla-ai/o11y`, wrapping the
|
|
270
342
|
Worker with `withObservability`, and choosing useful spans, metrics, errors, and
|
|
271
343
|
LLM-usage records. The human owns the device approval, production consent, and
|
|
@@ -317,7 +389,7 @@ export default {
|
|
|
317
389
|
dbEndpoint: process.env.ODLA_ENDPOINT ?? process.env.ODLA_DB_ENDPOINT ?? "https://db.odla.ai",
|
|
318
390
|
app: { id: "my-app", name: "My App" },
|
|
319
391
|
envs: ["dev"], // add "prod" deliberately; provisioning it requires --yes
|
|
320
|
-
services: ["db", "ai", "o11y"],
|
|
392
|
+
services: ["db", "ai", "o11y", "calendar"],
|
|
321
393
|
db: {
|
|
322
394
|
schema: "./src/odla/schema.mjs",
|
|
323
395
|
rules: "./src/odla/rules.mjs",
|
|
@@ -328,6 +400,21 @@ export default {
|
|
|
328
400
|
provider: process.env.ODLA_AI_PROVIDER ?? "anthropic",
|
|
329
401
|
keyEnv: "ANTHROPIC_API_KEY",
|
|
330
402
|
},
|
|
403
|
+
calendar: {
|
|
404
|
+
google: {
|
|
405
|
+
calendars: { dev: ["primary"] },
|
|
406
|
+
bookingPageUrl: {
|
|
407
|
+
dev: "https://calendar.google.com/calendar/appointments/schedules/…",
|
|
408
|
+
},
|
|
409
|
+
match: {
|
|
410
|
+
summaryPrefix: "Intro", // optional
|
|
411
|
+
organizerSelf: true, // default true
|
|
412
|
+
requireAttendees: true, // default true
|
|
413
|
+
},
|
|
414
|
+
attendeePolicy: "full", // or "hashed"
|
|
415
|
+
// This CLI release always requests calendar.events.readonly.
|
|
416
|
+
},
|
|
417
|
+
},
|
|
331
418
|
auth: {
|
|
332
419
|
// Publishable key (public). Created + pulled by the Clerk CLI (`npx clerk`);
|
|
333
420
|
// See the installed odla-migrate phase 3. Inline `pk_…` or "$ENV_VAR".
|
package/REQUIREMENTS.md
CHANGED
|
@@ -44,6 +44,20 @@ Agnacl, but none should mention or special-case Agnacl.
|
|
|
44
44
|
configured custom in-repository paths, must be mode `0600` where applicable
|
|
45
45
|
and gitignored.
|
|
46
46
|
- O11y-only projects must not create or require an odla-db key.
|
|
47
|
+
- Calendar projects must require db, apply one normalized config per env, and
|
|
48
|
+
use the existing db app key rather than introducing an application-held
|
|
49
|
+
Google credential.
|
|
50
|
+
- Google consent must be a separate, state-bound platform checkpoint. The CLI may
|
|
51
|
+
print/open and poll an opaque attempt, but must never receive an OAuth code,
|
|
52
|
+
access token, or refresh token.
|
|
53
|
+
- Read-only calendar intent must request only
|
|
54
|
+
`calendar.events.readonly`; scope elevation belongs in a later explicit flow.
|
|
55
|
+
- Calendar connect/status/discovery/resync/disconnect must be resumable and
|
|
56
|
+
machine-readable. Disconnect must be explicit and disclose that retained
|
|
57
|
+
mirror rows can remain stale.
|
|
58
|
+
- A public per-env `bookingPageUrl` must be validated and applied independently
|
|
59
|
+
of connector config so static Appointment Schedule embeds need no Google/app
|
|
60
|
+
credential in browser code.
|
|
47
61
|
- Schema pushes must be explicit and visible in dry-run.
|
|
48
62
|
- If rules are omitted, schema-derived deny-all rules are the safe default.
|
|
49
63
|
|