@odla-ai/cli 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,3 +1,5 @@
1
+ import { SecurityReport, PlatformSecurityRun } from '@odla-ai/security';
2
+
1
3
  /**
2
4
  * Parse CLI arguments and dispatch to the matching command — the entry point
3
5
  * `bin.ts` invokes. `argv` defaults to `process.argv.slice(2)`; the first
@@ -8,7 +10,10 @@
8
10
  * Recognized commands: `version`/`-v`/`--version` and `help`/`-h`/`--help` print
9
11
  * and return; `init` scaffolds a project (requires `--app-id` and `--name`);
10
12
  * `doctor` validates config offline; `capabilities` prints the responsibility
11
- * boundary; `provision` runs the full provision (including optional secret
13
+ * boundary; `admin ai` reads/updates purpose-specific platform AI policies and
14
+ * write-only credentials through a short-lived exact-scope device grant;
15
+ * `security run` performs an explicitly acknowledged, app-attributed hosted
16
+ * reasoning pass; `provision` runs the full provision (including optional secret
12
17
  * rotation, local vars, and deployed secret push); `smoke` checks a live env;
13
18
  * `setup` and `skill install` install the bundled offline runbooks for Claude
14
19
  * Code, Codex, Cursor, Copilot, Gemini, and `AGENTS.md`-aware agents; and
@@ -21,13 +26,62 @@
21
26
  */
22
27
  declare function runCli(argv?: string[]): Promise<void>;
23
28
 
29
+ /** Hosted platform purposes whose provider, model, and budgets an admin may route. */
30
+ declare const SYSTEM_AI_PURPOSES: readonly ["o11y.triage", "security.discovery", "security.validation"];
31
+ /** One catalog-validated, platform-funded System AI purpose. */
32
+ type SystemAiPurpose = (typeof SYSTEM_AI_PURPOSES)[number];
33
+ /** Inputs for one System AI read, policy update, credential-status read, or
34
+ * write-only credential transfer. Provider values may come only from a named
35
+ * environment variable or stdin. */
36
+ interface AdminAiOptions {
37
+ action: "show" | "set" | "credentials" | "credential-set";
38
+ purpose?: string;
39
+ provider?: string;
40
+ model?: string;
41
+ enabled?: boolean;
42
+ maxInputBytes?: number;
43
+ maxOutputTokens?: number;
44
+ maxCallsPerRun?: number;
45
+ platform?: string;
46
+ token?: string;
47
+ json?: boolean;
48
+ open?: boolean;
49
+ fetch?: typeof fetch;
50
+ stdout?: Pick<typeof console, "log">;
51
+ openApprovalUrl?: (url: string) => Promise<void>;
52
+ credentialProvider?: string;
53
+ fromEnv?: string;
54
+ stdin?: boolean;
55
+ readStdin?: () => Promise<string>;
56
+ /** Separate short-lived admin-token cache; never reuses the app developer-token file. */
57
+ tokenFile?: string;
58
+ }
59
+ /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
60
+ interface ScopedPlatformTokenOptions {
61
+ platform: string;
62
+ scope: "platform:ai:read" | "platform:ai:write" | "platform:security:self";
63
+ open?: boolean;
64
+ fetch?: typeof fetch;
65
+ stdout?: Pick<typeof console, "log">;
66
+ openApprovalUrl?: (url: string) => Promise<void>;
67
+ tokenFile?: string;
68
+ }
69
+ /** Obtain/cache one exact platform scope without granting ambient admin. */
70
+ declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
71
+ /** Read or update platform-funded AI routing. Authentication is a short-lived,
72
+ * explicitly scoped device grant; ordinary app developer tokens never become
73
+ * platform admins. Credential writes accept values only from a named env var
74
+ * or stdin, transfer them once, and never place them in argv, output, or the
75
+ * scoped-token cache. */
76
+ declare function adminAi(options: AdminAiOptions): Promise<void>;
77
+
24
78
  /** Stable, machine-readable division of work between the CLI, coding agent,
25
79
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
26
80
  declare const CAPABILITIES: {
27
- 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", "push db schema/rules and configure platform AI, auth, and deployment links", "validate config offline and smoke-test a provisioned db environment"];
81
+ 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", "push db schema/rules and configure platform AI, auth, and deployment links", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "let admins manage system AI routes/credentials through short-lived exact-scope approval"];
28
82
  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"];
29
- readonly human: readonly ["approve the odla device code and one-off third-party logins", "consent to production changes with --yes", "request destructive credential rotation explicitly", "review application semantics, security findings, releases, and merges"];
30
- readonly studio: readonly ["view telemetry and environment state", "perform manual credential recovery when the CLI's local shown-once copy is unavailable"];
83
+ readonly human: readonly ["approve the odla device code and one-off third-party logins", "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"];
84
+ readonly studio: readonly ["view telemetry and environment state", "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"];
31
85
  };
32
86
  type Output = Pick<typeof console, "log">;
33
87
  /** Print the stable responsibility boundary for humans or agent tooling. */
