@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/README.md CHANGED
@@ -1,14 +1,17 @@
1
1
  # @odla-ai/cli
2
2
 
3
- > ⚠️ **Experimentalan agentic-coding experiment.** This package is built and
4
- > operated by autonomous coding agents as an experiment in agentic loops. APIs
5
- > change without notice and nothing here is production-hardened. **Use at your
6
- > own risk.**
3
+ > ⚠️ **Early access pre-1.0.** Agents work from bounded runbooks; humans
4
+ > approve credentials, production changes, releases, and merges. APIs and exact
5
+ > package availability can change. Review the documented guarantees and
6
+ > limitations; this software is MIT-licensed and provided without warranty.
7
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
- push odla-db schema/rules, configure platform AI, configure Clerk auth, record
11
- deployment links, and write local runtime credentials.
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
12
+ deployed Worker secrets without printing them. It also gives platform admins a
13
+ scoped System AI control surface and gives app owners a provider-key-free
14
+ hosted security command.
12
15
 
13
16
  It does not know about any specific app. App identity, environments, services,
14
17
  schema, rules, auth, AI provider, and links all come from config.
@@ -26,7 +29,8 @@ For a project you keep working in, install it as a dev dependency so the
26
29
  shorter `npx odla-ai` form works and the version is pinned by your lockfile:
27
30
 
28
31
  ```bash
29
- npm i -D @odla-ai/cli
32
+ npm view @odla-ai/cli@0.6.0 version
33
+ npm i -D --save-exact @odla-ai/cli@0.6.0
30
34
  ```
31
35
 
32
36
  ## Prerequisites
@@ -46,12 +50,20 @@ npm i -D @odla-ai/cli
46
50
  ## Commands
47
51
 
48
52
  ```bash
53
+ npx odla-ai setup
49
54
  npx odla-ai init --app-id my-app --name "My App"
50
55
  npx odla-ai doctor
56
+ npx odla-ai capabilities --json
57
+ # install SDKs, write the Worker, and create wrangler.jsonc before secret push
51
58
  npx odla-ai provision --dry-run
52
- npx odla-ai provision --write-dev-vars
59
+ npx odla-ai provision --write-dev-vars --push-secrets
53
60
  npx odla-ai smoke --env dev
54
61
  npx odla-ai secrets push --env dev
62
+ npx odla-ai security run . --env dev --ack-redacted-source
63
+ npx odla-ai admin ai show
64
+ npx odla-ai admin ai set security.discovery --provider anthropic --model claude-opus-4-8 --enabled
65
+ npx odla-ai admin ai credentials
66
+ npx odla-ai admin ai credential set anthropic --from-env ANTHROPIC_API_KEY
55
67
  npx odla-ai skill install
56
68
  npx odla-ai version
57
69
  ```
@@ -63,8 +75,16 @@ npx odla-ai version
63
75
  - `src/odla/rules.mjs`
64
76
  - `.gitignore` entries for local credentials
65
77
 
78
+ New configs contain only the `dev` environment. Add `prod` explicitly after
79
+ the development flow is healthy; `provision` refuses to mutate `prod` or
80
+ `production` without `--yes` and supports `--dry-run` for review.
81
+
66
82
  `provision` performs the standard safe setup flow:
67
83
 
84
+ When using `--push-secrets`, create the Worker and its Wrangler config first.
85
+ The CLI checks that config and `wrangler whoami` before it issues or rotates a
86
+ shown-once credential.
87
+
68
88
  1. Gets an `odla_dev_...` token by device handshake, or reuses
69
89
  `ODLA_DEV_TOKEN` / `.odla/dev-token.json`.
70
90
  In an interactive terminal it opens the approval page in your browser when
@@ -73,14 +93,28 @@ npx odla-ai version
73
93
  best-effort; the printed URL and code always remain the fallback.
74
94
  2. Creates the platform app if needed.
75
95
  3. Enables configured services in every configured environment.
