@odla-ai/cli 0.13.0 → 0.14.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
@@ -2,6 +2,99 @@ import { SecurityReport, PlatformSecurityRun } from '@odla-ai/security';
2
2
  import { HostedSecurityJob, GitHubConnectionStatus, GitHubSecuritySource, HostedSecurityIntentResponse, HostedSecurityPlan, HostedSecurityReport, HostedSecurityJobStatus } from '@odla-ai/security/hosted';
3
3
  export { GitHubConnectionAttempt, GitHubConnectionStatus, GitHubSecuritySource, HostedSecurityCounts, HostedSecurityCoverage, HostedSecurityIntent, HostedSecurityIntentResponse, HostedSecurityJob, HostedSecurityJobStatus, HostedSecurityPlan, HostedSecurityPlanRoute, HostedSecurityReport, HostedSecurityReportFinding, HostedSecurityRoute } from '@odla-ai/security/hosted';
4
4
 
5
+ /** One exact platform scope obtainable through the admin device flow. */
6
+ type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write" | "platform:ai:credential:read" | "platform:ai:credential:write" | "platform:ai:usage:read" | "platform:ai:audit:read" | "platform:code:host:connect" | "platform:security:self";
7
+ /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
8
+ interface ScopedPlatformTokenOptions {
9
+ platform: string;
10
+ scope: ScopedPlatformScope;
11
+ /** Existing odla account email used only when a fresh handshake is required. */
12
+ email?: string;
13
+ open?: boolean;
14
+ fetch?: typeof fetch;
15
+ stdout?: Pick<typeof console, "log">;
16
+ openApprovalUrl?: (url: string) => Promise<void>;
17
+ tokenFile?: string;
18
+ /** Keep the shown-once grant only in memory. */
19
+ cache?: boolean;
20
+ /** Human-visible purpose recorded on the exact handshake. */
21
+ label?: string;
22
+ }
23
+ /** Obtain/cache one exact platform scope without granting ambient admin. */
24
+ declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
25
+
26
+ /** Immutable, release-owned Pi adapter. No registry credential enters it. */
27
+ declare const CODE_PI_IMAGE = "ghcr.io/cory/odla-pi-agent@sha256:713db58428bc05cb486167c5747de8fd826669c9b283ff78e0139ac194c3d058";
28
+ /** Supported local isolation engines for an odla Code host runtime. */
29
+ type CodeContainerEngine = "container" | "podman" | "docker";
30
+ /** Immutable CaMeL-registered build recipe available to an agent container. */
31
+ interface CodeBuildRule {
32
+ id: string;
33
+ image: string;
34
+ command: readonly string[];
35
+ timeoutMs: number;
36
+ maxOutputBytes: number;
37
+ cpus?: number;
38
+ memory?: string;
39
+ pids?: number;
40
+ tmpfsBytes?: number;
41
+ }
42
+ /** Bounded host facts reported on each outbound Code control-plane heartbeat. */
43
+ interface CodeHostCapabilities {
44
+ protocolVersion: 1;
45
+ platform: "macos" | "linux";
46
+ arch: string;
47
+ engines: CodeContainerEngine[];
48
+ cpuCount: number;
49
+ memoryBytes: number;
50
+ }
51
+ /** Initial CaMeL-registered clean-build rule. App-specific recipes can replace
52
+ * this only after their own owner-visible registration flow exists. */
53
+ declare const CODE_BUILD_RECIPES: readonly CodeBuildRule[];
54
+ type Output$1 = Pick<typeof console, "log" | "error">;
55
+ /** Inputs for enrolling the current checkout and running its foreground Pi host. */
56
+ interface CodeConnectOptions {
57
+ configPath: string;
58
+ /** Repository root. Defaults to the current directory. */
59
+ cwd?: string;
60
+ env?: string;
61
+ email?: string;
62
+ open?: boolean;
63
+ name?: string;
64
+ slots?: number;
65
+ engine?: CodeContainerEngine | "auto";
66
+ heartbeatMs?: number;
67
+ /** Enroll and prove one heartbeat without waiting for sessions. */
68
+ once?: boolean;
69
+ fetch?: typeof fetch;
70
+ stdout?: Output$1;
71
+ openApprovalUrl?: (url: string) => Promise<void>;
72
+ signal?: AbortSignal;
73
+ /** Test/embedding boundaries. */
74
+ getToken?: typeof getScopedPlatformToken;
75
+ selectEngine?: (requested: CodeContainerEngine | "auto") => Promise<CodeContainerEngine>;
76
+ runRuntime?: (input: CodeRuntimeInput) => Promise<void>;
77
+ readGitOrigin?: (cwd: string) => Promise<string>;
78
+ }
79
+ /** Authority and runtime boundaries used after a Code host enrollment succeeds. */
80
+ interface CodeRuntimeInput {
81
+ endpoint: string;
82
+ token: string;
83
+ engine: CodeContainerEngine;
84
+ capabilities: CodeHostCapabilities;
85
+ heartbeatMs: number;
86
+ once: boolean;
87
+ signal?: AbortSignal;
88
+ stdout: Output$1;
89
+ fetch?: typeof fetch;
90
+ }
91
+ /** Enroll this machine from an odla project and keep the embedded Pi runtime
92
+ * online. Both the approval grant and host credential hashes are stored in
93
+ * odla-ai/db; plaintext host authority exists only in this running process. */
94
+ declare function codeConnect(options: CodeConnectOptions): Promise<void>;
95
+ /** Run outbound presence and fenced Pi commands without opening a listener. */
96
+ declare function runCodeRuntime(input: CodeRuntimeInput): Promise<void>;
97
+
5
98
  /** Map a CLI failure to its process exit code: 75 (EX_TEMPFAIL) marks a
6
99
  * handshake that is still awaiting human approval — the pending state is
7
100
  * persisted and rerunning the same command resumes it — everything else is 1. */