@@ -300,6 +354,61 @@ interface SecretsPushOptions {
300
354
  */
301
355
  declare function secretsPush(options: SecretsPushOptions): Promise<void>;
302
356
 
357
+ /** Built-in security coverage profile selected for a hosted reasoning run. */
358
+ type HostedSecurityProfile = "odla" | "cloudflare-app" | "generic";
359
+ /** Exact attribution and authorization need supplied to a lazy token callback. */
360
+ interface HostedSecurityTokenRequest {
361
+ platform: string;
362
+ appId: string;
363
+ env: string;
364
+ selfAudit: boolean;
365
+ /** Self-audit asks the caller for an explicitly scoped platform credential. */
366
+ /** Ordinary app runs use owner authority and therefore request no platform scope. */
367
+ scope: "platform:security:self" | null;
368
+ }
369
+ /** Local snapshot/orchestration controls for an app-attributed hosted security
370
+ * run. The platform supplies model routes and provider credentials. */
371
+ interface RunHostedSecurityOptions {
372
+ /** Project config; loaded for customer-app runs and ignored for self-audit. */
373
+ configPath?: string;
374
+ /** Scan odla itself under the protected odla-ai/prod identity. */
375
+ selfAudit?: boolean;
376
+ /** Repository directory to snapshot. Defaults to the config root or cwd for self-audit. */
377
+ target?: string;
378
+ /** Private artifact directory. Defaults to `<target>/.odla/security/hosted`. */
379
+ out?: string;
380
+ /** Customer environment. Must be declared in config. Self-audit always uses prod. */
381
+ env?: string;
382
+ profile?: HostedSecurityProfile;
383
+ maxHuntTasks?: number;
384
+ /** Exact acknowledgement required before any source capture or network call. */
385
+ sourceDisclosureAck?: "redacted";
386
+ /** Optional client correlation id; the platform returns the authoritative run id. */
387
+ runId?: string;
388
+ /** Platform override. Customer runs otherwise use config.platformUrl. */
389
+ platform?: string;
390
+ /** Injected app credential; for self-audit this must be explicitly scoped by the caller. */
391
+ token?: string;
392
+ /** Lazy token acquisition. Receives the exact app/env and required scope. */
393
+ getToken?: (request: HostedSecurityTokenRequest) => string | Promise<string>;
394
+ fetch?: typeof fetch;
395
+ signal?: AbortSignal;
396
+ stdout?: Pick<typeof console, "log" | "error">;
397
+ }
398
+ /** Completed local report, public platform run metadata, and private artifact path. */
399
+ interface HostedSecurityResult {
400
+ report: SecurityReport;
401
+ run: Readonly<PlatformSecurityRun>;
402
+ output: string;
403
+ }
404
+ /**
405
+ * Run the hosted, redacted-source security harness for an odla app or odla's
406
+ * protected self-audit identity. Provider/model selection and provider secrets
407
+ * remain platform-owned; this function accepts only an app/scoped bearer and
408
+ * the opaque role grants remain inside @odla-ai/security's reasoner closures.
409
+ */
410
+ declare function runHostedSecurity(options: RunHostedSecurityOptions): Promise<HostedSecurityResult>;
411
+
303
412
  /** Agent harnesses with a first-class local adapter. */
304
413
  declare const AGENT_HARNESSES: readonly ["claude", "codex", "cursor", "copilot", "gemini", "agents"];
305
414
  /** A supported coding-agent harness. `agents` is the portable `AGENTS.md` adapter. */
@@ -379,4 +488,4 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
379
488
  */
380
489
  declare function smoke(options: SmokeOptions): Promise<void>;
381
490
 
382
- export { AGENT_HARNESSES, type AgentHarness, type AgentHarnessSelector, CAPABILITIES, type HarnessInstallResult, type LoadedProjectConfig, type LocalCredentials, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type SecretsPushOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, doctor, initProject, installSkill, printCapabilities, provision, redactSecrets, runCli, secretsPush, smoke };
491
+ export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, CAPABILITIES, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type LoadedProjectConfig, type LocalCredentials, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type SystemAiPurpose, adminAi, doctor, getScopedPlatformToken, initProject, installSkill, printCapabilities, provision, redactSecrets, runCli, runHostedSecurity, secretsPush, smoke };
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { SecurityReport, PlatformSecurityRun } from '@odla-ai/security';
2
+
1
3
  /**
2
4
  * Parse CLI arguments and dispatch to the matching command — the entry point
3
5
  * `bin.ts` invokes. `argv` defaults to `process.argv.slice(2)`; the first
@@ -8,7 +10,10 @@
8
10
  * Recognized commands: `version`/`-v`/`--version` and `help`/`-h`/`--help` print
9
11
  * and return; `init` scaffolds a project (requires `--app-id` and `--name`);
10
12
  * `doctor` validates config offline; `capabilities` prints the responsibility
11
- * boundary; `provision` runs the full provision (including optional secret
13
+ * boundary; `admin ai` reads/updates purpose-specific platform AI policies and
14
+ * write-only credentials through a short-lived exact-scope device grant;
15
+ * `security run` performs an explicitly acknowledged, app-attributed hosted
16
+ * reasoning pass; `provision` runs the full provision (including optional secret
12
17
  * rotation, local vars, and deployed secret push); `smoke` checks a live env;
13
18
  * `setup` and `skill install` install the bundled offline runbooks for Claude
14
19
  * Code, Codex, Cursor, Copilot, Gemini, and `AGENTS.md`-aware agents; and
@@ -21,13 +26,62 @@
21
26
  */
