@odla-ai/cli 0.10.0 → 0.10.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 +33 -6
- package/REQUIREMENTS.md +17 -1
- package/dist/bin.cjs +61 -31
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +1 -1
- package/dist/{chunk-WDKBW4BE.js → chunk-MWVKOIGR.js} +62 -32
- package/dist/chunk-MWVKOIGR.js.map +1 -0
- package/dist/index.cjs +61 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +30 -8
- package/dist/index.d.ts +30 -8
- package/dist/index.js +1 -1
- package/llms.txt +64 -15
- package/package.json +2 -2
- package/skills/odla/SKILL.md +7 -2
- package/skills/odla/references/build.md +5 -3
- package/skills/odla-migrate/SKILL.md +3 -0
- package/skills/odla-migrate/references/phase-2-db.md +8 -6
- package/skills/odla-migrate/references/secrets-map.md +2 -1
- package/skills/odla-migrate/references/troubleshooting.md +3 -1
- package/skills/odla-o11y-debug/SKILL.md +7 -3
- package/dist/chunk-WDKBW4BE.js.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -30,6 +30,8 @@ type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write
|
|
|
30
30
|
interface ScopedPlatformTokenOptions {
|
|
31
31
|
platform: string;
|
|
32
32
|
scope: ScopedPlatformScope;
|
|
33
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
34
|
+
email?: string;
|
|
33
35
|
open?: boolean;
|
|
34
36
|
fetch?: typeof fetch;
|
|
35
37
|
stdout?: Pick<typeof console, "log">;
|
|
@@ -59,6 +61,8 @@ interface AdminAiOptions {
|
|
|
59
61
|
maxCallsPerRun?: number;
|
|
60
62
|
platform?: string;
|
|
61
63
|
token?: string;
|
|
64
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
65
|
+
email?: string;
|
|
62
66
|
json?: boolean;
|
|
63
67
|
open?: boolean;
|
|
64
68
|
fetch?: typeof fetch;
|
|
@@ -91,16 +95,17 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
|
|
|
91
95
|
/** Stable, machine-readable division of work between the CLI, coding agent,
|
|
92
96
|
* human operator, and Studio. Printed by `odla-ai capabilities --json`. */
|
|
93
97
|
declare const CAPABILITIES: {
|
|
94
|
-
readonly cli: readonly ["register the app and enable configured services per environment", "issue, persist, and explicitly rotate configured service credentials", "write local Worker values and push deployed Worker secrets through Wrangler stdin", "store tenant-vault secrets (including the Clerk webhook secret and reserved Clerk secret key) write-only from stdin or an env var", "push db schema/rules and configure platform AI, auth, and deployment links", "apply read-only Google calendar mirror and public booking-page config, then drive state-bound consent, status, discovery, resync, and disconnect flows", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys", "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"];
|
|
98
|
+
readonly cli: readonly ["start an email-bound device request without accepting a password or user session token", "register the app and enable configured services per environment", "issue, persist, and explicitly rotate configured service credentials", "write local Worker values and push deployed Worker secrets through Wrangler stdin", "store tenant-vault secrets (including the Clerk webhook secret and reserved Clerk secret key) write-only from stdin or an env var", "push db schema/rules and configure platform AI, auth, and deployment links", "apply read-only Google calendar mirror and public booking-page config, then drive state-bound consent, status, discovery, resync, and disconnect flows", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys", "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"];
|
|
95
99
|
readonly agent: readonly ["install and import the selected odla SDKs", "wrap the Worker with withObservability and choose useful telemetry", "make application-specific schema, rules, auth, UI, and migration decisions", "wire @odla-ai/calendar into trusted Worker code and keep the app admin key out of browsers"];
|
|
96
|
-
readonly human: readonly ["
|
|
97
|
-
readonly studio: readonly ["view telemetry and environment state", "review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens", "perform manual credential recovery when the CLI's local shown-once copy is unavailable", "configure system AI purposes and view app/environment/run-attributed usage", "connect/revoke GitHub security sources and inspect ref-to-SHA jobs, routes, retention, coverage, and normalized reports"];
|
|
100
|
+
readonly human: readonly ["provide the existing odla account email, then sign in and explicitly review/approve the exact device code", "review mirrored calendar/attendee disclosure and complete the server-issued Google consent flow", "consent to production changes with --yes", "request destructive credential rotation explicitly", "review application semantics, security findings, releases, and merges", "approve redacted-source disclosure before hosted security reasoning", "approve GitHub App repository access separately from redacted-snippet disclosure"];
|
|
101
|
+
readonly studio: readonly ["view telemetry and environment state", "let signed-in users inventory/revoke their own agent grants and admins audit/global-revoke them", "review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens", "perform manual credential recovery when the CLI's local shown-once copy is unavailable", "configure system AI purposes and view app/environment/run-attributed usage", "connect/revoke GitHub security sources and inspect ref-to-SHA jobs, routes, retention, coverage, and normalized reports"];
|
|
98
102
|
};
|
|
99
103
|
type Output = Pick<typeof console, "log">;
|
|
100
104
|
/** Print the stable responsibility boundary for humans or agent tooling. */
|
|
101
105
|
declare function printCapabilities(json?: boolean, out?: Output): void;
|
|
102
106
|
|
|
103
107
|
declare const CALENDAR_STATES: readonly ["not_connected", "authorizing", "needs_sync", "initial_sync", "healthy", "degraded", "disconnected", "failed"];
|
|
108
|
+
/** Connection lifecycle reported by the registry; mirrors the platform's calendar states. */
|
|
104
109
|
type CalendarConnectionState = (typeof CALENDAR_STATES)[number];
|
|
105
110
|
/** Owner-visible, secret-free calendar connection and sync health. */
|
|
106
111
|
interface CalendarStatus {
|
|
@@ -136,10 +141,15 @@ interface AvailableGoogleCalendar {
|
|
|
136
141
|
accessRole?: "freeBusyReader" | "reader" | "writer" | "owner";
|
|
137
142
|
}
|
|
138
143
|
|
|
144
|
+
/** Shared inputs for the calendar lifecycle commands (status, connect,
|
|
145
|
+
* calendars, resync, disconnect): the project config path and env, plus
|
|
146
|
+
* injectable token, output, browser, clock, and polling hooks so agents and
|
|
147
|
+
* tests can drive the flow deterministically. */
|
|
139
148
|
interface CalendarLifecycleOptions {
|
|
140
|
-
configPath: string;
|
|
141
|
-
env?: string;
|
|
142
|
-
token?: string;
|
|
149
|
+
/** Path to the checked-in odla project config. */ configPath: string;
|
|
150
|
+
/** Configured environment; defaults to dev when present. */ env?: string;
|
|
151
|
+
/** Existing developer-token override. */ token?: string;
|
|
152
|
+
/** Existing odla account email used only for a fresh handshake. */ email?: string;
|
|
143
153
|
open?: boolean;
|
|
144
154
|
interactive?: boolean;
|
|
145
155
|
yes?: boolean;
|
|
@@ -206,6 +216,8 @@ interface GoogleCalendarConfig {
|
|
|
206
216
|
/** Store normalized attendee addresses, or only SHA-256 match keys. */
|
|
207
217
|
attendeePolicy?: "full" | "hashed";
|
|
208
218
|
}
|
|
219
|
+
/** The `calendar` block of `odla.config.mjs` — the Google read-mirror
|
|
220
|
+
* settings; valid only alongside the db service. */
|
|
209
221
|
interface CalendarConfig {
|
|
210
222
|
google: GoogleCalendarConfig;
|
|
211
223
|
}
|
|
@@ -309,6 +321,8 @@ interface ProvisionOptions {
|
|
|
309
321
|
writeCredentials?: boolean;
|
|
310
322
|
writeDevVars?: string | boolean;
|
|
311
323
|
token?: string;
|
|
324
|
+
/** Existing odla account email used only when a fresh device handshake is required. */
|
|
325
|
+
email?: string;
|
|
312
326
|
/** true forces browser launch, false disables it, undefined auto-opens only for interactive terminals. */
|
|
313
327
|
open?: boolean;
|
|
314
328
|
/** Test/embedding override for terminal interactivity. Defaults to stdin/stdout TTY detection. */
|
|
@@ -344,6 +358,8 @@ interface SmokeOptions {
|
|
|
344
358
|
env?: string;
|
|
345
359
|
/** Developer-token override used only for owner-visible calendar health. */
|
|
346
360
|
token?: string;
|
|
361
|
+
/** Existing odla account email used only when a fresh device handshake is required. */
|
|
362
|
+
email?: string;
|
|
347
363
|
open?: boolean;
|
|
348
364
|
interactive?: boolean;
|
|
349
365
|
openApprovalUrl?: (url: string) => Promise<void>;
|
|
@@ -351,6 +367,7 @@ interface SmokeOptions {
|
|
|
351
367
|
stdout?: Pick<typeof console, "log" | "error">;
|
|
352
368
|
}
|
|
353
369
|
|
|
370
|
+
/** The only Google OAuth scope the platform ever requests: read-only calendar events. */
|
|
354
371
|
declare const GOOGLE_CALENDAR_READ_SCOPE = "https://www.googleapis.com/auth/calendar.events.readonly";
|
|
355
372
|
/** Resolve the checked-in calendar block into one controller-safe env payload. */
|
|
356
373
|
declare function calendarServiceConfig(cfg: LoadedProjectConfig, env: string): CalendarServiceConfig;
|
|
@@ -434,14 +451,17 @@ declare function initProject(options: InitOptions): void;
|
|
|
434
451
|
* (mode 0600, gitignored) and, when requested, `.dev.vars`.
|
|
435
452
|
*
|
|
436
453
|
* The developer token comes from (in order) `options.token`, `$ODLA_DEV_TOKEN`,
|
|
437
|
-
* the cached `.odla` token, or a fresh device handshake — which
|
|
438
|
-
* code
|
|
454
|
+
* the cached `.odla` token, or a fresh email-bound device handshake — which
|
|
455
|
+
* prints a user code for the same signed-in account to review and, in
|
|
456
|
+
* interactive terminals, auto-opens the browser
|
|
439
457
|
* (`open: true`/`false` forces/suppresses it). Network error bodies pass through
|
|
440
458
|
* `redactSecrets` before display.
|
|
441
459
|
*
|
|
442
460
|
* @param options.dryRun Print the resolved plan and return before any network call/write.
|
|
443
461
|
* @param options.rotateKeys Rotate db keys and o11y tokens.
|
|
444
462
|
* @param options.rotateO11yToken Rotate only the o11y token.
|
|
463
|
+
* @param options.email Existing odla account email for a fresh handshake;
|
|
464
|
+
* this is an identity hint, never a password or session credential.
|
|
445
465
|
* @param options.pushSecrets Preflight Wrangler, then push each env's configured
|
|
446
466
|
* Worker secrets immediately after credential provisioning.
|
|
447
467
|
* @param options.writeDevVars `true`/a path writes `.dev.vars`; `writeCredentials: false` skips the creds file.
|
|
@@ -499,6 +519,8 @@ interface SecretsSetOptions {
|
|
|
499
519
|
yes?: boolean;
|
|
500
520
|
/** Developer token override; defaults to $ODLA_DEV_TOKEN, the cached token, or a device handshake. */
|
|
501
521
|
token?: string;
|
|
522
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
523
|
+
email?: string;
|
|
502
524
|
open?: boolean;
|
|
503
525
|
interactive?: boolean;
|
|
504
526
|
openApprovalUrl?: (url: string) => Promise<void>;
|
package/dist/index.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write
|
|
|
30
30
|
interface ScopedPlatformTokenOptions {
|
|
31
31
|
platform: string;
|
|
32
32
|
scope: ScopedPlatformScope;
|
|
33
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
34
|
+
email?: string;
|
|
33
35
|
open?: boolean;
|
|
34
36
|
fetch?: typeof fetch;
|
|
35
37
|
stdout?: Pick<typeof console, "log">;
|
|
@@ -59,6 +61,8 @@ interface AdminAiOptions {
|
|
|
59
61
|
maxCallsPerRun?: number;
|
|
60
62
|
platform?: string;
|
|
61
63
|
token?: string;
|
|
64
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
65
|
+
email?: string;
|
|
62
66
|
json?: boolean;
|
|
63
67
|
open?: boolean;
|
|
64
68
|
fetch?: typeof fetch;
|
|
@@ -91,16 +95,17 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
|
|
|
91
95
|
/** Stable, machine-readable division of work between the CLI, coding agent,
|
|
92
96
|
* human operator, and Studio. Printed by `odla-ai capabilities --json`. */
|
|
93
97
|
declare const CAPABILITIES: {
|
|
94
|
-
readonly cli: readonly ["register the app and enable configured services per environment", "issue, persist, and explicitly rotate configured service credentials", "write local Worker values and push deployed Worker secrets through Wrangler stdin", "store tenant-vault secrets (including the Clerk webhook secret and reserved Clerk secret key) write-only from stdin or an env var", "push db schema/rules and configure platform AI, auth, and deployment links", "apply read-only Google calendar mirror and public booking-page config, then drive state-bound consent, status, discovery, resync, and disconnect flows", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys", "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"];
|
|
98
|
+
readonly cli: readonly ["start an email-bound device request without accepting a password or user session token", "register the app and enable configured services per environment", "issue, persist, and explicitly rotate configured service credentials", "write local Worker values and push deployed Worker secrets through Wrangler stdin", "store tenant-vault secrets (including the Clerk webhook secret and reserved Clerk secret key) write-only from stdin or an env var", "push db schema/rules and configure platform AI, auth, and deployment links", "apply read-only Google calendar mirror and public booking-page config, then drive state-bound consent, status, discovery, resync, and disconnect flows", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys", "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"];
|
|
95
99
|
readonly agent: readonly ["install and import the selected odla SDKs", "wrap the Worker with withObservability and choose useful telemetry", "make application-specific schema, rules, auth, UI, and migration decisions", "wire @odla-ai/calendar into trusted Worker code and keep the app admin key out of browsers"];
|
|
96
|
-
readonly human: readonly ["
|
|
97
|
-
readonly studio: readonly ["view telemetry and environment state", "review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens", "perform manual credential recovery when the CLI's local shown-once copy is unavailable", "configure system AI purposes and view app/environment/run-attributed usage", "connect/revoke GitHub security sources and inspect ref-to-SHA jobs, routes, retention, coverage, and normalized reports"];
|
|
100
|
+
readonly human: readonly ["provide the existing odla account email, then sign in and explicitly review/approve the exact device code", "review mirrored calendar/attendee disclosure and complete the server-issued Google consent flow", "consent to production changes with --yes", "request destructive credential rotation explicitly", "review application semantics, security findings, releases, and merges", "approve redacted-source disclosure before hosted security reasoning", "approve GitHub App repository access separately from redacted-snippet disclosure"];
|
|
101
|
+
readonly studio: readonly ["view telemetry and environment state", "let signed-in users inventory/revoke their own agent grants and admins audit/global-revoke them", "review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens", "perform manual credential recovery when the CLI's local shown-once copy is unavailable", "configure system AI purposes and view app/environment/run-attributed usage", "connect/revoke GitHub security sources and inspect ref-to-SHA jobs, routes, retention, coverage, and normalized reports"];
|
|
98
102
|
};
|
|
99
103
|
type Output = Pick<typeof console, "log">;
|
|
100
104
|
/** Print the stable responsibility boundary for humans or agent tooling. */
|
|
101
105
|
declare function printCapabilities(json?: boolean, out?: Output): void;
|
|
102
106
|
|
|
103
107
|
declare const CALENDAR_STATES: readonly ["not_connected", "authorizing", "needs_sync", "initial_sync", "healthy", "degraded", "disconnected", "failed"];
|
|
108
|
+
/** Connection lifecycle reported by the registry; mirrors the platform's calendar states. */
|
|
104
109
|
type CalendarConnectionState = (typeof CALENDAR_STATES)[number];
|
|
105
110
|
/** Owner-visible, secret-free calendar connection and sync health. */
|
|
106
111
|
interface CalendarStatus {
|
|
@@ -136,10 +141,15 @@ interface AvailableGoogleCalendar {
|
|
|
136
141
|
accessRole?: "freeBusyReader" | "reader" | "writer" | "owner";
|
|
137
142
|
}
|
|
138
143
|
|
|
144
|
+
/** Shared inputs for the calendar lifecycle commands (status, connect,
|
|
145
|
+
* calendars, resync, disconnect): the project config path and env, plus
|
|
146
|
+
* injectable token, output, browser, clock, and polling hooks so agents and
|
|
147
|
+
* tests can drive the flow deterministically. */
|
|
139
148
|
interface CalendarLifecycleOptions {
|
|
140
|
-
configPath: string;
|
|
141
|
-
env?: string;
|
|
142
|
-
token?: string;
|
|
149
|
+
/** Path to the checked-in odla project config. */ configPath: string;
|
|
150
|
+
/** Configured environment; defaults to dev when present. */ env?: string;
|
|
151
|
+
/** Existing developer-token override. */ token?: string;
|
|
152
|
+
/** Existing odla account email used only for a fresh handshake. */ email?: string;
|
|
143
153
|
open?: boolean;
|
|
144
154
|
interactive?: boolean;
|
|
145
155
|
yes?: boolean;
|
|
@@ -206,6 +216,8 @@ interface GoogleCalendarConfig {
|
|
|
206
216
|
/** Store normalized attendee addresses, or only SHA-256 match keys. */
|
|
207
217
|
attendeePolicy?: "full" | "hashed";
|
|
208
218
|
}
|
|
219
|
+
/** The `calendar` block of `odla.config.mjs` — the Google read-mirror
|
|
220
|
+
* settings; valid only alongside the db service. */
|
|
209
221
|
interface CalendarConfig {
|
|
210
222
|
google: GoogleCalendarConfig;
|
|
211
223
|
}
|
|
@@ -309,6 +321,8 @@ interface ProvisionOptions {
|
|
|
309
321
|
writeCredentials?: boolean;
|
|
310
322
|
writeDevVars?: string | boolean;
|
|
311
323
|
token?: string;
|
|
324
|
+
/** Existing odla account email used only when a fresh device handshake is required. */
|
|
325
|
+
email?: string;
|
|
312
326
|
/** true forces browser launch, false disables it, undefined auto-opens only for interactive terminals. */
|
|
313
327
|
open?: boolean;
|
|
314
328
|
/** Test/embedding override for terminal interactivity. Defaults to stdin/stdout TTY detection. */
|
|
@@ -344,6 +358,8 @@ interface SmokeOptions {
|
|
|
344
358
|
env?: string;
|
|
345
359
|
/** Developer-token override used only for owner-visible calendar health. */
|
|
346
360
|
token?: string;
|
|
361
|
+
/** Existing odla account email used only when a fresh device handshake is required. */
|
|
362
|
+
email?: string;
|
|
347
363
|
open?: boolean;
|
|
348
364
|
interactive?: boolean;
|
|
349
365
|
openApprovalUrl?: (url: string) => Promise<void>;
|
|
@@ -351,6 +367,7 @@ interface SmokeOptions {
|
|
|
351
367
|
stdout?: Pick<typeof console, "log" | "error">;
|
|
352
368
|
}
|
|
353
369
|
|
|
370
|
+
/** The only Google OAuth scope the platform ever requests: read-only calendar events. */
|
|
354
371
|
declare const GOOGLE_CALENDAR_READ_SCOPE = "https://www.googleapis.com/auth/calendar.events.readonly";
|
|
355
372
|
/** Resolve the checked-in calendar block into one controller-safe env payload. */
|
|
356
373
|
declare function calendarServiceConfig(cfg: LoadedProjectConfig, env: string): CalendarServiceConfig;
|
|
@@ -434,14 +451,17 @@ declare function initProject(options: InitOptions): void;
|
|
|
434
451
|
* (mode 0600, gitignored) and, when requested, `.dev.vars`.
|
|
435
452
|
*
|
|
436
453
|
* The developer token comes from (in order) `options.token`, `$ODLA_DEV_TOKEN`,
|
|
437
|
-
* the cached `.odla` token, or a fresh device handshake — which
|
|
438
|
-
* code
|
|
454
|
+
* the cached `.odla` token, or a fresh email-bound device handshake — which
|
|
455
|
+
* prints a user code for the same signed-in account to review and, in
|
|
456
|
+
* interactive terminals, auto-opens the browser
|
|
439
457
|
* (`open: true`/`false` forces/suppresses it). Network error bodies pass through
|
|
440
458
|
* `redactSecrets` before display.
|
|
441
459
|
*
|
|
442
460
|
* @param options.dryRun Print the resolved plan and return before any network call/write.
|
|
443
461
|
* @param options.rotateKeys Rotate db keys and o11y tokens.
|
|
444
462
|
* @param options.rotateO11yToken Rotate only the o11y token.
|
|
463
|
+
* @param options.email Existing odla account email for a fresh handshake;
|
|
464
|
+
* this is an identity hint, never a password or session credential.
|
|
445
465
|
* @param options.pushSecrets Preflight Wrangler, then push each env's configured
|
|
446
466
|
* Worker secrets immediately after credential provisioning.
|
|
447
467
|
* @param options.writeDevVars `true`/a path writes `.dev.vars`; `writeCredentials: false` skips the creds file.
|
|
@@ -499,6 +519,8 @@ interface SecretsSetOptions {
|
|
|
499
519
|
yes?: boolean;
|
|
500
520
|
/** Developer token override; defaults to $ODLA_DEV_TOKEN, the cached token, or a device handshake. */
|
|
501
521
|
token?: string;
|
|
522
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
523
|
+
email?: string;
|
|
502
524
|
open?: boolean;
|
|
503
525
|
interactive?: boolean;
|
|
504
526
|
openApprovalUrl?: (url: string) => Promise<void>;
|
package/dist/index.js
CHANGED
package/llms.txt
CHANGED
|
@@ -31,13 +31,17 @@ For a project you keep working in, install it as a dev dependency so the
|
|
|
31
31
|
shorter `npx odla-ai` form works and the version is pinned by your lockfile:
|
|
32
32
|
|
|
33
33
|
```bash
|
|
34
|
-
npm view @odla-ai/cli@0.10.
|
|
35
|
-
npm i -D --save-exact @odla-ai/cli@0.10.
|
|
34
|
+
npm view @odla-ai/cli@0.10.1 version
|
|
35
|
+
npm i -D --save-exact @odla-ai/cli@0.10.1
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
## Prerequisites
|
|
39
39
|
|
|
40
40
|
- Node.js 20 or newer (`node --version`).
|
|
41
|
+
- An existing odla account that has signed in at least once. For any command
|
|
42
|
+
that may need a fresh device grant, pass `--email <account>` or set
|
|
43
|
+
`ODLA_USER_EMAIL`. This value identifies who may review the request; it is not
|
|
44
|
+
a password or session credential, and an agent must never ask for either.
|
|
41
45
|
- odla apps usually deploy as Cloudflare Workers. If you have never used
|
|
42
46
|
Cloudflare:
|
|
43
47
|
1. Create a free account at <https://dash.cloudflare.com/sign-up>.
|
|
@@ -63,7 +67,7 @@ npx odla-ai calendar disconnect --env dev --yes
|
|
|
63
67
|
npx odla-ai capabilities --json
|
|
64
68
|
# install SDKs, write the Worker, and create wrangler.jsonc before secret push
|
|
65
69
|
npx odla-ai provision --dry-run
|
|
66
|
-
npx odla-ai provision --write-dev-vars --push-secrets
|
|
70
|
+
npx odla-ai provision --email owner@example.com --write-dev-vars --push-secrets
|
|
67
71
|
npx odla-ai smoke --env dev
|
|
68
72
|
npx odla-ai secrets push --env dev
|
|
69
73
|
npx odla-ai secrets set clerk_webhook_secret --env dev --stdin
|
|
@@ -75,7 +79,7 @@ npx @odla-ai/cli security sources --env dev
|
|
|
75
79
|
npx @odla-ai/cli security run --source <source-id> --ref main --env dev --plan-digest <digest-from-security-plan> --ack-redacted-source
|
|
76
80
|
npx @odla-ai/cli security status <job-id>
|
|
77
81
|
npx @odla-ai/cli security report <job-id>
|
|
78
|
-
npx odla-ai admin ai show
|
|
82
|
+
npx odla-ai admin ai show --email owner@example.com
|
|
79
83
|
npx odla-ai admin ai models
|
|
80
84
|
npx odla-ai admin ai set security --discovery-provider anthropic --discovery-model claude-opus-4-8 --validation-provider openai --validation-model gpt-5.5 --enabled
|
|
81
85
|
npx odla-ai admin ai credentials
|
|
@@ -103,8 +107,11 @@ When using `--push-secrets`, create the Worker and its Wrangler config first.
|
|
|
103
107
|
The CLI checks that config and `wrangler whoami` before it issues or rotates a
|
|
104
108
|
shown-once credential.
|
|
105
109
|
|
|
106
|
-
1. Gets an `odla_dev_...` token by device handshake, or reuses
|
|
107
|
-
`ODLA_DEV_TOKEN` / `.odla/dev-token.json`.
|
|
110
|
+
1. Gets an `odla_dev_...` token by email-bound device handshake, or reuses
|
|
111
|
+
`ODLA_DEV_TOKEN` / `.odla/dev-token.json`. A fresh handshake requires
|
|
112
|
+
`--email <account>` or `ODLA_USER_EMAIL`; the matching existing account must
|
|
113
|
+
sign in, review the exact code, and approve it. Opening the URL alone does
|
|
114
|
+
not claim the request.
|
|
108
115
|
In an interactive terminal it opens the approval page in your browser when
|
|
109
116
|
the code is displayed. Pass `--open` to force browser launch from a
|
|
110
117
|
non-interactive shell, or `--no-open` to suppress it. Browser launch is
|
|
@@ -138,6 +145,26 @@ The CLI preflights Wrangler first and persists the replacement before pushing;
|
|
|
138
145
|
if that final push still fails, follow the printed `secrets push --env ...`
|
|
139
146
|
retry. Do not run the rotation flag again.
|
|
140
147
|
|
|
148
|
+
### Device-grant security and recovery
|
|
149
|
+
|
|
150
|
+
The account email sent during a fresh handshake is a non-secret identity hint,
|
|
151
|
+
not proof of identity. Unknown or never-signed-in accounts never produce a
|
|
152
|
+
claimable Studio request, and the public start/poll shape intentionally does not
|
|
153
|
+
reveal whether an account exists. The signed-in matching user must explicitly
|
|
154
|
+
review the exact code before it becomes pending, and only one claimed pending
|
|
155
|
+
or approved-but-uncollected request can be active for that user.
|
|
156
|
+
|
|
157
|
+
Developer grants are tracked by id, owner, label, scopes, creation/expiry,
|
|
158
|
+
last use, and revocation state. The plaintext token is delivered once to the
|
|
159
|
+
polling client and is never available from the inventory. Every signed-in user
|
|
160
|
+
can inspect and revoke their own grants under **Your agent credentials** in
|
|
161
|
+
Studio; platform admins additionally see the global token inventory and
|
|
162
|
+
metadata-only attempt evidence. Future requests with a revoked token fail.
|
|
163
|
+
Deleting
|
|
164
|
+
`.odla/dev-token.json` or `.odla/admin-token.local.json` removes the local copy
|
|
165
|
+
but does not revoke a token already copied elsewhere, so use Studio revocation
|
|
166
|
+
when compromise or accidental approval is possible.
|
|
167
|
+
|
|
141
168
|
`smoke` verifies a provisioned environment from local credentials. It fetches
|
|
142
169
|
the platform public config, checks the configured AI provider, fetches the live
|
|
143
170
|
odla-db schema with the tenant key, compares expected schema entities, and runs
|
|
@@ -431,7 +458,7 @@ If schema is present and rules are omitted, `defaultRules: "deny"` generates
|
|
|
431
458
|
deny-all rules for every schema entity. That is the safe default for Workers
|
|
432
459
|
that mediate reads and writes with an app key.
|
|
433
460
|
|
|
434
|
-
## API reference (generated from dist/index.d.ts, v0.10.
|
|
461
|
+
## API reference (generated from dist/index.d.ts, v0.10.1)
|
|
435
462
|
|
|
436
463
|
```ts
|
|
437
464
|
import { SecurityReport, PlatformSecurityRun } from '@odla-ai/security';
|
|
@@ -466,6 +493,8 @@ type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write
|
|
|
466
493
|
interface ScopedPlatformTokenOptions {
|
|
467
494
|
platform: string;
|
|
468
495
|
scope: ScopedPlatformScope;
|
|
496
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
497
|
+
email?: string;
|
|
469
498
|
open?: boolean;
|
|
470
499
|
fetch?: typeof fetch;
|
|
471
500
|
stdout?: Pick<typeof console, "log">;
|
|
@@ -495,6 +524,8 @@ interface AdminAiOptions {
|
|
|
495
524
|
maxCallsPerRun?: number;
|
|
496
525
|
platform?: string;
|
|
497
526
|
token?: string;
|
|
527
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
528
|
+
email?: string;
|
|
498
529
|
json?: boolean;
|
|
499
530
|
open?: boolean;
|
|
500
531
|
fetch?: typeof fetch;
|
|
@@ -527,16 +558,17 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
|
|
|
527
558
|
/** Stable, machine-readable division of work between the CLI, coding agent,
|
|
528
559
|
* human operator, and Studio. Printed by `odla-ai capabilities --json`. */
|
|
529
560
|
declare const CAPABILITIES: {
|
|
530
|
-
readonly cli: readonly ["register the app and enable configured services per environment", "issue, persist, and explicitly rotate configured service credentials", "write local Worker values and push deployed Worker secrets through Wrangler stdin", "store tenant-vault secrets (including the Clerk webhook secret and reserved Clerk secret key) write-only from stdin or an env var", "push db schema/rules and configure platform AI, auth, and deployment links", "apply read-only Google calendar mirror and public booking-page config, then drive state-bound consent, status, discovery, resync, and disconnect flows", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys", "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"];
|
|
561
|
+
readonly cli: readonly ["start an email-bound device request without accepting a password or user session token", "register the app and enable configured services per environment", "issue, persist, and explicitly rotate configured service credentials", "write local Worker values and push deployed Worker secrets through Wrangler stdin", "store tenant-vault secrets (including the Clerk webhook secret and reserved Clerk secret key) write-only from stdin or an env var", "push db schema/rules and configure platform AI, auth, and deployment links", "apply read-only Google calendar mirror and public booking-page config, then drive state-bound consent, status, discovery, resync, and disconnect flows", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "connect/revoke source-read-only GitHub sources and drive commit-pinned hosted security jobs without PATs or provider keys", "let admins manage system AI policy and credentials, inspect attributed usage, and read immutable admin changes through separate short-lived capability-only approvals"];
|
|
531
562
|
readonly agent: readonly ["install and import the selected odla SDKs", "wrap the Worker with withObservability and choose useful telemetry", "make application-specific schema, rules, auth, UI, and migration decisions", "wire @odla-ai/calendar into trusted Worker code and keep the app admin key out of browsers"];
|
|
532
|
-
readonly human: readonly ["
|
|
533
|
-
readonly studio: readonly ["view telemetry and environment state", "review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens", "perform manual credential recovery when the CLI's local shown-once copy is unavailable", "configure system AI purposes and view app/environment/run-attributed usage", "connect/revoke GitHub security sources and inspect ref-to-SHA jobs, routes, retention, coverage, and normalized reports"];
|
|
563
|
+
readonly human: readonly ["provide the existing odla account email, then sign in and explicitly review/approve the exact device code", "review mirrored calendar/attendee disclosure and complete the server-issued Google consent flow", "consent to production changes with --yes", "request destructive credential rotation explicitly", "review application semantics, security findings, releases, and merges", "approve redacted-source disclosure before hosted security reasoning", "approve GitHub App repository access separately from redacted-snippet disclosure"];
|
|
564
|
+
readonly studio: readonly ["view telemetry and environment state", "let signed-in users inventory/revoke their own agent grants and admins audit/global-revoke them", "review calendar connection, granted read scope, selected calendars, and sync health without exposing provider tokens", "perform manual credential recovery when the CLI's local shown-once copy is unavailable", "configure system AI purposes and view app/environment/run-attributed usage", "connect/revoke GitHub security sources and inspect ref-to-SHA jobs, routes, retention, coverage, and normalized reports"];
|
|
534
565
|
};
|
|
535
566
|
type Output = Pick<typeof console, "log">;
|
|
536
567
|
/** Print the stable responsibility boundary for humans or agent tooling. */
|
|
537
568
|
declare function printCapabilities(json?: boolean, out?: Output): void;
|
|
538
569
|
|
|
539
570
|
declare const CALENDAR_STATES: readonly ["not_connected", "authorizing", "needs_sync", "initial_sync", "healthy", "degraded", "disconnected", "failed"];
|
|
571
|
+
/** Connection lifecycle reported by the registry; mirrors the platform's calendar states. */
|
|
540
572
|
type CalendarConnectionState = (typeof CALENDAR_STATES)[number];
|
|
541
573
|
/** Owner-visible, secret-free calendar connection and sync health. */
|
|
542
574
|
interface CalendarStatus {
|
|
@@ -572,10 +604,15 @@ interface AvailableGoogleCalendar {
|
|
|
572
604
|
accessRole?: "freeBusyReader" | "reader" | "writer" | "owner";
|
|
573
605
|
}
|
|
574
606
|
|
|
607
|
+
/** Shared inputs for the calendar lifecycle commands (status, connect,
|
|
608
|
+
* calendars, resync, disconnect): the project config path and env, plus
|
|
609
|
+
* injectable token, output, browser, clock, and polling hooks so agents and
|
|
610
|
+
* tests can drive the flow deterministically. */
|
|
575
611
|
interface CalendarLifecycleOptions {
|
|
576
|
-
configPath: string;
|
|
577
|
-
env?: string;
|
|
578
|
-
token?: string;
|
|
612
|
+
/** Path to the checked-in odla project config. */ configPath: string;
|
|
613
|
+
/** Configured environment; defaults to dev when present. */ env?: string;
|
|
614
|
+
/** Existing developer-token override. */ token?: string;
|
|
615
|
+
/** Existing odla account email used only for a fresh handshake. */ email?: string;
|
|
579
616
|
open?: boolean;
|
|
580
617
|
interactive?: boolean;
|
|
581
618
|
yes?: boolean;
|
|
@@ -642,6 +679,8 @@ interface GoogleCalendarConfig {
|
|
|
642
679
|
/** Store normalized attendee addresses, or only SHA-256 match keys. */
|
|
643
680
|
attendeePolicy?: "full" | "hashed";
|
|
644
681
|
}
|
|
682
|
+
/** The `calendar` block of `odla.config.mjs` — the Google read-mirror
|
|
683
|
+
* settings; valid only alongside the db service. */
|
|
645
684
|
interface CalendarConfig {
|
|
646
685
|
google: GoogleCalendarConfig;
|
|
647
686
|
}
|
|
@@ -745,6 +784,8 @@ interface ProvisionOptions {
|
|
|
745
784
|
writeCredentials?: boolean;
|
|
746
785
|
writeDevVars?: string | boolean;
|
|
747
786
|
token?: string;
|
|
787
|
+
/** Existing odla account email used only when a fresh device handshake is required. */
|
|
788
|
+
email?: string;
|
|
748
789
|
/** true forces browser launch, false disables it, undefined auto-opens only for interactive terminals. */
|
|
749
790
|
open?: boolean;
|
|
750
791
|
/** Test/embedding override for terminal interactivity. Defaults to stdin/stdout TTY detection. */
|
|
@@ -780,6 +821,8 @@ interface SmokeOptions {
|
|
|
780
821
|
env?: string;
|
|
781
822
|
/** Developer-token override used only for owner-visible calendar health. */
|
|
782
823
|
token?: string;
|
|
824
|
+
/** Existing odla account email used only when a fresh device handshake is required. */
|
|
825
|
+
email?: string;
|
|
783
826
|
open?: boolean;
|
|
784
827
|
interactive?: boolean;
|
|
785
828
|
openApprovalUrl?: (url: string) => Promise<void>;
|
|
@@ -787,6 +830,7 @@ interface SmokeOptions {
|
|
|
787
830
|
stdout?: Pick<typeof console, "log" | "error">;
|
|
788
831
|
}
|
|
789
832
|
|
|
833
|
+
/** The only Google OAuth scope the platform ever requests: read-only calendar events. */
|
|
790
834
|
declare const GOOGLE_CALENDAR_READ_SCOPE = "https://www.googleapis.com/auth/calendar.events.readonly";
|
|
791
835
|
/** Resolve the checked-in calendar block into one controller-safe env payload. */
|
|
792
836
|
declare function calendarServiceConfig(cfg: LoadedProjectConfig, env: string): CalendarServiceConfig;
|
|
@@ -870,14 +914,17 @@ declare function initProject(options: InitOptions): void;
|
|
|
870
914
|
* (mode 0600, gitignored) and, when requested, `.dev.vars`.
|
|
871
915
|
*
|
|
872
916
|
* The developer token comes from (in order) `options.token`, `$ODLA_DEV_TOKEN`,
|
|
873
|
-
* the cached `.odla` token, or a fresh device handshake — which
|
|
874
|
-
* code
|
|
917
|
+
* the cached `.odla` token, or a fresh email-bound device handshake — which
|
|
918
|
+
* prints a user code for the same signed-in account to review and, in
|
|
919
|
+
* interactive terminals, auto-opens the browser
|
|
875
920
|
* (`open: true`/`false` forces/suppresses it). Network error bodies pass through
|
|
876
921
|
* `redactSecrets` before display.
|
|
877
922
|
*
|
|
878
923
|
* @param options.dryRun Print the resolved plan and return before any network call/write.
|
|
879
924
|
* @param options.rotateKeys Rotate db keys and o11y tokens.
|
|
880
925
|
* @param options.rotateO11yToken Rotate only the o11y token.
|
|
926
|
+
* @param options.email Existing odla account email for a fresh handshake;
|
|
927
|
+
* this is an identity hint, never a password or session credential.
|
|
881
928
|
* @param options.pushSecrets Preflight Wrangler, then push each env's configured
|
|
882
929
|
* Worker secrets immediately after credential provisioning.
|
|
883
930
|
* @param options.writeDevVars `true`/a path writes `.dev.vars`; `writeCredentials: false` skips the creds file.
|
|
@@ -935,6 +982,8 @@ interface SecretsSetOptions {
|
|
|
935
982
|
yes?: boolean;
|
|
936
983
|
/** Developer token override; defaults to $ODLA_DEV_TOKEN, the cached token, or a device handshake. */
|
|
937
984
|
token?: string;
|
|
985
|
+
/** Existing odla account email used only when a fresh handshake is required. */
|
|
986
|
+
email?: string;
|
|
938
987
|
open?: boolean;
|
|
939
988
|
interactive?: boolean;
|
|
940
989
|
openApprovalUrl?: (url: string) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odla-ai/cli",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.1",
|
|
4
4
|
"description": "Agent-operable CLI for odla provisioning, calendar consent and sync lifecycle, System AI administration, Worker secrets, security jobs, and smoke checks.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://odla.ai/docs/packages/cli",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"dependencies": {
|
|
62
62
|
"@odla-ai/ai": "^0.3.3",
|
|
63
63
|
"@odla-ai/apps": "^0.8.0",
|
|
64
|
-
"@odla-ai/db": "^0.6.
|
|
64
|
+
"@odla-ai/db": "^0.6.3",
|
|
65
65
|
"@odla-ai/security": "^0.2.2"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
package/skills/odla/SKILL.md
CHANGED
|
@@ -37,6 +37,9 @@ State which path you're taking and what you'll build in one line; get a nod.
|
|
|
37
37
|
`.odla/credentials.local.json`, or `.odla/dev-token.json` — use `ls -l` to
|
|
38
38
|
confirm they exist (and are `0600`). The only value a human ever pastes is a
|
|
39
39
|
Clerk **publishable** key (`pk_…`) — public by design.
|
|
40
|
+
A fresh odla device request also needs the existing account email via
|
|
41
|
+
`--email` or `ODLA_USER_EMAIL`; email is a non-secret identifier. Never ask
|
|
42
|
+
for an odla password, Clerk token, or browser session.
|
|
40
43
|
2. **Dev before prod.** Keep `envs: ["dev"]` and verify the tenant
|
|
41
44
|
(`<appId>--dev`) before any write or deploy. Add `prod` only at the explicit
|
|
42
45
|
production checkpoint. The first prod
|
|
@@ -66,8 +69,10 @@ guessing which platform/credential steps need manual work. Then:
|
|
|
66
69
|
`withObservability`. The CLI will refuse secret delivery until the Wrangler
|
|
67
70
|
target exists.
|
|
68
71
|
3. **provision** ⏸ —
|
|
69
|
-
`npx @odla-ai/cli provision --
|
|
70
|
-
|
|
72
|
+
`npx @odla-ai/cli provision --email <existing-odla-account>
|
|
73
|
+
--write-dev-vars --push-secrets`. A device code prints; that same account
|
|
74
|
+
signs in, reviews the exact code, and approves it at https://odla.ai/studio.
|
|
75
|
+
Opening the link alone is inert. It creates the app,
|
|
71
76
|
enables services, issues or reuses configured credentials (db key + o11y
|
|
72
77
|
ingest token when enabled), pushes schema + rules, writes `.dev.vars`, and
|
|
73
78
|
transfers Worker secrets through Wrangler stdin. With calendar enabled it
|
|
@@ -37,11 +37,13 @@ service source or online documentation is not setup context.
|
|
|
37
37
|
## 3. Provision ⏸ device-code approval
|
|
38
38
|
|
|
39
39
|
```
|
|
40
|
-
npx @odla-ai/cli provision --write-dev-vars --push-secrets
|
|
40
|
+
npx @odla-ai/cli provision --email <existing-odla-account> --write-dev-vars --push-secrets
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
The email is an account identifier, never a password or session credential.
|
|
44
|
+
Prints a short device code and a link. ⏸ That same account opens the link, signs
|
|
45
|
+
in, explicitly reviews the exact code, and approves it — loading the URL alone
|
|
46
|
+
does not claim access, and no secret passes through the chat. Provision then:
|
|
45
47
|
creates the app, enables its services, issues or reuses the db key (and the
|
|
46
48
|
o11y ingest token when o11y is enabled), pushes schema + rules, writes
|
|
47
49
|
`.dev.vars`, and transfers configured Worker secrets through Wrangler stdin.
|
|
@@ -38,6 +38,9 @@ installed skill at `../odla/SKILL.md` instead.
|
|
|
38
38
|
3. Never print, paste, or commit a secret. Never `cat` .dev.vars,
|
|
39
39
|
.odla/credentials.local.json, or .odla/dev-token.json. Read
|
|
40
40
|
references/secrets-map.md BEFORE any command that touches a credential.
|
|
41
|
+
A fresh device request requires the existing odla account email via
|
|
42
|
+
`--email` or `ODLA_USER_EMAIL`; email is a non-secret identifier. Never ask
|
|
43
|
+
for an odla password, Clerk token, or browser session.
|
|
41
44
|
4. Never `git add -A` without reading `git status` first.
|
|
42
45
|
5. Never widen a db rule to silence a 403 — default-deny is the design.
|
|
43
46
|
Any rules change is a human checkpoint.
|
|
@@ -4,14 +4,15 @@ Goal: the app registered on the platform, a dev odla-db tenant with
|
|
|
4
4
|
schema + deny-all rules, the db key in the dev worker, and first
|
|
5
5
|
`/api/*` routes live in dev.
|
|
6
6
|
|
|
7
|
-
Human obligation:
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
Human obligation: provide the existing odla account email (not a password or
|
|
8
|
+
session credential), sign in at https://odla.ai/studio, explicitly review the
|
|
9
|
+
exact handshake code, and approve it. The provision run prints the code and
|
|
10
|
+
opens the review page in interactive terminals; loading it alone is inert.
|
|
10
11
|
|
|
11
12
|
## Steps
|
|
12
13
|
|
|
13
|
-
1. Require `npm view @odla-ai/cli@0.10.
|
|
14
|
-
`npm i -D --save-exact @odla-ai/cli@0.10.
|
|
14
|
+
1. Require `npm view @odla-ai/cli@0.10.1 version` to succeed, then run
|
|
15
|
+
`npm i -D --save-exact @odla-ai/cli@0.10.1` and `npm i @odla-ai/db`.
|
|
15
16
|
2. `npx @odla-ai/cli init --app-id <id> --name "<Name>" --env dev --services db`
|
|
16
17
|
Review `odla.config.mjs`. Keep `envs: ["dev"]` — prod is Phase 5. Set
|
|
17
18
|
`links.dev` to the URL the Phase 1 `wrangler deploy` **actually printed** —
|
|
@@ -32,7 +33,8 @@ in the browser in interactive terminals).
|
|
|
32
33
|
directly. Loosening a rule is a human checkpoint.
|
|
33
34
|
5. `npx @odla-ai/cli doctor` until clean.
|
|
34
35
|
6. `npx @odla-ai/cli provision --dry-run` — show the plan to the human.
|
|
35
|
-
7. `npx @odla-ai/cli provision --
|
|
36
|
+
7. `npx @odla-ai/cli provision --email <existing-odla-account>
|
|
37
|
+
--write-dev-vars --push-secrets` — handshake,
|
|
36
38
|
app registration, dev db key, schema + rules push; writes
|
|
37
39
|
`.odla/credentials.local.json` (0600) and `.dev.vars`, then pipes configured
|
|
38
40
|
Worker secrets to Wrangler over stdin. Both local files are gitignored by
|
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
| Clerk webhook secret (`whsec_…`) | tenant vault (`clerk_webhook_secret`) | only for auth mode "full"; piped with `secrets set clerk_webhook_secret --env <env> --stdin`, or entered in Studio; never wrangler, never chat |
|
|
9
9
|
| Clerk secret key (`sk_test_`/`sk_live_`) | not needed for this journey | if a later feature needs user resolution/invites, pipe it with `secrets set-clerk-key --env <env>` (reserved `$clerk_secret`, write-only); never chat |
|
|
10
10
|
| LLM provider key | tenant vault | env var in the HUMAN's shell for one provision run; never wrangler vars, never git, never chat |
|
|
11
|
+
| `ODLA_USER_EMAIL` / `--email` | process environment or one command invocation | non-secret identifier for the existing signed-in odla account allowed to review a fresh request; never substitute a password or session token |
|
|
11
12
|
| `odla_sk_…` (tenant db key) | wrangler secret `ODLA_API_KEY` + `.odla/credentials.local.json` (0600) + `.dev.vars` | present when db is enabled; move it only with the pipeline below |
|
|
12
|
-
| `odla_dev_…` (developer token) | `.odla/dev-token.json` (0600) | ~24h lifetime, provision-time only; never deployed |
|
|
13
|
+
| `odla_dev_…` (developer token) | `.odla/dev-token.json` (0600) | tracked/revocable, ~24h lifetime, provision-time only; never deployed; deleting this cache does not revoke a copied token |
|
|
13
14
|
| scoped `odla_dev_…` (admin-approved platform capability) | `.odla/admin-token.local.json` (0600) | separate policy/credential/usage/self-audit scope, ~15m lifetime, denied on owner routes, never deployed |
|
|
14
15
|
| `o11y_…` (o11y ingest token) | wrangler secret `ODLA_O11Y_TOKEN` + `.odla/credentials.local.json` (0600) + `.dev.vars` | only if the app enables o11y; provision issues/reuses it and moves it alongside the db key; never a var, never chat |
|
|
15
16
|
| `ODLA_ENDPOINT` / `ODLA_TENANT` / `ODLA_PLATFORM` / `ODLA_APP_ID` / `ODLA_ENV` | wrangler `vars` | not secrets; keep them set in every env block |
|
|
@@ -30,7 +30,9 @@ prints what it verified against.
|
|
|
30
30
|
Cause: the `odla_dev_…` token expired (~24h) or the handshake was never
|
|
31
31
|
approved.
|
|
32
32
|
Fix: re-run `npx @odla-ai/cli provision` — it starts a fresh handshake; the
|
|
33
|
-
|
|
33
|
+
matching existing account must be supplied with `--email` or
|
|
34
|
+
`ODLA_USER_EMAIL`, then signs in, reviews, and approves the exact code at the
|
|
35
|
+
printed URL. Never ask for a password or session token. Use `--no-open` in
|
|
34
36
|
non-interactive shells if the browser launch misbehaves.
|
|
35
37
|
|
|
36
38
|
## `smoke` fails: missing credentials
|
|
@@ -29,9 +29,13 @@ GET https://odla.ai/o11y/<appId>/<endpoint>?env=prod
|
|
|
29
29
|
Authorization: Bearer <developer-token>
|
|
30
30
|
```
|
|
31
31
|
|
|
32
|
-
Get `<developer-token>` from the device handshake
|
|
33
|
-
|
|
34
|
-
`
|
|
32
|
+
Get `<developer-token>` from `@odla-ai/cli` or the device handshake: start with
|
|
33
|
+
`POST https://odla.ai/handshake` and
|
|
34
|
+
`{"email":"<existing-odla-account>","label":"o11y debugger"}`, show the returned
|
|
35
|
+
verification URL, then poll `POST /handshake/poll`. Email is a non-secret
|
|
36
|
+
identifier; never ask for a password or session token. The matching account
|
|
37
|
+
must sign in and explicitly review and approve the exact code. `env` is `prod`
|
|
38
|
+
(default) or `dev`. If a read returns `{"error":"ae_not_configured"}` (501), the app's metrics
|
|
35
39
|
reads aren't turned on yet — errors/traces still work; say so and fall back to them.
|
|
36
40
|
|
|
37
41
|
## Endpoints
|