@@ -14,6 +107,7 @@ interface CliDependencies {
14
107
  readGitOrigin?: (cwd: string) => Promise<string>;
15
108
  confirm?: (message: string) => Promise<boolean>;
16
109
  stdout?: Pick<typeof console, "log" | "error">;
110
+ codeConnect?: (options: CodeConnectOptions) => Promise<void>;
17
111
  }
18
112
  /**
19
113
  * Parse CLI arguments and dispatch the matching odla command.
@@ -28,23 +122,6 @@ interface CliDependencies {
28
122
  */
29
123
  declare function runCli(argv?: string[], dependencies?: CliDependencies): Promise<void>;
30
124
 
31
- /** One exact platform scope obtainable through the admin device flow. */
32
- type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write" | "platform:ai:credential:read" | "platform:ai:credential:write" | "platform:ai:usage:read" | "platform:ai:audit:read" | "platform:security:self";
33
- /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
34
- interface ScopedPlatformTokenOptions {
35
- platform: string;
36
- scope: ScopedPlatformScope;
37
- /** Existing odla account email used only when a fresh handshake is required. */
38
- email?: string;
39
- open?: boolean;
40
- fetch?: typeof fetch;
41
- stdout?: Pick<typeof console, "log">;
42
- openApprovalUrl?: (url: string) => Promise<void>;
43
- tokenFile?: string;
44
- }
45
- /** Obtain/cache one exact platform scope without granting ambient admin. */
46
- declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
47
-
48
125
  /** Hosted platform purposes whose provider, model, and budgets an admin may route. */
49
126
  declare const SYSTEM_AI_PURPOSES: readonly ["o11y.triage", "security.discovery", "security.validation"];
50
127
  /** One catalog-validated, platform-funded System AI purpose. */