22
27
  declare function runCli(argv?: string[]): Promise<void>;
23
28
 
29
+ /** Hosted platform purposes whose provider, model, and budgets an admin may route. */
30
+ declare const SYSTEM_AI_PURPOSES: readonly ["o11y.triage", "security.discovery", "security.validation"];
31
+ /** One catalog-validated, platform-funded System AI purpose. */
32
+ type SystemAiPurpose = (typeof SYSTEM_AI_PURPOSES)[number];
33
+ /** Inputs for one System AI read, policy update, credential-status read, or
34
+ * write-only credential transfer. Provider values may come only from a named
35
+ * environment variable or stdin. */
36
+ interface AdminAiOptions {
37
+ action: "show" | "set" | "credentials" | "credential-set";
38
+ purpose?: string;
39
+ provider?: string;
40
+ model?: string;
41
+ enabled?: boolean;
42
+ maxInputBytes?: number;
43
+ maxOutputTokens?: number;
44
+ maxCallsPerRun?: number;
45
+ platform?: string;
46
+ token?: string;
47
+ json?: boolean;
48
+ open?: boolean;
49
+ fetch?: typeof fetch;
50
+ stdout?: Pick<typeof console, "log">;
51
+ openApprovalUrl?: (url: string) => Promise<void>;
52
+ credentialProvider?: string;
53
+ fromEnv?: string;
54
+ stdin?: boolean;
55
+ readStdin?: () => Promise<string>;
56
+ /** Separate short-lived admin-token cache; never reuses the app developer-token file. */
57
+ tokenFile?: string;
58
+ }
59
+ /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
60
+ interface ScopedPlatformTokenOptions {
61
+ platform: string;
62
+ scope: "platform:ai:read" | "platform:ai:write" | "platform:security:self";
63
+ open?: boolean;
64
+ fetch?: typeof fetch;
65
+ stdout?: Pick<typeof console, "log">;
66
+ openApprovalUrl?: (url: string) => Promise<void>;
67
+ tokenFile?: string;
68
+ }
69
+ /** Obtain/cache one exact platform scope without granting ambient admin. */
70
+ declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
71
+ /** Read or update platform-funded AI routing. Authentication is a short-lived,
72
+ * explicitly scoped device grant; ordinary app developer tokens never become
73
+ * platform admins. Credential writes accept values only from a named env var
74
+ * or stdin, transfer them once, and never place them in argv, output, or the
75
+ * scoped-token cache. */
76
+ declare function adminAi(options: AdminAiOptions): Promise<void>;
77
+
24
78
  /** Stable, machine-readable division of work between the CLI, coding agent,
25
79
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
26
80
  declare const CAPABILITIES: {
27
- 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", "push db schema/rules and configure platform AI, auth, and deployment links", "validate config offline and smoke-test a provisioned db environment"];
81
+ 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", "push db schema/rules and configure platform AI, auth, and deployment links", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "let admins manage system AI routes/credentials through short-lived exact-scope approval"];
28
82
  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"];
29
- readonly human: readonly ["approve the odla device code and one-off third-party logins", "consent to production changes with --yes", "request destructive credential rotation explicitly", "review application semantics, security findings, releases, and merges"];
30
- readonly studio: readonly ["view telemetry and environment state", "perform manual credential recovery when the CLI's local shown-once copy is unavailable"];
83
+ readonly human: readonly ["approve the odla device code and one-off third-party logins", "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"];
84
+ readonly studio: readonly ["view telemetry and environment state", "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"];
31
85
  };
32
86
  type Output = Pick<typeof console, "log">;
33
87
  /** Print the stable responsibility boundary for humans or agent tooling. */