76
- 4. Mints or reuses each env's odla-db app key.
96
+ 4. Mints or reuses each env's configured service credentials: an odla-db app
97
+ key for `db` and an ingest token for `o11y`.
77
98
  5. Pushes the configured schema and rules.
78
99
  6. Configures platform AI and stores provider keys in the tenant vault when the
79
100
  configured key env var is set.
80
101
  7. Writes `.odla/credentials.local.json` with mode `0600`.
81
-
82
- Pass `--rotate-keys` to mint fresh db keys. Pass `--no-write-credentials` to
83
- skip writing the local credentials file.
102
+ 8. With `--write-dev-vars`, writes the local Worker values to `.dev.vars`; with
103
+ `--push-secrets`, transfers the configured service secrets to the matching
104
+ deployed Worker environment over Wrangler stdin.
105
+
106
+ Plain reruns are idempotent. Pass `--rotate-o11y-token` only when deliberately
107
+ invalidating and replacing the o11y token; combine it with `--push-secrets` so
108
+ the replacement reaches the Worker in the same run. `--rotate-keys` remains the
109
+ broader credential rotation. Production mutation or secret transfer requires
110
+ `--yes`. Pass `--no-write-credentials` to skip writing the local credentials
111
+ file; it cannot be combined with an operation that would issue a shown-once
112
+ credential.
113
+
114
+ Rotation and Wrangler secret replacement are not a distributed transaction.
115
+ The CLI preflights Wrangler first and persists the replacement before pushing;
116
+ if that final push still fails, follow the printed `secrets push --env ...`
117
+ retry. Do not run the rotation flag again.
84
118
 
85
119
  `smoke` verifies a provisioned environment from local credentials. It fetches
86
120
  the platform public config, checks the configured AI provider, fetches the live
@@ -88,23 +122,82 @@ odla-db schema with the tenant key, compares expected schema entities, and runs
88
122
  a count aggregate against the first entity. It fails early with a clear message
89
123
  when provisioning has not written `.odla/credentials.local.json`.
90
124
 