@@ -99,10 +176,10 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
99
176
  /** Stable, machine-readable division of work between the CLI, coding agent,
100
177
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
101
178
  declare const CAPABILITIES: {
102
- 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", "compose declared app-capability schema/rules, create guarded seeds when absent, and configure platform AI, auth, and deployment links", "apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)", "validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes", "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"];
179
+ 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", "add or remove app co-owners, each of whom self-provisions their own credentials for the shared db without any secret handoff", "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", "compose declared app-capability schema/rules, create guarded seeds when absent, and configure platform AI, auth, and deployment links", "apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)", "validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes", "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"];
103
180
  readonly agent: readonly ["install and import the selected odla SDKs", "wrap the Worker with withObservability and choose useful telemetry", "install capability packages, mount their runtime routes, and 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"];
104
181
  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"];
105
- 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"];
182
+ 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 — for the primary owner or any co-owner — 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"];
106
183
  };
107
184
  type Output = Pick<typeof console, "log">;
108
185
  /** Print the stable responsibility boundary for humans or agent tooling. */
@@ -855,4 +932,4 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
855
932
  */
856
933
  declare function smoke(options: SmokeOptions): Promise<void>;
857
934
 
858
- export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, type AvailableGoogleCalendar, CAPABILITIES, type CalendarConfig, type CalendarConnectionState, type CalendarLifecycleOptions, type CalendarServiceConfig, type CalendarStatus, type CliDependencies, type ConnectGitHubSecuritySourceOptions, type DisconnectGitHubSecuritySourceOptions, type FollowHostedSecurityJobOptions, GOOGLE_CALENDAR_EVENTS_SCOPE, type GetHostedSecurityIntentOptions, type GetHostedSecurityJobOptions, type GoogleCalendarConfig, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type IntegrationProbe, type IntegrationSeed, type ListGitHubSecuritySourcesOptions, type ListHostedSecurityJobsOptions, type LoadedProjectConfig, type LocalCredentials, type OdlaIntegration, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SecretsSetOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type StartHostedSecurityJobOptions, type SystemAiPurpose, adminAi, calendarBookingPageUrl, calendarCalendars, calendarConnect, calendarDisconnect, calendarServiceConfig, calendarStatus, connectGitHubSecuritySource, disconnectGitHubSecuritySource, doctor, exitCodeFor, followHostedSecurityJob, getHostedSecurityIntent, getHostedSecurityJob, getHostedSecurityPlan, getHostedSecurityReport, getScopedPlatformToken, inferGitHubRepository, initProject, installSkill, isTerminalHostedSecurityStatus, listGitHubSecuritySources, listHostedSecurityJobs, printCapabilities, provision, redactSecrets, repositoryFromGitRemote, runCli, runHostedSecurity, secretsPush, secretsSet, secretsSetClerkKey, smoke, startHostedSecurityJob };
935
+ export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, type AvailableGoogleCalendar, CAPABILITIES, CODE_BUILD_RECIPES, CODE_PI_IMAGE, type CalendarConfig, type CalendarConnectionState, type CalendarLifecycleOptions, type CalendarServiceConfig, type CalendarStatus, type CliDependencies, type CodeBuildRule, type CodeConnectOptions, type CodeContainerEngine, type CodeHostCapabilities, type CodeRuntimeInput, type ConnectGitHubSecuritySourceOptions, type DisconnectGitHubSecuritySourceOptions, type FollowHostedSecurityJobOptions, GOOGLE_CALENDAR_EVENTS_SCOPE, type GetHostedSecurityIntentOptions, type GetHostedSecurityJobOptions, type GoogleCalendarConfig, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type IntegrationProbe, type IntegrationSeed, type ListGitHubSecuritySourcesOptions, type ListHostedSecurityJobsOptions, type LoadedProjectConfig, type LocalCredentials, type OdlaIntegration, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SecretsSetOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type StartHostedSecurityJobOptions, type SystemAiPurpose, adminAi, calendarBookingPageUrl, calendarCalendars, calendarConnect, calendarDisconnect, calendarServiceConfig, calendarStatus, codeConnect, connectGitHubSecuritySource, disconnectGitHubSecuritySource, doctor, exitCodeFor, followHostedSecurityJob, getHostedSecurityIntent, getHostedSecurityJob, getHostedSecurityPlan, getHostedSecurityReport, getScopedPlatformToken, inferGitHubRepository, initProject, installSkill, isTerminalHostedSecurityStatus, listGitHubSecuritySources, listHostedSecurityJobs, printCapabilities, provision, redactSecrets, repositoryFromGitRemote, runCli, runCodeRuntime, runHostedSecurity, secretsPush, secretsSet, secretsSetClerkKey, smoke, startHostedSecurityJob };
package/dist/index.d.ts CHANGED
@@ -2,6 +2,99 @@ import { SecurityReport, PlatformSecurityRun } from '@odla-ai/security';
2
2
  import { HostedSecurityJob, GitHubConnectionStatus, GitHubSecuritySource, HostedSecurityIntentResponse, HostedSecurityPlan, HostedSecurityReport, HostedSecurityJobStatus } from '@odla-ai/security/hosted';