@@ -300,6 +354,61 @@ interface SecretsPushOptions {
300
354
  */
301
355
  declare function secretsPush(options: SecretsPushOptions): Promise<void>;
302
356
 
357
+ /** Built-in security coverage profile selected for a hosted reasoning run. */
358
+ type HostedSecurityProfile = "odla" | "cloudflare-app" | "generic";
359
+ /** Exact attribution and authorization need supplied to a lazy token callback. */
360
+ interface HostedSecurityTokenRequest {
361
+ platform: string;
362
+ appId: string;
363
+ env: string;
364
+ selfAudit: boolean;
365
+ /** Self-audit asks the caller for an explicitly scoped platform credential. */
366
+ /** Ordinary app runs use owner authority and therefore request no platform scope. */
367
+ scope: "platform:security:self" | null;
368
+ }
369
+ /** Local snapshot/orchestration controls for an app-attributed hosted security
370
+ * run. The platform supplies model routes and provider credentials. */
371
+ interface RunHostedSecurityOptions {
372
+ /** Project config; loaded for customer-app runs and ignored for self-audit. */
373
+ configPath?: string;
374
+ /** Scan odla itself under the protected odla-ai/prod identity. */
375
+ selfAudit?: boolean;
376
+ /** Repository directory to snapshot. Defaults to the config root or cwd for self-audit. */
377
+ target?: string;
378
+ /** Private artifact directory. Defaults to `<target>/.odla/security/hosted`. */
379
+ out?: string;
380
+ /** Customer environment. Must be declared in config. Self-audit always uses prod. */
381
+ env?: string;
382
+ profile?: HostedSecurityProfile;
383
+ maxHuntTasks?: number;
384
+ /** Exact acknowledgement required before any source capture or network call. */
385
+ sourceDisclosureAck?: "redacted";
386
+ /** Optional client correlation id; the platform returns the authoritative run id. */
387
+ runId?: string;
388
+ /** Platform override. Customer runs otherwise use config.platformUrl. */
389
+ platform?: string;
390
+ /** Injected app credential; for self-audit this must be explicitly scoped by the caller. */
391
+ token?: string;
392
+ /** Lazy token acquisition. Receives the exact app/env and required scope. */
393
+ getToken?: (request: HostedSecurityTokenRequest) => string | Promise<string>;
394
+ fetch?: typeof fetch;
395
+ signal?: AbortSignal;
396
+ stdout?: Pick<typeof console, "log" | "error">;
397
+ }
398
+ /** Completed local report, public platform run metadata, and private artifact path. */
399
+ interface HostedSecurityResult {
400
+ report: SecurityReport;
401
+ run: Readonly<PlatformSecurityRun>;
402
+ output: string;
403
+ }
404
+ /**
405
+ * Run the hosted, redacted-source security harness for an odla app or odla's
406
+ * protected self-audit identity. Provider/model selection and provider secrets
407
+ * remain platform-owned; this function accepts only an app/scoped bearer and
408
+ * the opaque role grants remain inside @odla-ai/security's reasoner closures.
409
+ */
410
+ declare function runHostedSecurity(options: RunHostedSecurityOptions): Promise<HostedSecurityResult>;
411
+
303
412
  /** Agent harnesses with a first-class local adapter. */
304
413
  declare const AGENT_HARNESSES: readonly ["claude", "codex", "cursor", "copilot", "gemini", "agents"];
305
414
  /** A supported coding-agent harness. `agents` is the portable `AGENTS.md` adapter. */
@@ -379,4 +488,4 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
379
488
  */
380
489
  declare function smoke(options: SmokeOptions): Promise<void>;
381
490
 
382
- export { AGENT_HARNESSES, type AgentHarness, type AgentHarnessSelector, CAPABILITIES, type HarnessInstallResult, type LoadedProjectConfig, type LocalCredentials, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type SecretsPushOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, doctor, initProject, installSkill, printCapabilities, provision, redactSecrets, runCli, secretsPush, smoke };
491
+ export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, CAPABILITIES, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type LoadedProjectConfig, type LocalCredentials, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type SystemAiPurpose, adminAi, doctor, getScopedPlatformToken, initProject, installSkill, printCapabilities, provision, redactSecrets, runCli, runHostedSecurity, secretsPush, smoke };
package/dist/index.js CHANGED
@@ -2,26 +2,34 @@
2
2
  import {
3
3
  AGENT_HARNESSES,
4
4
  CAPABILITIES,
5
+ SYSTEM_AI_PURPOSES,
6
+ adminAi,
5
7
  doctor,
8
+ getScopedPlatformToken,
6
9
  initProject,
7
10
  installSkill,
8
11
  printCapabilities,
9
12
  provision,
10
13
  redactSecrets,
11
14
  runCli,
15
+ runHostedSecurity,
12
16
  secretsPush,
13
17
  smoke
14
- } from "./chunk-7WZIZCGA.js";
18
+ } from "./chunk-OERLHVLH.js";
15
19
  export {
16
20
  AGENT_HARNESSES,
17
21
  CAPABILITIES,
22
+ SYSTEM_AI_PURPOSES,
23
+ adminAi,
18
24
  doctor,
25
+ getScopedPlatformToken,
19
26
  initProject,
20
27
  installSkill,
21
28
  printCapabilities,
22
29
  provision,
23
30
  redactSecrets,
24
31
  runCli,
32
+ runHostedSecurity,
25
33
  secretsPush,
26
34
  smoke
27
35
  };
