@odla-ai/cli 0.33.0 → 0.34.1
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 +204 -112
- package/REQUIREMENTS.md +6 -0
- package/dist/bin.cjs +1027 -527
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-YSQORU5J.js → chunk-RUEM7ZTA.js} +998 -523
- package/dist/chunk-RUEM7ZTA.js.map +1 -0
- package/dist/{cli-U436OLYW.js → cli-NKNQLWOM.js} +2 -2
- package/dist/index.cjs +1001 -524
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +173 -4
- package/dist/index.d.ts +173 -4
- package/dist/index.js +5 -1
- package/package.json +2 -2
- package/skills/odla/SKILL.md +65 -35
- package/skills/odla/references/agent-identity.md +5 -5
- package/skills/odla/references/build.md +16 -15
- package/skills/odla/references/co-owners.md +1 -1
- package/skills/odla/references/pm-work-intake.md +12 -12
- package/skills/odla/references/pm.md +17 -17
- package/skills/odla/references/sdks.md +2 -2
- package/skills/odla-migrate/SKILL.md +23 -5
- package/skills/odla-migrate/references/phase-2-chapter.md +1 -1
- package/skills/odla-migrate/references/phase-2-db.md +11 -10
- package/skills/odla-migrate/references/phase-3-auth.md +2 -2
- package/skills/odla-migrate/references/phase-3b-user-sync.md +2 -2
- package/skills/odla-migrate/references/phase-4-ai.md +3 -3
- package/skills/odla-migrate/references/phase-5-cutover.md +5 -5
- package/skills/odla-migrate/references/project-state.md +4 -4
- package/skills/odla-migrate/references/secrets-map.md +6 -6
- package/skills/odla-migrate/references/troubleshooting.md +23 -23
- package/skills/odla-o11y-debug/SKILL.md +3 -3
- package/dist/chunk-YSQORU5J.js.map +0 -1
- /package/dist/{cli-U436OLYW.js.map → cli-NKNQLWOM.js.map} +0 -0
|
@@ -39,7 +39,7 @@ key; it never forwards or accepts another site's Clerk JWT.
|
|
|
39
39
|
- `npx clerk link` (or `--app <id>`), then `npx clerk env pull` — pull
|
|
40
40
|
the dev `pk_test_…` into `.env.local`. Take only the publishable key.
|
|
41
41
|
2. Add the key to `odla.config.mjs`: `auth: { clerk: { dev: "<pk_test_…>" } }`
|
|
42
|
-
(inline is fine — it's public), then `npx @odla-ai/cli provision`
|
|
42
|
+
(inline is fine — it's public), then `npx --yes @odla-ai/cli@latest provision`
|
|
43
43
|
(idempotent) — calls setAuth for the dev env; the issuer is derived
|
|
44
44
|
from the key. **provision OVERWRITES any stale key** on public-config.
|
|
45
45
|
The worker fetches auth config from public-config at runtime, so a key
|
|
@@ -146,7 +146,7 @@ works. Before writing any markup:
|
|
|
146
146
|
|
|
147
147
|
- [ ] Unauthenticated curl to the gated route → 401
|
|
148
148
|
- [ ] Signed-in browser session reaches the gated route
|
|
149
|
-
- [ ] `npx @odla-ai/cli smoke --env dev` still passes
|
|
149
|
+
- [ ] `npx --yes @odla-ai/cli@latest smoke --env dev` still passes
|
|
150
150
|
- [ ] Every added UI element matches the site's existing look (fonts,
|
|
151
151
|
palette, logo, spacing) — human-confirmed, not self-asserted
|
|
152
152
|
- [ ] Post-login redirect lands on a real URL (mind trailing-slash /
|
|
@@ -41,14 +41,14 @@ Enable it here.
|
|
|
41
41
|
2. **Store the secret in the tenant vault** as `clerk_webhook_secret`, write-only.
|
|
42
42
|
If any command can print the `whsec_` (Clerk CLI, Svix API), pipe it without
|
|
43
43
|
it ever being displayed:
|
|
44
|
-
`<command that prints whsec_…> | npx @odla-ai/cli secrets set clerk_webhook_secret --env dev --stdin`.
|
|
44
|
+
`<command that prints whsec_…> | npx --yes @odla-ai/cli@latest secrets set clerk_webhook_secret --env dev --stdin`.
|
|
45
45
|
Otherwise a human pastes it into Studio's secret UI (`odla.ai/studio` → the
|
|
46
46
|
app → the env → secrets) — same write-only slot. The server decrypts it only
|
|
47
47
|
to verify inbound events (svix HMAC over `id.timestamp.body`).
|
|
48
48
|
3. **(Optional) `sk_…`** — the webhook payload already carries email/name/image,
|
|
49
49
|
so the basic mirror needs only `whsec_`. Add the Clerk backend key only if
|
|
50
50
|
you later need to resolve data the webhook doesn't send (invites, member
|
|
51
|
-
lookups): `npx @odla-ai/cli secrets set-clerk-key --env dev --from-env CLERK_SECRET_KEY`
|
|
51
|
+
lookups): `npx --yes @odla-ai/cli@latest secrets set-clerk-key --env dev --from-env CLERK_SECRET_KEY`
|
|
52
52
|
stores it in the reserved `$clerk_secret` slot, write-only.
|
|
53
53
|
|
|
54
54
|
## Verify
|
|
@@ -15,11 +15,11 @@ own terminal so you never see the value.
|
|
|
15
15
|
via this session):
|
|
16
16
|
|
|
17
17
|
export <PROVIDER>_API_KEY=... # their key
|
|
18
|
-
npx @odla-ai/cli provision
|
|
18
|
+
npx --yes @odla-ai/cli@latest provision
|
|
19
19
|
|
|
20
20
|
provision stores the key in the tenant vault and sets provider/model
|
|
21
21
|
in the registry. Their shell forgets it when closed; wrangler and git
|
|
22
|
-
never see it. If they use `! npx @odla-ai/cli provision` in-session, the
|
|
22
|
+
never see it. If they use `! npx --yes @odla-ai/cli@latest provision` in-session, the
|
|
23
23
|
export must still happen in a terminal you don't read.
|
|
24
24
|
3. `npm i @odla-ai/ai`. In the worker, use `initFromPlatform` — it reads
|
|
25
25
|
provider/model from public-config (cached ~60s) and resolves the key
|
|
@@ -32,7 +32,7 @@ own terminal so you never see the value.
|
|
|
32
32
|
|
|
33
33
|
## Verification checklist
|
|
34
34
|
|
|
35
|
-
- [ ] `npx @odla-ai/cli smoke --env dev` passes
|
|
35
|
+
- [ ] `npx --yes @odla-ai/cli@latest smoke --env dev` passes
|
|
36
36
|
- [ ] The AI route returns a model response on the deployed dev worker
|
|
37
37
|
- [ ] `wrangler.jsonc` `vars` contain NO provider key; `git grep` for the
|
|
38
38
|
key's prefix finds nothing
|
|
@@ -17,8 +17,8 @@ instance, never a second Clerk app per env; final go/no-go at each step.
|
|
|
17
17
|
add `links: { prod: "https://<domain>" }` (the CNAME domain captured in
|
|
18
18
|
Phase 0). If using AI, the human re-runs the Phase 4 export + provision
|
|
19
19
|
so the PROD tenant's vault gets the key.
|
|
20
|
-
2. `npx @odla-ai/cli provision --dry-run`, show the human, then
|
|
21
|
-
`npx @odla-ai/cli provision --yes --push-secrets` — provisions the prod
|
|
20
|
+
2. `npx --yes @odla-ai/cli@latest provision --dry-run`, show the human, then
|
|
21
|
+
`npx --yes @odla-ai/cli@latest provision --yes --push-secrets` — provisions the prod
|
|
22
22
|
tenant (`<appId>`) and transfers its configured db/o11y secrets through
|
|
23
23
|
Wrangler stdin. `--yes` is the explicit production consent; use standalone
|
|
24
24
|
`secrets push --env prod --yes` only to retry the transfer (see
|
|
@@ -32,7 +32,7 @@ instance, never a second Clerk app per env; final go/no-go at each step.
|
|
|
32
32
|
Review `REPORT.md`; a candidate is a lead, not confirmation, and a baseline
|
|
33
33
|
requires a concrete reason, owner, and expiry.
|
|
34
34
|
If the human explicitly approves redacted tracked-source disclosure, follow
|
|
35
|
-
with `npx @odla-ai/cli security run . --env prod --ack-redacted-source`.
|
|
35
|
+
with `npx --yes @odla-ai/cli@latest security run . --env prod --ack-redacted-source`.
|
|
36
36
|
The platform owns provider credentials and attributes the bounded,
|
|
37
37
|
independent-model run to this app; never request provider keys locally.
|
|
38
38
|
For a repeatable commit-pinned review, the human can first approve
|
|
@@ -46,7 +46,7 @@ instance, never a second Clerk app per env; final go/no-go at each step.
|
|
|
46
46
|
request/response contracts on the prod workers.dev URL. Equal payload values
|
|
47
47
|
with different keys, nesting, types, units, or omission behavior are not
|
|
48
48
|
parity.
|
|
49
|
-
5. `npx @odla-ai/cli smoke --env prod`.
|
|
49
|
+
5. `npx --yes @odla-ai/cli@latest smoke --env prod`.
|
|
50
50
|
6. Human: add the domain to Cloudflare, then attach it to the prod
|
|
51
51
|
worker (Workers & Pages → the worker → Domains & Routes). Supply
|
|
52
52
|
them the exact hostname values to enter.
|
|
@@ -81,7 +81,7 @@ production on the *existing* app. Then:
|
|
|
81
81
|
|
|
82
82
|
## Verification checklist
|
|
83
83
|
|
|
84
|
-
- [ ] `npx @odla-ai/cli smoke --env prod` passes
|
|
84
|
+
- [ ] `npx --yes @odla-ai/cli@latest smoke --env prod` passes
|
|
85
85
|
- [ ] Passive `odla-security` pre-cutover report reviewed; critical lead gate passes
|
|
86
86
|
- [ ] Public domain serves from the worker (check the `x-odla-worker`
|
|
87
87
|
header) on every parity path
|
|
@@ -51,10 +51,10 @@ Resolve `appId` from `odla.config.mjs`; do not guess it from a repository name,
|
|
|
51
51
|
deployment, old branch, or conversation.
|
|
52
52
|
|
|
53
53
|
```cmd
|
|
54
|
-
npx @odla-ai/cli pm next --app <appId>
|
|
55
|
-
npx @odla-ai/cli pm bug list --app <appId> --status open
|
|
56
|
-
npx @odla-ai/cli pm decision list --app <appId> --limit 20
|
|
57
|
-
npx @odla-ai/cli pm goal list --app <appId> --status open
|
|
54
|
+
npx --yes @odla-ai/cli@latest pm next --app <appId>
|
|
55
|
+
npx --yes @odla-ai/cli@latest pm bug list --app <appId> --status open
|
|
56
|
+
npx --yes @odla-ai/cli@latest pm decision list --app <appId> --limit 20
|
|
57
|
+
npx --yes @odla-ai/cli@latest pm goal list --app <appId> --status open
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
Read the linked goal and the active task's comments before editing. Confirm
|
|
@@ -30,8 +30,8 @@ authorizes one exact Cloudflare target; Registry stages additive DB/o11y
|
|
|
30
30
|
credentials, the CLI holds plaintext only in memory, and one Wrangler bulk
|
|
31
31
|
stdin call installs `ODLA_API_KEY` plus `ODLA_O11Y_TOKEN`:
|
|
32
32
|
|
|
33
|
-
npx @odla-ai/cli provision --push-secrets
|
|
34
|
-
npx @odla-ai/cli provision --live --yes --push-secrets # Phase 5; prod only
|
|
33
|
+
npx --yes @odla-ai/cli@latest provision --push-secrets
|
|
34
|
+
npx --yes @odla-ai/cli@latest provision --live --yes --push-secrets # Phase 5; prod only
|
|
35
35
|
|
|
36
36
|
Each developer and Worker may have a different credential for the same sandbox
|
|
37
37
|
tenant. Revocation is targeted and never rotates siblings. Use
|
|
@@ -39,8 +39,8 @@ tenant. Revocation is targeted and never rotates siblings. Use
|
|
|
39
39
|
one deployed runtime. Use the narrower command below only to transfer an
|
|
40
40
|
already-saved local-development credential:
|
|
41
41
|
|
|
42
|
-
npx @odla-ai/cli secrets push --env dev
|
|
43
|
-
npx @odla-ai/cli secrets push --env prod --yes
|
|
42
|
+
npx --yes @odla-ai/cli@latest secrets push --env dev
|
|
43
|
+
npx --yes @odla-ai/cli@latest secrets push --env prod --yes
|
|
44
44
|
|
|
45
45
|
There is intentionally no production manual-copy fallback. If the CLI is
|
|
46
46
|
unavailable, repair the CLI or Registry session path rather than exporting a
|
|
@@ -52,8 +52,8 @@ production key into shell history or chat.
|
|
|
52
52
|
reading the value only from stdin or a named env var — never argv — so a
|
|
53
53
|
producer command pipes straight into the vault:
|
|
54
54
|
|
|
55
|
-
<command that prints the value> | npx @odla-ai/cli secrets set clerk_webhook_secret --env dev --stdin
|
|
56
|
-
npx @odla-ai/cli secrets set-clerk-key --env dev --from-env CLERK_SECRET_KEY
|
|
55
|
+
<command that prints the value> | npx --yes @odla-ai/cli@latest secrets set clerk_webhook_secret --env dev --stdin
|
|
56
|
+
npx --yes @odla-ai/cli@latest secrets set-clerk-key --env dev --from-env CLERK_SECRET_KEY
|
|
57
57
|
|
|
58
58
|
The value cannot be read back by the CLI, Studio, or the developer token —
|
|
59
59
|
only by that tenant's app API key (reserved `$` secrets not even then). Studio
|
|
@@ -22,30 +22,30 @@ Cause: tenant confusion — the code ran against `<appId>` (prod) instead
|
|
|
22
22
|
of `<appId>--dev`, or vice versa. Typical trigger: `wrangler deploy`
|
|
23
23
|
without `--env dev`, or `wrangler dev` picking up top-level vars.
|
|
24
24
|
Fix: check `ODLA_TENANT`/`ODLA_ENV` in the relevant `wrangler.jsonc`
|
|
25
|
-
env block and which deploy command ran. `npx @odla-ai/cli smoke --env dev`
|
|
25
|
+
env block and which deploy command ran. `npx --yes @odla-ai/cli@latest smoke --env dev`
|
|
26
26
|
prints what it verified against.
|
|
27
27
|
|
|
28
28
|
## Provision fails with an auth/token error
|
|
29
29
|
|
|
30
30
|
Cause: the `odla_dev_…` token expired (~24h) or the handshake was never
|
|
31
31
|
approved.
|
|
32
|
-
Fix:
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
Fix: start one fresh foreground provision with the matching existing account
|
|
33
|
+
supplied by `--email` or `ODLA_USER_EMAIL`, plus `--no-open --wait 600`.
|
|
34
|
+
Immediately surface the printed URL and code to that human and preserve the CLI
|
|
35
|
+
process while they review and approve it. Never ask for a password or session
|
|
36
|
+
token.
|
|
37
37
|
|
|
38
38
|
## Handshake exits with code 75 / "handshake still pending"
|
|
39
39
|
|
|
40
|
-
Cause: nobody approved
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Fix:
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
retries
|
|
40
|
+
Cause: nobody approved before the CLI process's wait cap. The opaque device code
|
|
41
|
+
lived only in that process and is not persisted, so an exited process cannot
|
|
42
|
+
collect a later approval of its old URL.
|
|
43
|
+
Fix: tell the human the old code is no longer usable. Start one fresh foreground
|
|
44
|
+
command with `--no-open --wait 600`, immediately surface its new clickable URL
|
|
45
|
+
and code, and keep that exact CLI process running. Wait only on the tool's
|
|
46
|
+
existing process session; the CLI owns protocol polling. Do not use `open`,
|
|
47
|
+
browser control, `curl`, a shell wait/poll loop, detached execution, or
|
|
48
|
+
unattended retries.
|
|
49
49
|
|
|
50
50
|
## The approval URL says no request matches, or is never approvable
|
|
51
51
|
|
|
@@ -65,22 +65,22 @@ prints a URL, polls, and times out.
|
|
|
65
65
|
Fix: confirm the address with the human and re-run. **Never derive it from
|
|
66
66
|
`git config user.email`, `gh`, or a commit author** — that is the usual source
|
|
67
67
|
of this, because a git identity is routinely a different address from the odla
|
|
68
|
-
account.
|
|
69
|
-
|
|
70
|
-
registered — the human must add it to their account (or
|
|
71
|
-
one), and no amount of retrying will help.
|
|
68
|
+
account. A legacy `.odla/handshake.local.json` is discarded by current clients
|
|
69
|
+
and must not be treated as resumable state. Repeated failures with the same
|
|
70
|
+
address mean it is not registered — the human must add it to their account (or
|
|
71
|
+
use the registered one), and no amount of retrying will help.
|
|
72
72
|
|
|
73
73
|
## `smoke` fails: missing credentials
|
|
74
74
|
|
|
75
75
|
Cause: `.odla/credentials.local.json` absent, for a different app id,
|
|
76
76
|
or lacking a db key for the requested env.
|
|
77
|
-
Fix: run `npx @odla-ai/cli provision` for the configured envs first; confirm
|
|
77
|
+
Fix: run `npx --yes @odla-ai/cli@latest provision` for the configured envs first; confirm
|
|
78
78
|
`envs` in odla.config.mjs includes the env you're smoking.
|
|
79
79
|
|
|
80
80
|
## `smoke` fails: schema mismatch
|
|
81
81
|
|
|
82
82
|
Cause: local `src/odla/schema.mjs` changed since the last push.
|
|
83
|
-
Fix: re-run `npx @odla-ai/cli provision` (schema re-push is the migration
|
|
83
|
+
Fix: re-run `npx --yes @odla-ai/cli@latest provision` (schema re-push is the migration
|
|
84
84
|
mechanism; additive changes are safe on live tenants), then re-run
|
|
85
85
|
smoke.
|
|
86
86
|
|
|
@@ -88,7 +88,7 @@ smoke.
|
|
|
88
88
|
|
|
89
89
|
Cause: an older CLI expected one o11y token per tenant. Current o11y credentials
|
|
90
90
|
are additive, so another developer or Worker's token is not an obstacle.
|
|
91
|
-
Fix: run `npx @odla-ai/cli provision --push-secrets` (add `--yes` when production
|
|
91
|
+
Fix: run `npx --yes @odla-ai/cli@latest provision --push-secrets` (add `--yes` when production
|
|
92
92
|
is in the plan). The approved handshake stages a new target-bound token and DB
|
|
93
93
|
key, installs them without a local plaintext cache, and leaves every sibling
|
|
94
94
|
credential intact. Use destructive rotation only for an actual compromise.
|
|
@@ -127,7 +127,7 @@ Wrangler bulk operation automatically revokes its staged set.
|
|
|
127
127
|
|
|
128
128
|
## Something not covered here
|
|
129
129
|
|
|
130
|
-
Check, in order: `npx @odla-ai/cli doctor` output; this skill's current phase
|
|
130
|
+
Check, in order: `npx --yes @odla-ai/cli@latest doctor` output; this skill's current phase
|
|
131
131
|
and troubleshooting references; then the relevant installed package README and
|
|
132
132
|
exported TypeScript declarations/JSDoc. Do not improvise around a safety rule
|
|
133
133
|
to unblock yourself — surface the blocker to the human instead.
|
|
@@ -22,8 +22,8 @@ do those requests share."
|
|
|
22
22
|
Start with the stable aggregate envelope before composing individual routes:
|
|
23
23
|
|
|
24
24
|
```cmd
|
|
25
|
-
npx @odla-ai/cli context show --app <appId> --env prod --json
|
|
26
|
-
npx @odla-ai/cli o11y status --app <appId> --env prod --minutes 60 --json
|
|
25
|
+
npx --yes @odla-ai/cli@latest context show --app <appId> --env prod --json
|
|
26
|
+
npx --yes @odla-ai/cli@latest o11y status --app <appId> --env prod --minutes 60 --json
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Both commands work outside a project checkout. `context show` reports where
|
|
@@ -123,7 +123,7 @@ bug against the app, with the cohort in the description and the trace id in a
|
|
|
123
123
|
comment:
|
|
124
124
|
|
|
125
125
|
```cmd
|
|
126
|
-
npx @odla-ai/cli pm bug add --app <appId> --title "POST /pay 503s under retry" --severity high --desc "…"
|
|
126
|
+
npx --yes @odla-ai/cli@latest pm bug add --app <appId> --title "POST /pay 503s under retry" --severity high --desc "…"
|
|
127
127
|
```
|
|
128
128
|
|
|
129
129
|
Severity follows the blast radius, not your confidence. The conventions and the
|