3
3
  export { GitHubConnectionAttempt, GitHubConnectionStatus, GitHubSecuritySource, HostedSecurityCounts, HostedSecurityCoverage, HostedSecurityIntent, HostedSecurityIntentResponse, HostedSecurityJob, HostedSecurityJobStatus, HostedSecurityPlan, HostedSecurityPlanRoute, HostedSecurityReport, HostedSecurityReportFinding, HostedSecurityRoute } from '@odla-ai/security/hosted';
4
4
 
5
+ /** One exact platform scope obtainable through the admin device flow. */
6
+ type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write" | "platform:ai:credential:read" | "platform:ai:credential:write" | "platform:ai:usage:read" | "platform:ai:audit:read" | "platform:code:host:connect" | "platform:security:self";
7
+ /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
8
+ interface ScopedPlatformTokenOptions {
9
+ platform: string;
10
+ scope: ScopedPlatformScope;
11
+ /** Existing odla account email used only when a fresh handshake is required. */
12
+ email?: string;
13
+ open?: boolean;
14
+ fetch?: typeof fetch;
15
+ stdout?: Pick<typeof console, "log">;
16
+ openApprovalUrl?: (url: string) => Promise<void>;
17
+ tokenFile?: string;
18
+ /** Keep the shown-once grant only in memory. */
19
+ cache?: boolean;
20
+ /** Human-visible purpose recorded on the exact handshake. */
21
+ label?: string;
22
+ }
23
+ /** Obtain/cache one exact platform scope without granting ambient admin. */
24
+ declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
25
+
26
+ /** Immutable, release-owned Pi adapter. No registry credential enters it. */
27
+ declare const CODE_PI_IMAGE = "ghcr.io/cory/odla-pi-agent@sha256:713db58428bc05cb486167c5747de8fd826669c9b283ff78e0139ac194c3d058";
28
+ /** Supported local isolation engines for an odla Code host runtime. */
29
+ type CodeContainerEngine = "container" | "podman" | "docker";
30
+ /** Immutable CaMeL-registered build recipe available to an agent container. */
31
+ interface CodeBuildRule {
32
+ id: string;
33
+ image: string;
34
+ command: readonly string[];
35
+ timeoutMs: number;
36
+ maxOutputBytes: number;
37
+ cpus?: number;
38
+ memory?: string;
39
+ pids?: number;
40
+ tmpfsBytes?: number;
41
+ }
42
+ /** Bounded host facts reported on each outbound Code control-plane heartbeat. */
43
+ interface CodeHostCapabilities {
44
+ protocolVersion: 1;
45
+ platform: "macos" | "linux";
46
+ arch: string;
47
+ engines: CodeContainerEngine[];
48
+ cpuCount: number;
49
+ memoryBytes: number;
50
+ }
51
+ /** Initial CaMeL-registered clean-build rule. App-specific recipes can replace
52
+ * this only after their own owner-visible registration flow exists. */
53
+ declare const CODE_BUILD_RECIPES: readonly CodeBuildRule[];
54
+ type Output$1 = Pick<typeof console, "log" | "error">;
55
+ /** Inputs for enrolling the current checkout and running its foreground Pi host. */
56
+ interface CodeConnectOptions {
57
+ configPath: string;
58
+ /** Repository root. Defaults to the current directory. */
59
+ cwd?: string;
60
+ env?: string;
61
+ email?: string;
62
+ open?: boolean;
63
+ name?: string;
64
+ slots?: number;
65
+ engine?: CodeContainerEngine | "auto";
66
+ heartbeatMs?: number;
67
+ /** Enroll and prove one heartbeat without waiting for sessions. */
68
+ once?: boolean;
69
+ fetch?: typeof fetch;
70
+ stdout?: Output$1;
71
+ openApprovalUrl?: (url: string) => Promise<void>;
72
+ signal?: AbortSignal;
73
+ /** Test/embedding boundaries. */
74
+ getToken?: typeof getScopedPlatformToken;
75
+ selectEngine?: (requested: CodeContainerEngine | "auto") => Promise<CodeContainerEngine>;
76
+ runRuntime?: (input: CodeRuntimeInput) => Promise<void>;
77
+ readGitOrigin?: (cwd: string) => Promise<string>;
78
+ }
79
+ /** Authority and runtime boundaries used after a Code host enrollment succeeds. */
80
+ interface CodeRuntimeInput {
81
+ endpoint: string;
82
+ token: string;
83
+ engine: CodeContainerEngine;
84
+ capabilities: CodeHostCapabilities;
85
+ heartbeatMs: number;
86
+ once: boolean;
87
+ signal?: AbortSignal;
88
+ stdout: Output$1;
89
+ fetch?: typeof fetch;
90
+ }
91
+ /** Enroll this machine from an odla project and keep the embedded Pi runtime
92
+ * online. Both the approval grant and host credential hashes are stored in
93
+ * odla-ai/db; plaintext host authority exists only in this running process. */
94
+ declare function codeConnect(options: CodeConnectOptions): Promise<void>;
95
+ /** Run outbound presence and fenced Pi commands without opening a listener. */
96
+ declare function runCodeRuntime(input: CodeRuntimeInput): Promise<void>;
97
+
5
98
  /** Map a CLI failure to its process exit code: 75 (EX_TEMPFAIL) marks a
6
99
  * handshake that is still awaiting human approval — the pending state is
7
100
  * persisted and rerunning the same command resumes it — everything else is 1. */