package/llms.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  # @odla-ai/cli — LLM context
2
2
 
3
- > Agent-operable CLI for provisioning odla apps, services, credentials, Worker secrets, and local runtime files.
3
+ > Agent-operable CLI for odla provisioning, scoped System AI administration, hosted security runs, Worker secrets, and smoke checks.
4
4
 
5
5
  > ⚠️ **Early access — pre-1.0.** Agents work from bounded runbooks; humans
6
6
  > approve credentials, production changes, releases, and merges. APIs and exact
@@ -9,9 +9,11 @@
9
9
 
10
10
  Project-neutral provisioning CLI for odla apps. It creates and validates an
11
11
  `odla.config.mjs`, then uses that config to register an app, enable services,
12
- push odla-db schema/rules, configure platform AI, configure Clerk auth, record
12
+ push odla-db schema/rules, configure per-app BYOK AI, configure Clerk auth, record
13
13
  deployment links, provision o11y ingest credentials, and transfer local or
14
- deployed Worker secrets without printing them.
14
+ deployed Worker secrets without printing them. It also gives platform admins a
15
+ scoped System AI control surface and gives app owners a provider-key-free
16
+ hosted security command.
15
17
 
16
18
  It does not know about any specific app. App identity, environments, services,
17
19
  schema, rules, auth, AI provider, and links all come from config.
@@ -29,8 +31,8 @@ For a project you keep working in, install it as a dev dependency so the
29
31
  shorter `npx odla-ai` form works and the version is pinned by your lockfile:
30
32
 
31
33
  ```bash
32
- npm view @odla-ai/cli@0.5.0 version
33
- npm i -D --save-exact @odla-ai/cli@0.5.0
34
+ npm view @odla-ai/cli@0.6.0 version
35
+ npm i -D --save-exact @odla-ai/cli@0.6.0
34
36
  ```
35
37
 
36
38
  ## Prerequisites
@@ -59,6 +61,11 @@ npx odla-ai provision --dry-run
59
61
  npx odla-ai provision --write-dev-vars --push-secrets
60
62
  npx odla-ai smoke --env dev
61
63
  npx odla-ai secrets push --env dev
64
+ npx odla-ai security run . --env dev --ack-redacted-source
65
+ npx odla-ai admin ai show
66
+ npx odla-ai admin ai set security.discovery --provider anthropic --model claude-opus-4-8 --enabled
67
+ npx odla-ai admin ai credentials
68
+ npx odla-ai admin ai credential set anthropic --from-env ANTHROPIC_API_KEY
62
69
  npx odla-ai skill install
63
70
  npx odla-ai version
