@odla-ai/cli 0.11.2 → 0.13.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 CHANGED
@@ -8,13 +8,13 @@
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, connect read-only Google Calendar mirrors, provision o11y ingest credentials, and transfer local or
11
+ deployment links, compose declared npm capability integrations, connect Google Calendar booking, 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.
15
15
 
16
16
  It does not know about any specific app. App identity, environments, services,
17
- schema, rules, auth, AI provider, and links all come from config.
17
+ schema, rules, integrations, auth, AI provider, and links all come from config.
18
18
 
19
19
  ## Install
20
20
 
@@ -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.10.2 version
33
- npm i -D --save-exact @odla-ai/cli@0.10.2
32
+ npm view @odla-ai/cli@0.13.0 version
33
+ npm i -D --save-exact @odla-ai/cli@0.13.0
34
34
  ```
35
35
 
36
36
  ## Prerequisites
@@ -114,13 +114,20 @@ shown-once credential.
114
114
  including from scripted and agent-driven shells; only CI, SSH sessions, and
115
115
  display-less hosts skip the launch. Pass `--open` to force it anyway, or
116
116
  `--no-open` to suppress it. Browser launch is best-effort; the printed URL
117
- and code always remain the fallback.
117
+ and code always remain the fallback and agents must relay that URL to the
118
+ human. The started handshake is persisted privately under `.odla/`, so a
119
+ run killed before approval loses nothing: rerunning resumes the same code.
120
+ Outside an interactive terminal the approval wait is capped (90 seconds by
121
+ default; `--wait <seconds>` overrides), and a still-pending handshake exits
122
+ with code 75 — approve at the URL, then re-run to collect the token.
118
123
  2. Creates the platform app if needed.
119
124
  3. Enables configured services in every configured environment. Calendar
120
125
  config is normalized per env and fixed to Google read-only access.
121
126
  4. Mints or reuses each env's configured service credentials: an odla-db app
122
127
  key for `db` and an ingest token for `o11y`.
123
- 5. Pushes the configured schema and rules.
128
+ 5. Collision-checks and merges declared integration schema/rule fragments,
129
+ pushes the composed database contract, and creates integration seeds only
130
+ when their natural-key rows are absent.
124
131
  6. Configures platform AI and stores provider keys in the tenant vault when the
125
132
  configured key env var is set.
126
133
  7. For calendar, reads owner-visible connection status and, when needed, asks
@@ -146,6 +153,39 @@ The CLI preflights Wrangler first and persists the replacement before pushing;
146
153
  if that final push still fails, follow the printed `secrets push --env ...`
147
154
  retry. Do not run the rotation flag again.
148
155
 
156
+ ### Application capability integrations
157
+
158
+ An integration is an npm capability composed into an app, not a hosted
159
+ platform service. Put data-only descriptors under `integrations` in
160
+ `odla.config.mjs`; do not add their ids to `services`.
161
+
162
+ ```js
163
+ import { createCrmIntegration } from "@odla-ai/crm";
164
+ import { crm } from "./src/crm.js";
165
+
166
+ export default {
167
+ app: { id: "my-app", name: "My App" },
168
+ services: ["db"],
169
+ integrations: [createCrmIntegration(crm, { basePath: "/api/crm" })],
170
+ links: { dev: "https://dev.example.com" },
171
+ };
172
+ ```
173
+
174
+ Descriptors are consumed structurally, so capability packages do not depend
175
+ on the CLI. `provision --dry-run` names every integration and its namespace,
176
+ seed, and probe counts. Provision accepts an app-authored namespace/rule that
177
+ is byte-for-byte structurally identical to an integration fragment, which
178
+ makes existing manually merged apps migratable; conflicting definitions fail
179
+ before credentials or network mutations. A guarded seed requires a
180
+ declared-unique natural key, is queried first, and is created only when absent.
181
+ A concurrent create fails uniqueness instead of overwriting runtime owner edits.
182
+
183
+ `doctor` remains offline: it checks the composed schema, complete rule coverage,
184
+ and seed targets. `smoke` remains read-only: after the normal db checks it runs
185
+ each descriptor's anonymous route probe against `links.<env>`. Installing the
186
+ package, mounting its routes in the Worker, and supplying app authorization are
187
+ source-code responsibilities for the agent/developer.
188
+
149
189
  ### Device-grant security and recovery
150
190
 
151
191
  The account email sent during a fresh handshake is a non-secret identity hint,
@@ -168,8 +208,9 @@ when compromise or accidental approval is possible.
168
208
 
169
209
  `smoke` verifies a provisioned environment from local credentials. It fetches
170
210
  the platform public config, checks the configured AI provider, fetches the live
171
- odla-db schema with the tenant key, compares expected schema entities, and runs
172
- a count aggregate against the first entity. It fails early with a clear message
211
+ odla-db schema with the tenant key, compares the fully composed schema entities,
212
+ runs a count aggregate against the first entity, and executes declared
213
+ integration route probes without credentials. It fails early with a clear message
173
214
  when provisioning has not written `.odla/credentials.local.json`.
174
215
 
175
216
  ### Read-only Google Calendar
package/REQUIREMENTS.md CHANGED
@@ -6,7 +6,8 @@ Agnacl, but none should mention or special-case Agnacl.
6
6
  ## Core Contract
7
7
 
8
8
  - A project must declare intent in a checked-in config file:
9
- app id/name, envs, platform URL, db endpoint, services, schema, rules, auth,
9
+ app id/name, envs, platform URL, db endpoint, services, app-capability
10
+ integrations, schema, rules, auth,
10
11
  AI provider/model, deployment links, and local credential paths.
11
12
  - The CLI must validate that contract without network calls.
12
13
  - The CLI must show a dry-run plan before creating platform state or writing
@@ -14,7 +15,8 @@ Agnacl, but none should mention or special-case Agnacl.
14
15
  - The CLI must treat platform registry and odla-db as separate endpoints. They
15
16
  may be the same in some deployments, but generated configs must not imply it.
16
17
  - If a platform or credential change is deterministic from `odla.config.mjs`,
17
- the CLI owns it. That includes service enablement, service-specific credential
18
+ the CLI owns it. That includes service enablement, integration schema/rule
19
+ composition and guarded seeds, service-specific credential
18
20
  issuance/persistence, local runtime values, and deployed Worker secret
19
21
  transfer. `odla-ai capabilities --json` must expose this boundary to agents.
20
22
  - Source semantics remain with the coding agent: package installation, Worker
@@ -76,6 +78,11 @@ Agnacl, but none should mention or special-case Agnacl.
76
78
  credential in browser code.
77
79
  - Schema pushes must be explicit and visible in dry-run.
78
80
  - If rules are omitted, schema-derived deny-all rules are the safe default.
81
+ - App-capability descriptors are structural config data, not hosted services:
82
+ merge their schema/rules with collision checks, accept identical pre-merged
83
+ definitions, require declared-unique natural keys, and create seeds only
84
+ when absent so owner edits survive every rerun and concurrent creates fail
85
+ instead of overwriting them.
79
86
 
80
87
  ## App Scaffolding Gaps
81
88
 
@@ -85,7 +92,8 @@ Agnacl, but none should mention or special-case Agnacl.
85
92
  `@odla-ai/db` initialization, `@odla-ai/ai initFromPlatform`, and
86
93
  `@odla-ai/kg writeFragment` seed/ingest helpers.
87
94
  - `smoke` should verify:
88
- public-config fetch, db schema presence, a simple db aggregate/query, and AI
95
+ public-config fetch, composed db schema presence, a simple db aggregate/query,
96
+ anonymous integration route probes against the configured deployment link, and AI
89
97
  config resolution. Tenant-vault key availability is still a follow-up because
90
98
  checking it requires knowing the provider secret name and deliberately
91
99
  touching the secret read path.