@@ -14,6 +107,7 @@ interface CliDependencies {
14
107
  readGitOrigin?: (cwd: string) => Promise<string>;
15
108
  confirm?: (message: string) => Promise<boolean>;
16
109
  stdout?: Pick<typeof console, "log" | "error">;
110
+ codeConnect?: (options: CodeConnectOptions) => Promise<void>;
17
111
  }
18
112
  /**
19
113
  * Parse CLI arguments and dispatch the matching odla command.
@@ -28,23 +122,6 @@ interface CliDependencies {
28
122
  */
29
123
  declare function runCli(argv?: string[], dependencies?: CliDependencies): Promise<void>;
30
124
 
31
- /** One exact platform scope obtainable through the admin device flow. */
32
- type ScopedPlatformScope = "platform:ai:policy:read" | "platform:ai:policy:write" | "platform:ai:credential:read" | "platform:ai:credential:write" | "platform:ai:usage:read" | "platform:ai:audit:read" | "platform:security:self";
33
- /** Inputs for obtaining one short-lived, exact-scope platform device grant. */
34
- interface ScopedPlatformTokenOptions {
35
- platform: string;
36
- scope: ScopedPlatformScope;
37
- /** Existing odla account email used only when a fresh handshake is required. */
38
- email?: string;
39
- open?: boolean;
40
- fetch?: typeof fetch;
41
- stdout?: Pick<typeof console, "log">;
42
- openApprovalUrl?: (url: string) => Promise<void>;
43
- tokenFile?: string;
44
- }
45
- /** Obtain/cache one exact platform scope without granting ambient admin. */
46
- declare function getScopedPlatformToken(options: ScopedPlatformTokenOptions): Promise<string>;
47
-
48
125
  /** Hosted platform purposes whose provider, model, and budgets an admin may route. */