64
71
  ```
@@ -119,17 +126,30 @@ when provisioning has not written `.odla/credentials.local.json`.
119
126
 
120
127
  The bundled build/migration skills add a passive pre-ship gate with
121
128
  `@odla-ai/security`: after the exact-version availability check, run
122
- `npm i -D --save-exact @odla-ai/security@0.1.0`, then
129
+ `npm i -D --save-exact @odla-ai/security@0.2.0`, then
123
130
  `npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical`.
124
- This is a separate binary, not a hidden `odla-ai` subcommand; it makes no model
125
- calls and does not execute target code.
131
+ The passive scan remains a separate binary: it makes no model calls and does
132
+ not execute target code. After explicit redacted-source approval,
133
+ `odla-ai security run . --env dev --ack-redacted-source` adds hosted discovery
134
+ and independent validation. The CLI obtains/reuses app-owner auth and the
135
+ platform supplies bounded role grants; it never requests provider keys.
136
+ Early-access run ceilings are rolling; a `429` includes the platform's safe
137
+ retry hint, which the CLI surfaces without echoing arbitrary response text.
126
138
  Before installing the exact release, require
127
- `npm view @odla-ai/security@0.1.0 version` to succeed before installation. An
139
+ `npm view @odla-ai/security@0.2.0 version` to succeed before installation. An
128
140
  exact-version `E404` means the release is unavailable, not that the security
129
141
  preflight passed, and does not prove the package name is absent. odla's own
130
142
  engineering environment uses an equivalent internal gate; customer projects
131
143
  should use the published `odla-security` command above.
132
144
 
145
+ `admin ai show|set|credentials|credential set` manages platform-funded System
146
+ AI (`o11y.triage`, `security.discovery`, `security.validation`). It uses a
147
+ separate, mode-`0600` `.odla/admin-token.local.json` cache. Studio displays the
148
+ exact scope, only an admin can approve it, and it expires after ~15 minutes;
149
+ the token never becomes ambient admin. Credential writes accept only
150
+ `--from-env <NAME>` or `--stdin` and never place the value in argv, output, or
151
+ the cache. System AI and each app's BYOK AI are separate vault/funding paths.
152
+
133
153
  `secrets push --env <env>` is the narrower recovery/retry command. It moves the
134
154
  configured env's odla-db key and/or o11y ingest token from
135
155
  `.odla/credentials.local.json` into the deployed Worker by piping each value
@@ -151,7 +171,8 @@ agent owns application semantics: installing `@odla-ai/o11y`, wrapping the
151
171
  Worker with `withObservability`, and choosing useful spans, metrics, errors, and
152
172
  LLM-usage records. The human owns the device approval, production consent, and
153
173
  explicit destructive rotation. Studio is where people view telemetry and
154
- perform manual recovery; its token control is not the normal setup path.
174
+ perform manual recovery, configure System AI, and inspect app/run-attributed
175
+ platform usage; its o11y token control is not the normal setup path.
155
176
  Run `npx odla-ai capabilities` for the human-readable contract or add `--json`
156
177
  when an agent or tool needs to branch on it without scraping prose.
157
178
 
@@ -230,9 +251,11 @@ If schema is present and rules are omitted, `defaultRules: "deny"` generates
230
251
  deny-all rules for every schema entity. That is the safe default for Workers
231
252
  that mediate reads and writes with an app key.
232
253
 
233
- ## API reference (generated from dist/index.d.ts, v0.5.0)
254
+ ## API reference (generated from dist/index.d.ts, v0.6.0)
234
255
 
235
256
  ```ts
257
+ import { SecurityReport, PlatformSecurityRun } from '@odla-ai/security';
258
+
236
259
  /**
237
260
  * Parse CLI arguments and dispatch to the matching command — the entry point
238
261
  * `bin.ts` invokes. `argv` defaults to `process.argv.slice(2)`; the first
@@ -243,7 +266,10 @@ that mediate reads and writes with an app key.
243
266
  * Recognized commands: `version`/`-v`/`--version` and `help`/`-h`/`--help` print
244
267
  * and return; `init` scaffolds a project (requires `--app-id` and `--name`);
245
268
  * `doctor` validates config offline; `capabilities` prints the responsibility
246
- * boundary; `provision` runs the full provision (including optional secret
269
+ * boundary; `admin ai` reads/updates purpose-specific platform AI policies and
270
+ * write-only credentials through a short-lived exact-scope device grant;
271
+ * `security run` performs an explicitly acknowledged, app-attributed hosted
272
+ * reasoning pass; `provision` runs the full provision (including optional secret
247
273
  * rotation, local vars, and deployed secret push); `smoke` checks a live env;
248
274
  * `setup` and `skill install` install the bundled offline runbooks for Claude
249
275
  * Code, Codex, Cursor, Copilot, Gemini, and `AGENTS.md`-aware agents; and
@@ -256,13 +282,62 @@ that mediate reads and writes with an app key.
256
282
  */
257
283
  declare function runCli(argv?: string[]): Promise<void>;
258
284
 