91
- `secrets push --env <env>` moves the env's odla-db key from
92
- `.odla/credentials.local.json` into the deployed Worker by piping it over
93
- stdin to `wrangler secret put ODLA_API_KEY` the value never appears on
94
- argv, in output, or in an agent's transcript. It preflights `wrangler whoami`
95
- and the presence of a wrangler config file. The env `prod`/`production`
96
- targets the top-level wrangler environment (no `--env` flag is passed to
97
- wrangler) and requires `--yes`; every other env maps to wrangler's
98
- `--env <name>`. `--dry-run` prints a redacted plan without spawning anything.
99
-
100
- `skill install` copies the Claude Code skills bundled with this package
101
- (currently `odla-migrate`, the phased GitHub Pages odla migration
102
- procedure) into the project's `.claude/skills/`, or into `~/.claude/skills/`
103
- with `--global`. Re-runs are idempotent; a locally modified skill file is
104
- never overwritten without `--force`. The skill's reference runbook is served
105
- at <https://odla.ai/llms-migrate.txt>; the human companion "Moving your site
106
- to odla" (accounts, the approval code, costs) lives in the odla docs after
107
- sign-in.
125
+ The bundled build/migration skills add a passive pre-ship gate with
126
+ `@odla-ai/security`: after the exact-version availability check, run
127
+ `npm i -D --save-exact @odla-ai/security@0.2.0`, then
128
+ `npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical`.
129
+ The passive scan remains a separate binary: it makes no model calls and does
130
+ not execute target code. After explicit redacted-source approval,
131
+ `odla-ai security run . --env dev --ack-redacted-source` adds hosted discovery
132
+ and independent validation. The CLI obtains/reuses app-owner auth and the
133
+ platform supplies bounded role grants; it never requests provider keys.
134
+ Early-access run ceilings are rolling; a `429` includes the platform's safe
135
+ retry hint, which the CLI surfaces without echoing arbitrary response text.
136
+ Before installing the exact release, require
137
+ `npm view @odla-ai/security@0.2.0 version` to succeed before installation. An
138
+ exact-version `E404` means the release is unavailable, not that the security
139
+ preflight passed, and does not prove the package name is absent. odla's own
140
+ engineering environment uses an equivalent internal gate; customer projects
141
+ should use the published `odla-security` command above.
142
+
143
+ `admin ai show|set|credentials|credential set` manages platform-funded System
144
+ AI (`o11y.triage`, `security.discovery`, `security.validation`). It uses a
145
+ separate, mode-`0600` `.odla/admin-token.local.json` cache. Studio displays the
146
+ exact scope, only an admin can approve it, and it expires after ~15 minutes;
147
+ the token never becomes ambient admin. Credential writes accept only
148
+ `--from-env <NAME>` or `--stdin` and never place the value in argv, output, or
149
+ the cache. System AI and each app's BYOK AI are separate vault/funding paths.
150
+
151
+ `secrets push --env <env>` is the narrower recovery/retry command. It moves the
152
+ configured env's odla-db key and/or o11y ingest token from
153
+ `.odla/credentials.local.json` into the deployed Worker by piping each value
154
+ over stdin to `wrangler secret put`; values never appear on argv, in output, or
155
+ in an agent's transcript. It preflights `wrangler whoami` and the presence of a
156
+ wrangler config file. The env `prod`/`production` targets the top-level
157
+ wrangler environment (no `--env` flag is passed to Wrangler) and requires
158
+ `--yes`; every other env maps to `wrangler --env <name>`. `--dry-run` prints a
159
+ redacted plan without spawning anything. For the normal path, use
160
+ `provision --write-dev-vars --push-secrets` so service enablement, credential
161
+ issuance, local config, and deployed secret transfer stay one composition.
162
+
163
+ ## Who does what
164
+
165
+ If a change is deterministic from `odla.config.mjs`, the CLI owns it: app and
166
+ service enablement, credential issuance and local persistence, `.dev.vars`,
167
+ schema/rules/auth/AI configuration, and Wrangler secret transfer. The coding
168
+ agent owns application semantics: installing `@odla-ai/o11y`, wrapping the
169
+ Worker with `withObservability`, and choosing useful spans, metrics, errors, and
170
+ LLM-usage records. The human owns the device approval, production consent, and
171
+ explicit destructive rotation. Studio is where people view telemetry and
172
+ perform manual recovery, configure System AI, and inspect app/run-attributed
173
+ platform usage; its o11y token control is not the normal setup path.
174
+ Run `npx odla-ai capabilities` for the human-readable contract or add `--json`
175
+ when an agent or tool needs to branch on it without scraping prose.
176
+
177
+ `setup` (and `skill install`) installs one complete offline runbook bundle at
178
+ `.agents/skills/`, then adds thin native adapters for Claude Code
179
+ (`.claude/skills/`), Codex, Cursor (`.cursor/rules/`), GitHub Copilot
180
+ (`.github/copilot-instructions.md`), Gemini CLI (`GEMINI.md`), and portable
181
+ `AGENTS.md` agents. The default is `--agent all`; select one or more with
182
+ `--agent claude,codex` or repeated `--agent` flags. A global install supports
183
+ the native Claude and Codex roots only.
184
+
185
+ Existing `AGENTS.md`, `GEMINI.md`, and Copilot instructions are preserved. The
186
+ installer appends a bounded odla-managed section, is idempotent, refuses
187
+ symlink-redirection and locally changed managed content, and lets `--force`
188
+ replace only odla-owned content. The local bundle includes build, migration,
189
+ and observability-debug procedures plus every reference they need; agents do
190
+ not need online docs or access to odla's private service source after setup.
191
+
192
+ After running setup, the whole prompt can be: “Set up odla in this repo using
193
+ the installed local odla runbook. Decide whether this is a new app or an
194
+ existing site to migrate, then drive it end to end. Ask me only for the device
195
+ approval and other human-only checkpoints.”
196
+
197
+ For programmatic callers, `installSkill()` keeps `targetDir`, `written`, and
198
+ `unchanged` as one unambiguous primary-root view: the latter two contain paths
199
+ relative to `targetDir` only. Use the additive absolute `writtenPaths` and
200
+ `unchangedPaths` fields to inspect every shared-bundle and adapter artifact.
108
201
 