49
126
  declare const SYSTEM_AI_PURPOSES: readonly ["o11y.triage", "security.discovery", "security.validation"];
50
127
  /** One catalog-validated, platform-funded System AI purpose. */
@@ -99,10 +176,10 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
99
176
  /** Stable, machine-readable division of work between the CLI, coding agent,
100
177
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
101
178
  declare const CAPABILITIES: {
102
- 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", "compose declared app-capability schema/rules, create guarded seeds when absent, and configure platform AI, auth, and deployment links", "apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)", "validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes", "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"];
179
+ 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", "add or remove app co-owners, each of whom self-provisions their own credentials for the shared db without any secret handoff", "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", "compose declared app-capability schema/rules, create guarded seeds when absent, and configure platform AI, auth, and deployment links", "apply Google Calendar booking config, then drive state-bound consent, status, discovery, and disconnect flows (bookings run live through the platform proxy)", "validate integration contracts offline and smoke-test a provisioned db environment plus anonymous capability routes", "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"];
103
180
  readonly agent: readonly ["install and import the selected odla SDKs", "wrap the Worker with withObservability and choose useful telemetry", "install capability packages, mount their runtime routes, and 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"];
104
181
  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"];
105
- 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"];
182
+ 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 — for the primary owner or any co-owner — 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"];
106
183
  };
107
184
  type Output = Pick<typeof console, "log">;
108
185
  /** Print the stable responsibility boundary for humans or agent tooling. */
@@ -855,4 +932,4 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
855
932
  */
856
933
  declare function smoke(options: SmokeOptions): Promise<void>;
857
934
 