285
+ /** Hosted platform purposes whose provider, model, and budgets an admin may route. */
286
+ declare const SYSTEM_AI_PURPOSES: readonly ["o11y.triage", "security.discovery", "security.validation"];
287
+ /** One catalog-validated, platform-funded System AI purpose. */
288
+ type SystemAiPurpose = (typeof SYSTEM_AI_PURPOSES)[number];
289
+ /** Inputs for one System AI read, policy update, credential-status read, or
290
+ * write-only credential transfer. Provider values may come only from a named
291
+ * environment variable or stdin. */
292
+ interface AdminAiOptions {
293
+ action: "show" | "set" | "credentials" | "credential-set";
294
+ purpose?: string;
295
+ provider?: string;
296
+ model?: string;
297
+ enabled?: boolean;
298
+ maxInputBytes?: number;
299
+ maxOutputTokens?: number;
300
+ maxCallsPerRun?: number;
301
+ platform?: string;
302
+ token?: string;
303
+ json?: boolean;
304
+ open?: boolean;
305
+ fetch?: typeof fetch;
306
+ stdout?: Pick<typeof console, "log">;
307
+ openApprovalUrl?: (url: string) => Promise<void>;
308
+ credentialProvider?: string;
309
+ fromEnv?: string;
310
+ stdin?: boolean;
311
+ readStdin?: () => Promise<string>;
312
+ /** Separate short-lived admin-token cache; never reuses the app developer-token file. */
313
+ tokenFile?: string;
314
+ }
315
+ /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
316
+ interface ScopedPlatformTokenOptions {
317
+ platform: string;
318
+ scope: "platform:ai:read" | "platform:ai:write" | "platform:security:self";
319
+ open?: boolean;
320
+ fetch?: typeof fetch;
321
+ stdout?: Pick<typeof console, "log">;
322
+ openApprovalUrl?: (url: string) => Promise<void>;
323
+ tokenFile?: string;
324
+ }
325
+ /** Obtain/cache one exact platform scope without granting ambient admin. */
326
+ declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
327
+ /** Read or update platform-funded AI routing. Authentication is a short-lived,
328
+ * explicitly scoped device grant; ordinary app developer tokens never become
329
+ * platform admins. Credential writes accept values only from a named env var
330
+ * or stdin, transfer them once, and never place them in argv, output, or the
331
+ * scoped-token cache. */
332
+ declare function adminAi(options: AdminAiOptions): Promise<void>;
333
+
259
334
  /** Stable, machine-readable division of work between the CLI, coding agent,
260
335
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
261
336
  declare const CAPABILITIES: {
262
- 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", "push db schema/rules and configure platform AI, auth, and deployment links", "validate config offline and smoke-test a provisioned db environment"];
337
+ 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", "push db schema/rules and configure platform AI, auth, and deployment links", "validate config offline and smoke-test a provisioned db environment", "run app-attributed hosted security discovery and independent validation without provider keys", "let admins manage system AI routes/credentials through short-lived exact-scope approval"];
263
338
  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"];
264
- readonly human: readonly ["approve the odla device code and one-off third-party logins", "consent to production changes with --yes", "request destructive credential rotation explicitly", "review application semantics, security findings, releases, and merges"];
265
- readonly studio: readonly ["view telemetry and environment state", "perform manual credential recovery when the CLI's local shown-once copy is unavailable"];
339
+ readonly human: readonly ["approve the odla device code and one-off third-party logins", "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"];
340
+ readonly studio: readonly ["view telemetry and environment state", "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"];
266
341
  };
267
342
  type Output = Pick<typeof console, "log">;
268
343
  /** Print the stable responsibility boundary for humans or agent tooling. */