109
202
  `doctor` also lints for common footguns: permission rules that are literally
110
203
  `"true"` (public writes always warn; a public `view` warns unless the
@@ -122,8 +215,8 @@ export default {
122
215
  platformUrl: process.env.ODLA_PLATFORM_URL ?? "https://odla.ai",
123
216
  dbEndpoint: process.env.ODLA_ENDPOINT ?? process.env.ODLA_DB_ENDPOINT ?? "https://db.odla.ai",
124
217
  app: { id: "my-app", name: "My App" },
125
- envs: ["prod", "dev"],
126
- services: ["db", "ai"],
218
+ envs: ["dev"], // add "prod" deliberately; provisioning it requires --yes
219
+ services: ["db", "ai", "o11y"],
127
220
  db: {
128
221
  schema: "./src/odla/schema.mjs",
129
222
  rules: "./src/odla/rules.mjs",
@@ -135,6 +228,8 @@ export default {
135
228
  keyEnv: "ANTHROPIC_API_KEY",
136
229
  },
137
230
  auth: {
231
+ // Publishable key (public). Created + pulled by the Clerk CLI (`npx clerk`);
232
+ // See the installed odla-migrate phase 3. Inline `pk_…` or "$ENV_VAR".
138
233
  clerk: {
139
234
  dev: "$CLERK_PUBLISHABLE_KEY",
140
235
  prod: "$CLERK_PUBLISHABLE_KEY",
package/REQUIREMENTS.md CHANGED
@@ -13,6 +13,13 @@ Agnacl, but none should mention or special-case Agnacl.
13
13
  credentials.
14
14
  - The CLI must treat platform registry and odla-db as separate endpoints. They
15
15
  may be the same in some deployments, but generated configs must not imply it.
16
+ - 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
+ issuance/persistence, local runtime values, and deployed Worker secret
19
+ transfer. `odla-ai capabilities --json` must expose this boundary to agents.
20
+ - Source semantics remain with the coding agent: package installation, Worker
21
+ instrumentation, and application-specific signals/rules. Humans approve
22
+ identity, production mutation, and explicit destructive rotation.
16
23
 
17
24
  ## Human Approval
18
25
 
@@ -26,9 +33,17 @@ Agnacl, but none should mention or special-case Agnacl.
26
33
 
27
34
  ## Safe Provisioning
28
35
 
29
- - Re-runs must be idempotent: reuse existing app registration and local db keys.
30
- - Key rotation must be explicit (`--rotate-keys`).
31
- - Local runtime files (`.dev.vars`, local credentials) must be gitignored.
36
+ - Re-runs must be idempotent: reuse existing app registration and local service
37
+ credentials. A missing local shown-once token must fail safely instead of
38
+ rotating a possibly live credential.
39
+ - Credential rotation must be explicit: `--rotate-o11y-token` for only o11y or
40
+ `--rotate-keys` for the broader credential set.
41
+ - `--push-secrets` must preflight Wrangler configuration and login before any
42
+ shown-once issuance or destructive rotation, then pipe values over stdin.
43
+ - Local runtime files (`.dev.vars`, token cache, local credentials), including
44
+ configured custom in-repository paths, must be mode `0600` where applicable
45
+ and gitignored.
46
+ - O11y-only projects must not create or require an odla-db key.
32
47
  - Schema pushes must be explicit and visible in dry-run.
33
48
  - If rules are omitted, schema-derived deny-all rules are the safe default.
34
49