858
- export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, type AvailableGoogleCalendar, CAPABILITIES, type CalendarConfig, type CalendarConnectionState, type CalendarLifecycleOptions, type CalendarServiceConfig, type CalendarStatus, type CliDependencies, type ConnectGitHubSecuritySourceOptions, type DisconnectGitHubSecuritySourceOptions, type FollowHostedSecurityJobOptions, GOOGLE_CALENDAR_EVENTS_SCOPE, type GetHostedSecurityIntentOptions, type GetHostedSecurityJobOptions, type GoogleCalendarConfig, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type IntegrationProbe, type IntegrationSeed, type ListGitHubSecuritySourcesOptions, type ListHostedSecurityJobsOptions, type LoadedProjectConfig, type LocalCredentials, type OdlaIntegration, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SecretsSetOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type StartHostedSecurityJobOptions, type SystemAiPurpose, adminAi, calendarBookingPageUrl, calendarCalendars, calendarConnect, calendarDisconnect, calendarServiceConfig, calendarStatus, connectGitHubSecuritySource, disconnectGitHubSecuritySource, doctor, exitCodeFor, followHostedSecurityJob, getHostedSecurityIntent, getHostedSecurityJob, getHostedSecurityPlan, getHostedSecurityReport, getScopedPlatformToken, inferGitHubRepository, initProject, installSkill, isTerminalHostedSecurityStatus, listGitHubSecuritySources, listHostedSecurityJobs, printCapabilities, provision, redactSecrets, repositoryFromGitRemote, runCli, runHostedSecurity, secretsPush, secretsSet, secretsSetClerkKey, smoke, startHostedSecurityJob };
935
+ export { AGENT_HARNESSES, type AdminAiOptions, type AgentHarness, type AgentHarnessSelector, type AvailableGoogleCalendar, CAPABILITIES, CODE_BUILD_RECIPES, CODE_PI_IMAGE, type CalendarConfig, type CalendarConnectionState, type CalendarLifecycleOptions, type CalendarServiceConfig, type CalendarStatus, type CliDependencies, type CodeBuildRule, type CodeConnectOptions, type CodeContainerEngine, type CodeHostCapabilities, type CodeRuntimeInput, type ConnectGitHubSecuritySourceOptions, type DisconnectGitHubSecuritySourceOptions, type FollowHostedSecurityJobOptions, GOOGLE_CALENDAR_EVENTS_SCOPE, type GetHostedSecurityIntentOptions, type GetHostedSecurityJobOptions, type GoogleCalendarConfig, type HarnessInstallResult, type HostedSecurityProfile, type HostedSecurityResult, type HostedSecurityTokenRequest, type IntegrationProbe, type IntegrationSeed, type ListGitHubSecuritySourcesOptions, type ListHostedSecurityJobsOptions, type LoadedProjectConfig, type LocalCredentials, type OdlaIntegration, type OdlaProjectConfig, type ProvisionOptions, type ProvisionPlan, type RunHostedSecurityOptions, SYSTEM_AI_PURPOSES, type ScopedPlatformTokenOptions, type SecretsPushOptions, type SecretsSetOptions, type SkillInstallOptions, type SkillInstallResult, type SmokeOptions, type StartHostedSecurityJobOptions, type SystemAiPurpose, adminAi, calendarBookingPageUrl, calendarCalendars, calendarConnect, calendarDisconnect, calendarServiceConfig, calendarStatus, codeConnect, connectGitHubSecuritySource, disconnectGitHubSecuritySource, doctor, exitCodeFor, followHostedSecurityJob, getHostedSecurityIntent, getHostedSecurityJob, getHostedSecurityPlan, getHostedSecurityReport, getScopedPlatformToken, inferGitHubRepository, initProject, installSkill, isTerminalHostedSecurityStatus, listGitHubSecuritySources, listHostedSecurityJobs, printCapabilities, provision, redactSecrets, repositoryFromGitRemote, runCli, runCodeRuntime, runHostedSecurity, secretsPush, secretsSet, secretsSetClerkKey, smoke, startHostedSecurityJob };
package/dist/index.js CHANGED
@@ -2,6 +2,8 @@
2
2
  import {
3
3
  AGENT_HARNESSES,
4
4
  CAPABILITIES,
5
+ CODE_BUILD_RECIPES,
6
+ CODE_PI_IMAGE,
5
7
  GOOGLE_CALENDAR_EVENTS_SCOPE,
6
8
  SYSTEM_AI_PURPOSES,
7
9
  adminAi,
@@ -11,6 +13,7 @@ import {
11
13
  calendarDisconnect,
12
14
  calendarServiceConfig,
13
15
  calendarStatus,
16
+ codeConnect,
14
17
  connectGitHubSecuritySource,
15
18
  disconnectGitHubSecuritySource,
16
19
  doctor,
@@ -32,16 +35,19 @@ import {
32
35
  redactSecrets,
33
36
  repositoryFromGitRemote,
34
37
  runCli,
38
+ runCodeRuntime,
35
39
  runHostedSecurity,
36
40
  secretsPush,
37
41
  secretsSet,
38
42
  secretsSetClerkKey,
39
43
  smoke,
40
44
  startHostedSecurityJob
41
- } from "./chunk-I7XDJZB6.js";
45
+ } from "./chunk-3AC74CD2.js";
42
46
  export {
43
47
  AGENT_HARNESSES,
44
48
  CAPABILITIES,
49
+ CODE_BUILD_RECIPES,
50
+ CODE_PI_IMAGE,
45
51
  GOOGLE_CALENDAR_EVENTS_SCOPE,
46
52
  SYSTEM_AI_PURPOSES,
47
53
  adminAi,
@@ -51,6 +57,7 @@ export {
51
57
  calendarDisconnect,
52
58
  calendarServiceConfig,
53
59
  calendarStatus,
60
+ codeConnect,
54
61
  connectGitHubSecuritySource,
55
62
  disconnectGitHubSecuritySource,
56
63
  doctor,
@@ -72,6 +79,7 @@ export {
72
79
  redactSecrets,
73
80
  repositoryFromGitRemote,
74
81
  runCli,
82
+ runCodeRuntime,
75
83
  runHostedSecurity,
76
84
  secretsPush,
77
85
  secretsSet,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odla-ai/cli",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
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",
@@ -57,12 +57,13 @@
57
57
  "prepublishOnly": "npm run build"
58
58
  },
59
59
  "dependencies": {
60
- "@odla-ai/ai": "^0.4.0",
60
+ "@odla-ai/ai": "^0.5.0",
61
61
  "@odla-ai/apps": "^0.8.1",
62
- "@odla-ai/db": "^0.6.4",
62
+ "@odla-ai/db": ">=0.6.4",
63
63
  "@odla-ai/security": "^0.3.1"
64
64
  },
65
65
  "devDependencies": {
66
+ "@odla-ai/harness": "*",
66
67
  "@types/node": "^22.10.0",
67
68
  "tsup": "^8.5.1",
68
69
  "typescript": "^6.0.3",
@@ -9,6 +9,7 @@ description: >
9
9
  runbookOrder:
10
10
  - references/build.md
11
11
  - references/sdks.md
12
+ - references/co-owners.md
12
13
  ---
13
14
 
14
15
  # odla
@@ -160,3 +161,6 @@ code, paste a publishable key, run a command) — and wait for a nod.
160
161
  exported TypeScript declarations/JSDoc (resolve entry points through its
161
162
  `package.json` `exports`). Rendered references are also public at
162
163
  `https://odla.ai/docs/packages/<pkg>`.
164
+ - `references/co-owners.md` — sharing one app's db and tooling across a team:
165
+ `app owners add/list/remove`, and how each co-owner self-provisions their own
166
+ credentials (dev and the shared prod database) without any secret handoff.
@@ -0,0 +1,54 @@
1
+ # Co-owners — sharing one app's db and tooling
2
+
3
+ An odla app can have more than one owner. The creator is the **primary owner**;
4
+ everyone else is a **co-owner** with the *same* full access. This is how a team
5
+ shares one database — dev and prod — with each person holding their own
6
+ revocable credentials. No secret is ever copied between people.
7
+
8
+ ## The rule that makes this safe
9
+
10
+ Each owner mints their **own** `ODLA_API_KEY`. You never send someone a
11
+ `.dev.vars`, a `.odla/credentials.local.json`, or a key over chat. The registry
12
+ records who co-owns an app; the db honors any co-owner when they provision.
13
+
14
+ ## Onboarding a co-owner
15
+
16
+ 1. **The primary owner adds them** (they must already be a signed-up odla
17
+ member — an admin invites them first if not):
18
+
19
+ ```cmd
20
+ npx @odla-ai/cli app owners add teammate@example.com
21
+ npx @odla-ai/cli app owners list
22
+ ```
23
+
24
+ (`npx @odla-ai/cli app owners remove teammate@example.com` revokes it. The
25
+ primary owner can't be removed. Studio's app **Settings** does the same.)
26
+
27
+ 2. **The co-owner provisions as themselves.** They clone the repo (which carries
28
+ `odla.config.mjs` but not the gitignored credentials) and run provision with
29
+ their *own* account email — the device grant is approved by them, not the
30
+ primary owner:
31
+
32
+ ```cmd
33
+ npx @odla-ai/cli provision --email teammate@example.com --write-dev-vars --push-secrets
34
+ ```
35
+
36
+ provision verifies the existing app (it does not re-create it), mints the
37
+ co-owner's own db/o11y credentials for the shared tenant, writes their local
38
+ `.dev.vars`, and transfers secrets to their Worker. They can now
39
+ `npm run dev` and, at the production checkpoint, deploy.
40
+
41
+ ## Production is one shared database
42
+
43
+ Every environment's tenant is the same across all owners (prod's tenant is the
44
+ bare app id; `dev` is `<appId>--dev`). So multiple co-owners deploying to
45
+ **production** all read and write the **same** prod database — each with their
46
+ own key. Treat first-prod provision/deploy as the usual human checkpoint
47
+ (`provision --dry-run` review, then `provision --yes --push-secrets`), and never
48
+ rotate another owner's credentials on their behalf.
49
+
50
+ ## If a co-owner loses their local key
51
+
52
+ Keys are shown once and stored hashed — there is no reveal. Re-mint instead:
53
+ re-run `provision` (or Studio's **mint API key**). Both work for any owner now,
54
+ not just the creator.