@odla-ai/cli 0.10.0 → 0.10.2
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 +35 -8
- package/REQUIREMENTS.md +20 -2
- 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/package.json +7 -9
- package/skills/odla/SKILL.md +11 -4
- package/skills/odla/references/build.md +11 -8
- package/skills/odla/references/sdks.md +6 -5
- package/skills/odla-migrate/SKILL.md +6 -2
- package/skills/odla-migrate/references/phase-2-db.md +12 -9
- package/skills/odla-migrate/references/phase-2b-calendar.md +2 -2
- package/skills/odla-migrate/references/phase-4-ai.md +4 -3
- package/skills/odla-migrate/references/phase-5-cutover.md +2 -2
- package/skills/odla-migrate/references/secrets-map.md +2 -1
- package/skills/odla-migrate/references/troubleshooting.md +6 -4
- package/skills/odla-o11y-debug/SKILL.md +7 -3
- package/dist/chunk-WDKBW4BE.js.map +0 -1
- package/llms.txt +0 -1221
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@odla-ai/cli",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
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",
|
|
@@ -27,8 +27,7 @@
|
|
|
27
27
|
"dist",
|
|
28
28
|
"skills",
|
|
29
29
|
"README.md",
|
|
30
|
-
"REQUIREMENTS.md"
|
|
31
|
-
"llms.txt"
|
|
30
|
+
"REQUIREMENTS.md"
|
|
32
31
|
],
|
|
33
32
|
"sideEffects": false,
|
|
34
33
|
"engines": {
|
|
@@ -55,14 +54,13 @@
|
|
|
55
54
|
"typecheck": "tsc --noEmit",
|
|
56
55
|
"test": "vitest run",
|
|
57
56
|
"coverage": "vitest run --coverage",
|
|
58
|
-
"
|
|
59
|
-
"prepublishOnly": "npm run build && npm run gen:llms"
|
|
57
|
+
"prepublishOnly": "npm run build"
|
|
60
58
|
},
|
|
61
59
|
"dependencies": {
|
|
62
|
-
"@odla-ai/ai": "^0.
|
|
63
|
-
"@odla-ai/apps": "^0.8.
|
|
64
|
-
"@odla-ai/db": "^0.6.
|
|
65
|
-
"@odla-ai/security": "^0.
|
|
60
|
+
"@odla-ai/ai": "^0.4.0",
|
|
61
|
+
"@odla-ai/apps": "^0.8.1",
|
|
62
|
+
"@odla-ai/db": "^0.6.4",
|
|
63
|
+
"@odla-ai/security": "^0.3.1"
|
|
66
64
|
},
|
|
67
65
|
"devDependencies": {
|
|
68
66
|
"@types/node": "^22.10.0",
|
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
|
|
@@ -119,5 +124,7 @@ code, paste a publishable key, run a command) — and wait for a nod.
|
|
|
119
124
|
- `references/build.md` — the greenfield build, step by step, with the exact
|
|
120
125
|
commands and what to verify at each one.
|
|
121
126
|
- `references/sdks.md` — SDK cheat-sheet (what each does + minimal real usage).
|
|
122
|
-
|
|
123
|
-
|
|
127
|
+
For the full, version-matched API, read the installed package's README and
|
|
128
|
+
exported TypeScript declarations/JSDoc (resolve entry points through its
|
|
129
|
+
`package.json` `exports`). Rendered references are also public at
|
|
130
|
+
`https://odla.ai/docs/packages/<pkg>`.
|
|
@@ -30,18 +30,21 @@ deployed-secret transfer. With o11y, install `@odla-ai/o11y`, add
|
|
|
30
30
|
`"nodejs_compat"` to `compatibility_flags`, and wrap the entrypoint with
|
|
31
31
|
`withObservability`.
|
|
32
32
|
|
|
33
|
-
Each installed package's
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
Each installed package's README and exported TypeScript declarations/JSDoc are
|
|
34
|
+
the version-matched API contract; resolve public entry points through its
|
|
35
|
+
`package.json` `exports`. The npm artifacts contain everything required for
|
|
36
|
+
this flow; private service source or online documentation is not setup context.
|
|
36
37
|
|
|
37
38
|
## 3. Provision ⏸ device-code approval
|
|
38
39
|
|
|
39
40
|
```
|
|
40
|
-
npx @odla-ai/cli provision --write-dev-vars --push-secrets
|
|
41
|
+
npx @odla-ai/cli provision --email <existing-odla-account> --write-dev-vars --push-secrets
|
|
41
42
|
```
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
The email is an account identifier, never a password or session credential.
|
|
45
|
+
Prints a short device code and a link. ⏸ That same account opens the link, signs
|
|
46
|
+
in, explicitly reviews the exact code, and approves it — loading the URL alone
|
|
47
|
+
does not claim access, and no secret passes through the chat. Provision then:
|
|
45
48
|
creates the app, enables its services, issues or reuses the db key (and the
|
|
46
49
|
o11y ingest token when o11y is enabled), pushes schema + rules, writes
|
|
47
50
|
`.dev.vars`, and transfers configured Worker secrets through Wrangler stdin.
|
|
@@ -85,12 +88,12 @@ code. Browser code uses db subscriptions under explicit rules or pure
|
|
|
85
88
|
Install the passive harness and scan before any production secret or deploy:
|
|
86
89
|
|
|
87
90
|
Before installing the exact release, first verify
|
|
88
|
-
`npm view @odla-ai/security@0.
|
|
91
|
+
`npm view @odla-ai/security@0.3.1 version`. An exact-version `E404` means the
|
|
89
92
|
release is unavailable and blocks this preflight; it is not a clean scan and
|
|
90
93
|
does not prove the package name is absent.
|
|
91
94
|
|
|
92
95
|
```
|
|
93
|
-
npm i -D --save-exact @odla-ai/security@0.
|
|
96
|
+
npm i -D --save-exact @odla-ai/security@0.3.1
|
|
94
97
|
npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical
|
|
95
98
|
```
|
|
96
99
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# odla SDK cheat-sheet
|
|
2
2
|
|
|
3
|
-
Install only what the app needs.
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Install only what the app needs. Prefer the installed package's README and
|
|
4
|
+
exported TypeScript declarations/JSDoc over training memory; resolve public
|
|
5
|
+
entry points through its `package.json` `exports`. Rendered references are also
|
|
6
|
+
available at `https://odla.ai/docs/packages/<pkg>`. Minimal real usage follows.
|
|
6
7
|
|
|
7
8
|
## @odla-ai/db — realtime graph database
|
|
8
9
|
|
|
@@ -99,12 +100,12 @@ Run the passive CLI in local/CI development; do not import it into the running
|
|
|
99
100
|
Worker:
|
|
100
101
|
|
|
101
102
|
Before installing the exact release, require
|
|
102
|
-
`npm view @odla-ai/security@0.
|
|
103
|
+
`npm view @odla-ai/security@0.3.1 version` to succeed before installing it. An
|
|
103
104
|
exact-version `E404` means the release is unavailable, not that the preflight
|
|
104
105
|
passed, and does not prove the package name is absent.
|
|
105
106
|
|
|
106
107
|
```
|
|
107
|
-
npm i -D --save-exact @odla-ai/security@0.
|
|
108
|
+
npm i -D --save-exact @odla-ai/security@0.3.1
|
|
108
109
|
npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical
|
|
109
110
|
```
|
|
110
111
|
|
|
@@ -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.
|
|
@@ -118,5 +121,6 @@ On any failure, read references/troubleshooting.md before improvising.
|
|
|
118
121
|
This installed skill and its `references/` directory are the complete migration
|
|
119
122
|
runbook; do not fetch a website or private source repository to reconstruct it.
|
|
120
123
|
Read only the current phase file as directed above. After `npm install`, prefer
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
each installed package's README and exported TypeScript declarations/JSDoc over
|
|
125
|
+
training memory; resolve entry points through its `package.json` `exports`.
|
|
126
|
+
Those artifacts describe the version this project actually uses.
|
|
@@ -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.2 version` to succeed, then run
|
|
15
|
+
`npm i -D --save-exact @odla-ai/cli@0.10.2` 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** —
|
|
@@ -21,7 +22,7 @@ in the browser in interactive terminals).
|
|
|
21
22
|
public-config show where the app runs. (`links.prod` is set the same way at
|
|
22
23
|
Phase 5, from the prod deploy's printed URL.)
|
|
23
24
|
3. STOP before touching schema: read "Porting relational code" in
|
|
24
|
-
`node_modules/@odla-ai/db/
|
|
25
|
+
`node_modules/@odla-ai/db/README.md`. The traps are silent: entity ids
|
|
25
26
|
are not attrs (mirror an id attr), there is no NULL (omit on write,
|
|
26
27
|
re-project on read), lists need explicit `order`, uniques are
|
|
27
28
|
single-attr (derive composite keys), ON CONFLICT maps to `mutationId`
|
|
@@ -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
|
|
@@ -47,8 +49,9 @@ in the browser in interactive terminals).
|
|
|
47
49
|
10. Add `/api/*` routes before the assets fall-through, using
|
|
48
50
|
`init({ appId: env.ODLA_TENANT, adminToken: env.ODLA_API_KEY,
|
|
49
51
|
endpoint: env.ODLA_ENDPOINT })` from `@odla-ai/db`. Read the installed
|
|
50
|
-
package's
|
|
51
|
-
error contracts.
|
|
52
|
+
package's README and exported TypeScript declarations/JSDoc for query,
|
|
53
|
+
transaction, and error contracts. The rendered reference is at
|
|
54
|
+
`https://odla.ai/docs/packages/db` when online.
|
|
52
55
|
11. `wrangler dev` + curl each route; then `npm run deploy:app:dev` and
|
|
53
56
|
curl the workers.dev URL.
|
|
54
57
|
|
|
@@ -9,8 +9,8 @@ server-issued Google consent page. They never paste an OAuth code or token.
|
|
|
9
9
|
|
|
10
10
|
1. Inventory the old behavior. Distinguish a public appointment-page link from
|
|
11
11
|
actual event create/reschedule/cancel APIs. Do not promise more than exists.
|
|
12
|
-
2. Require `npm view @odla-ai/calendar@0.1.
|
|
13
|
-
`npm i --save-exact @odla-ai/calendar@0.1.
|
|
12
|
+
2. Require `npm view @odla-ai/calendar@0.1.1 version` to succeed, then install
|
|
13
|
+
`npm i --save-exact @odla-ai/calendar@0.1.1` as a runtime dependency. An
|
|
14
14
|
exact-version `E404` blocks this phase; do not substitute a git checkout or
|
|
15
15
|
another version. Add `"calendar"` beside
|
|
16
16
|
`"db"` in services and configure:
|
|
@@ -24,9 +24,10 @@ own terminal so you never see the value.
|
|
|
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
|
|
26
26
|
from the vault at call time using only the app's db key. Provider and
|
|
27
|
-
model are switchable in Studio with no redeploy. Read
|
|
28
|
-
`node_modules/@odla-ai/ai/
|
|
29
|
-
|
|
27
|
+
model are switchable in Studio with no redeploy. Read the installed
|
|
28
|
+
`node_modules/@odla-ai/ai/README.md` and exported TypeScript
|
|
29
|
+
declarations/JSDoc for the version-matched API; the rendered reference at
|
|
30
|
+
`https://odla.ai/docs/packages/ai` covers the public platform composition.
|
|
30
31
|
4. Add one `/api/*` route that round-trips the model; deploy dev.
|
|
31
32
|
|
|
32
33
|
## Verification checklist
|
|
@@ -24,10 +24,10 @@ instance, never a second Clerk app per env; final go/no-go at each step.
|
|
|
24
24
|
`secrets push --env prod --yes` only to retry the transfer (see
|
|
25
25
|
references/secrets-map.md).
|
|
26
26
|
3. Build, then run the passive pre-cutover security gate:
|
|
27
|
-
first require `npm view @odla-ai/security@0.
|
|
27
|
+
first require `npm view @odla-ai/security@0.3.1 version` to succeed. An
|
|
28
28
|
exact-version `E404` means the release is unavailable and blocks cutover;
|
|
29
29
|
it is not a clean scan and does not prove the package name is absent. Run
|
|
30
|
-
`npm i -D --save-exact @odla-ai/security@0.
|
|
30
|
+
`npm i -D --save-exact @odla-ai/security@0.3.1` followed by
|
|
31
31
|
`npx odla-security scan . --profile odla --out .odla/security/pre-cutover --fail-on high --fail-on-candidates critical`.
|
|
32
32
|
Review `REPORT.md`; a candidate is a lead, not confirmation, and a baseline
|
|
33
33
|
requires a concrete reason, owner, and expiry.
|
|
@@ -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
|
|
@@ -78,6 +80,6 @@ the printed `secrets push --env ...` retry and do not rotate again.
|
|
|
78
80
|
## Something not covered here
|
|
79
81
|
|
|
80
82
|
Check, in order: `npx @odla-ai/cli doctor` output; this skill's current phase
|
|
81
|
-
and troubleshooting references; then the relevant installed
|
|
82
|
-
|
|
83
|
-
unblock yourself — surface the blocker to the human instead.
|
|
83
|
+
and troubleshooting references; then the relevant installed package README and
|
|
84
|
+
exported TypeScript declarations/JSDoc. Do not improvise around a safety rule
|
|
85
|
+
to unblock yourself — surface the blocker to the human instead.
|
|
@@ -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
|