@@ -535,6 +610,61 @@ interface SecretsPushOptions {
535
610
  */
536
611
  declare function secretsPush(options: SecretsPushOptions): Promise<void>;
537
612
 
613
+ /** Built-in security coverage profile selected for a hosted reasoning run. */
614
+ type HostedSecurityProfile = "odla" | "cloudflare-app" | "generic";
615
+ /** Exact attribution and authorization need supplied to a lazy token callback. */
616
+ interface HostedSecurityTokenRequest {
617
+ platform: string;
618
+ appId: string;
619
+ env: string;
620
+ selfAudit: boolean;
621
+ /** Self-audit asks the caller for an explicitly scoped platform credential. */
622
+ /** Ordinary app runs use owner authority and therefore request no platform scope. */
623
+ scope: "platform:security:self" | null;
624
+ }
625
+ /** Local snapshot/orchestration controls for an app-attributed hosted security
626
+ * run. The platform supplies model routes and provider credentials. */
627
+ interface RunHostedSecurityOptions {
628
+ /** Project config; loaded for customer-app runs and ignored for self-audit. */
629
+ configPath?: string;
630
+ /** Scan odla itself under the protected odla-ai/prod identity. */
631
+ selfAudit?: boolean;
632
+ /** Repository directory to snapshot. Defaults to the config root or cwd for self-audit. */
633
+ target?: string;
634
+ /** Private artifact directory. Defaults to `<target>/.odla/security/hosted`. */
635
+ out?: string;
636
+ /** Customer environment. Must be declared in config. Self-audit always uses prod. */
637
+ env?: string;
638
+ profile?: HostedSecurityProfile;
639
+ maxHuntTasks?: number;
640
+ /** Exact acknowledgement required before any source capture or network call. */
641
+ sourceDisclosureAck?: "redacted";
642
+ /** Optional client correlation id; the platform returns the authoritative run id. */
643
+ runId?: string;
644
+ /** Platform override. Customer runs otherwise use config.platformUrl. */
645
+ platform?: string;
646
+ /** Injected app credential; for self-audit this must be explicitly scoped by the caller. */
647
+ token?: string;
648
+ /** Lazy token acquisition. Receives the exact app/env and required scope. */
649
+ getToken?: (request: HostedSecurityTokenRequest) => string | Promise<string>;
650
+ fetch?: typeof fetch;
651
+ signal?: AbortSignal;
652
+ stdout?: Pick<typeof console, "log" | "error">;
653
+ }
654
+ /** Completed local report, public platform run metadata, and private artifact path. */
655
+ interface HostedSecurityResult {
656
+ report: SecurityReport;
657
+ run: Readonly<PlatformSecurityRun>;
658
+ output: string;
659
+ }
660
+ /**
661
+ * Run the hosted, redacted-source security harness for an odla app or odla's
662
+ * protected self-audit identity. Provider/model selection and provider secrets
663
+ * remain platform-owned; this function accepts only an app/scoped bearer and
664
+ * the opaque role grants remain inside @odla-ai/security's reasoner closures.
665
+ */
666
+ declare function runHostedSecurity(options: RunHostedSecurityOptions): Promise<HostedSecurityResult>;
667
+
538
668
  /** Agent harnesses with a first-class local adapter. */
539
669
  declare const AGENT_HARNESSES: readonly ["claude", "codex", "cursor", "copilot", "gemini", "agents"];
540
670
  /** A supported coding-agent harness. `agents` is the portable `AGENTS.md` adapter. */
@@ -614,5 +744,5 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
614
744
  */
615
745
  declare function smoke(options: SmokeOptions): Promise<void>;
616
746
 
617
- export { AGENT_HARNESSES, type AgentHarness, type AgentHarnessSelector, CAPABILITIES, type HarnessInstallResult, type LoadedProjectConfig, type LocalCredentials, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type SecretsPushOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, doctor, initProject, installSkill, printCapabilities, provision, redactSecrets, runCli, secretsPush, smoke };
747
+ export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, CAPABILITIES, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type LoadedProjectConfig, type LocalCredentials, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type SystemAiPurpose, adminAi, doctor, getScopedPlatformToken, initProject, installSkill, printCapabilities, provision, redactSecrets, runCli, runHostedSecurity, secretsPush, smoke };
618
748
  ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@odla-ai/cli",
3
- "version": "0.5.0",
4
- "description": "Agent-operable CLI for provisioning odla apps, services, credentials, Worker secrets, and local runtime files.",
3
+ "version": "0.6.0",
4
+ "description": "Agent-operable CLI for odla provisioning, scoped System AI administration, hosted security runs, Worker secrets, and smoke checks.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://odla.ai/docs/packages/cli",
7
7
  "repository": {
@@ -59,9 +59,10 @@
59
59
  "prepublishOnly": "npm run build && npm run gen:llms"
60
60
  },
61
61
  "dependencies": {
62
- "@odla-ai/ai": "^0.3.0",
62
+ "@odla-ai/ai": "^0.3.1",
63
63
  "@odla-ai/apps": "^0.7.1",
64
- "@odla-ai/db": "^0.6.0"
64
+ "@odla-ai/db": "^0.6.1",
65
+ "@odla-ai/security": "^0.2.0"
65
66
  },
66
67
  "devDependencies": {
67
68
  "@types/node": "^22.10.0",
@@ -69,8 +69,12 @@ guessing which platform/credential steps need manual work. Then:
69
69
  ingest token when enabled), pushes schema + rules, writes `.dev.vars`, and
70
70
  transfers Worker secrets through Wrangler stdin.
71
71
  4. **run** — `npx wrangler dev` (auto-loads `.dev.vars`); verify locally.
72
- 5. **security** — run the passive `@odla-ai/security` odla profile;
73
- inspect every lead and keep critical candidate gating enabled.
72
+ 5. **security** — run the passive `@odla-ai/security` odla profile; inspect
73
+ every lead and keep critical candidate gating enabled. If the human approves
74
+ redacted source disclosure, follow with
75
+ `npx @odla-ai/cli security run . --env dev --ack-redacted-source` for
76
+ app-attributed discovery + independent validation. Never request provider
77
+ keys; the platform selects the routes and returns bounded role grants.
74
78
  6. **ship** ⏸ — after adding `prod`, run `npx @odla-ai/cli provision --dry-run`,
75
79
  show the human, then `npx @odla-ai/cli provision --yes --push-secrets` and
76
80
  `npx wrangler deploy`.