@odla-ai/cli 0.12.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -99,8 +99,8 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
99
99
  /** Stable, machine-readable division of work between the CLI, coding agent,
100
100
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
101
101
  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", "push db schema/rules 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 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"];
103
- 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"];
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"];
103
+ 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
104
  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
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"];
106
106
  };
@@ -195,6 +195,51 @@ type AppRules = Record<string, {
195
195
  update?: string;
196
196
  delete?: string;
197
197
  }>;
198
+ /** One natural-key row the CLI creates only when an integration has not
199
+ * already been configured. Existing owner-edited rows are never overwritten. */
200
+ interface IntegrationSeed {
201
+ /** Stable label used in dry-run output and the exactly-once mutation id. */
202
+ id: string;
203
+ /** Namespace containing the singleton/seed row. */
204
+ ns: string;
205
+ /** Declared-unique natural key used to detect an existing row and prevent
206
+ * a concurrent create from overwriting it. */
207
+ key: {
208
+ attr: string;
209
+ value: string;
210
+ };
211
+ /** Complete initial attributes; the key attribute may be omitted. */
212
+ attrs: Record<string, unknown>;
213
+ }
214
+ /** One unauthenticated deployed-app check performed by `odla-ai smoke`. */
215
+ interface IntegrationProbe {
216
+ /** Absolute path beneath the configured environment link. */
217
+ path: string;
218
+ /** Expected unauthenticated HTTP status, normally 401. */
219
+ expectedStatus: number;
220
+ }
221
+ /** Structural, data-only capability descriptor consumed from
222
+ * `odla.config.mjs`. Capability packages do not depend on the CLI; their
223
+ * descriptors only need to conform to this shape. */
224
+ interface OdlaIntegration {
225
+ /** Stable lowercase capability id, unique within one project. */
226
+ id: string;
227
+ /** Human-readable capability name for plans and diagnostics. */
228
+ title: string;
229
+ /** Package that supplies the capability. */
230
+ npm: string;
231
+ /** Serialized odla-db schema fragment merged by namespace. */
232
+ schema?: {
233
+ entities: Record<string, unknown>;
234
+ links?: Record<string, unknown>;
235
+ };
236
+ /** Rule fragment merged by namespace. */
237
+ rules?: AppRules;
238
+ /** Rows created after schema/rules provisioning only when absent. */
239
+ seeds?: IntegrationSeed[];
240
+ /** Read-only unauthenticated checks run against `links.<env>`. */
241
+ probes?: IntegrationProbe[];
242
+ }
198
243
  interface ClerkAuthConfig {
199
244
  publishableKey?: string;
200
245
  audience?: string;
@@ -237,6 +282,9 @@ interface OdlaProjectConfig {
237
282
  };
238
283
  envs?: OdlaEnvName[];
239
284
  services?: string[];
285
+ /** App capabilities composed into schema/rules/seeds. Integrations are npm
286
+ * modules, not hosted platform services, so they do not belong in services. */
287
+ integrations?: OdlaIntegration[];
240
288
  db?: {
241
289
  /** Inline SerializedSchema, JSON file, or JS module path exporting default/schema. */
242
290
  schema?: unknown;
@@ -345,6 +393,8 @@ interface ProvisionPlan {
345
393
  dbEndpoint: string;
346
394
  envs: string[];
347
395
  services: string[];
396
+ /** Configured app-capability ids in provisioning order. */
397
+ integrations: string[];
348
398
  hasSchema: boolean;
349
399
  hasRules: boolean;
350
400
  aiProvider?: string;
@@ -377,13 +427,14 @@ interface DoctorOptions {
377
427
  /**
378
428
  * Validate and summarize an odla project config entirely offline — no network
379
429
  * calls and no file writes. Loads `configPath`, builds the provision plan, and
380
- * resolves the schema and rules (synthesizing deny-all rules from the schema
381
- * when `db.rules` is omitted and `db.defaultRules` isn't `false`), then prints a
382
- * summary line for the app, envs, services, schema entity count, rules namespace
383
- * count, and AI provider.
430
+ * resolves and collision-checks app plus integration schema/rules (synthesizing
431
+ * deny-all rules when `db.rules` is omitted and `db.defaultRules` isn't
432
+ * `false`), then prints the app, envs, services, integrations, schema entity
433
+ * count, rules namespace count, and AI provider.
384
434
  *
385
435
  * It then collects warnings for the mistakes provision can't fix silently: a
386
- * schema with no entities, a rules namespace with no matching entity, the `ai`
436
+ * schema with no entities, a rules namespace with no matching entity, an
437
+ * integration with incomplete rules or a seed targeting an unknown namespace, the `ai`
387
438
  * service enabled without an `ai.provider`, `auth.clerk` entries that reference
388
439
  * an unset env var (`$FOO`), an `ai.keyEnv` that isn't set (provider key upload
389
440
  * will be skipped), and — when `o11y` is enabled — any env whose local
@@ -441,8 +492,9 @@ declare function initProject(options: InitOptions): void;
441
492
  * developer token, creates the registry app when absent, enables each service
442
493
  * per env (AI also gets `setAi` with the configured provider/model), configures
443
494
  * Clerk auth and links, then per env mints or reuses credentials only for the
444
- * configured services, pushes the schema with the db key and the
445
- * rules with the developer token, and stores the provider key in the tenant
495
+ * configured services, collision-checks and merges integration schema/rules,
496
+ * pushes the composed schema with the db key and rules with the developer
497
+ * token, creates natural-key integration seeds only when absent, and stores the provider key in the tenant
446
498
  * vault when `ai.keyEnv` is set and present. Writes the credentials file
447
499
  * (mode 0600, gitignored) and, when requested, `.dev.vars`. Google Calendar
448
500
  * consent runs last, per env; when the platform connector itself is not yet
@@ -789,9 +841,10 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
789
841
  *
790
842
  * It then makes real network calls: fetches the registry public-config (and, when
791
843
  * `ai.provider` is configured, asserts the live provider matches), fetches the
792
- * live db schema with the db key and asserts every entity from the local schema
793
- * is present, and runs a `count` aggregate against the first entity to confirm
794
- * the db answers queries. Progress lines are printed and it ends with `ok`.
844
+ * live db schema with the db key and asserts every entity from the composed app
845
+ * plus integration schema is present, runs a `count` aggregate against the
846
+ * first entity, and checks each integration's deployed route probe anonymously
847
+ * against `links.<env>`. Progress lines are printed and it ends with `ok`.
795
848
  * Read-only — it writes nothing and throws on the first mismatch or failed
796
849
  * request.
797
850
  *
@@ -802,4 +855,4 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
802
855
  */
803
856
  declare function smoke(options: SmokeOptions): Promise<void>;
804
857
 
805
- 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 ListGitHubSecuritySourcesOptions, type ListHostedSecurityJobsOptions, type LoadedProjectConfig, type LocalCredentials, 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 };
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 };
package/dist/index.d.ts CHANGED
@@ -99,8 +99,8 @@ declare function adminAi(options: AdminAiOptions): Promise<void>;
99
99
  /** Stable, machine-readable division of work between the CLI, coding agent,
100
100
  * human operator, and Studio. Printed by `odla-ai capabilities --json`. */
101
101
  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", "push db schema/rules 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 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"];
103
- 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"];
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"];
103
+ 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
104
  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
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"];
106
106
  };
@@ -195,6 +195,51 @@ type AppRules = Record<string, {
195
195
  update?: string;
196
196
  delete?: string;
197
197
  }>;
198
+ /** One natural-key row the CLI creates only when an integration has not
199
+ * already been configured. Existing owner-edited rows are never overwritten. */
200
+ interface IntegrationSeed {
201
+ /** Stable label used in dry-run output and the exactly-once mutation id. */
202
+ id: string;
203
+ /** Namespace containing the singleton/seed row. */
204
+ ns: string;
205
+ /** Declared-unique natural key used to detect an existing row and prevent
206
+ * a concurrent create from overwriting it. */
207
+ key: {
208
+ attr: string;
209
+ value: string;
210
+ };
211
+ /** Complete initial attributes; the key attribute may be omitted. */
212
+ attrs: Record<string, unknown>;
213
+ }
214
+ /** One unauthenticated deployed-app check performed by `odla-ai smoke`. */
215
+ interface IntegrationProbe {
216
+ /** Absolute path beneath the configured environment link. */
217
+ path: string;
218
+ /** Expected unauthenticated HTTP status, normally 401. */
219
+ expectedStatus: number;
220
+ }
221
+ /** Structural, data-only capability descriptor consumed from
222
+ * `odla.config.mjs`. Capability packages do not depend on the CLI; their
223
+ * descriptors only need to conform to this shape. */
224
+ interface OdlaIntegration {
225
+ /** Stable lowercase capability id, unique within one project. */
226
+ id: string;
227
+ /** Human-readable capability name for plans and diagnostics. */
228
+ title: string;
229
+ /** Package that supplies the capability. */
230
+ npm: string;
231
+ /** Serialized odla-db schema fragment merged by namespace. */
232
+ schema?: {
233
+ entities: Record<string, unknown>;
234
+ links?: Record<string, unknown>;
235
+ };
236
+ /** Rule fragment merged by namespace. */
237
+ rules?: AppRules;
238
+ /** Rows created after schema/rules provisioning only when absent. */
239
+ seeds?: IntegrationSeed[];
240
+ /** Read-only unauthenticated checks run against `links.<env>`. */
241
+ probes?: IntegrationProbe[];
242
+ }
198
243
  interface ClerkAuthConfig {
199
244
  publishableKey?: string;
200
245
  audience?: string;
@@ -237,6 +282,9 @@ interface OdlaProjectConfig {
237
282
  };
238
283
  envs?: OdlaEnvName[];
239
284
  services?: string[];
285
+ /** App capabilities composed into schema/rules/seeds. Integrations are npm
286
+ * modules, not hosted platform services, so they do not belong in services. */
287
+ integrations?: OdlaIntegration[];
240
288
  db?: {
241
289
  /** Inline SerializedSchema, JSON file, or JS module path exporting default/schema. */
242
290
  schema?: unknown;
@@ -345,6 +393,8 @@ interface ProvisionPlan {
345
393
  dbEndpoint: string;
346
394
  envs: string[];
347
395
  services: string[];
396
+ /** Configured app-capability ids in provisioning order. */
397
+ integrations: string[];
348
398
  hasSchema: boolean;
349
399
  hasRules: boolean;
350
400
  aiProvider?: string;
@@ -377,13 +427,14 @@ interface DoctorOptions {
377
427
  /**
378
428
  * Validate and summarize an odla project config entirely offline — no network
379
429
  * calls and no file writes. Loads `configPath`, builds the provision plan, and
380
- * resolves the schema and rules (synthesizing deny-all rules from the schema
381
- * when `db.rules` is omitted and `db.defaultRules` isn't `false`), then prints a
382
- * summary line for the app, envs, services, schema entity count, rules namespace
383
- * count, and AI provider.
430
+ * resolves and collision-checks app plus integration schema/rules (synthesizing
431
+ * deny-all rules when `db.rules` is omitted and `db.defaultRules` isn't
432
+ * `false`), then prints the app, envs, services, integrations, schema entity
433
+ * count, rules namespace count, and AI provider.
384
434
  *
385
435
  * It then collects warnings for the mistakes provision can't fix silently: a
386
- * schema with no entities, a rules namespace with no matching entity, the `ai`
436
+ * schema with no entities, a rules namespace with no matching entity, an
437
+ * integration with incomplete rules or a seed targeting an unknown namespace, the `ai`
387
438
  * service enabled without an `ai.provider`, `auth.clerk` entries that reference
388
439
  * an unset env var (`$FOO`), an `ai.keyEnv` that isn't set (provider key upload
389
440
  * will be skipped), and — when `o11y` is enabled — any env whose local
@@ -441,8 +492,9 @@ declare function initProject(options: InitOptions): void;
441
492
  * developer token, creates the registry app when absent, enables each service
442
493
  * per env (AI also gets `setAi` with the configured provider/model), configures
443
494
  * Clerk auth and links, then per env mints or reuses credentials only for the
444
- * configured services, pushes the schema with the db key and the
445
- * rules with the developer token, and stores the provider key in the tenant
495
+ * configured services, collision-checks and merges integration schema/rules,
496
+ * pushes the composed schema with the db key and rules with the developer
497
+ * token, creates natural-key integration seeds only when absent, and stores the provider key in the tenant
446
498
  * vault when `ai.keyEnv` is set and present. Writes the credentials file
447
499
  * (mode 0600, gitignored) and, when requested, `.dev.vars`. Google Calendar
448
500
  * consent runs last, per env; when the platform connector itself is not yet
@@ -789,9 +841,10 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
789
841
  *
790
842
  * It then makes real network calls: fetches the registry public-config (and, when
791
843
  * `ai.provider` is configured, asserts the live provider matches), fetches the
792
- * live db schema with the db key and asserts every entity from the local schema
793
- * is present, and runs a `count` aggregate against the first entity to confirm
794
- * the db answers queries. Progress lines are printed and it ends with `ok`.
844
+ * live db schema with the db key and asserts every entity from the composed app
845
+ * plus integration schema is present, runs a `count` aggregate against the
846
+ * first entity, and checks each integration's deployed route probe anonymously
847
+ * against `links.<env>`. Progress lines are printed and it ends with `ok`.
795
848
  * Read-only — it writes nothing and throws on the first mismatch or failed
796
849
  * request.
797
850
  *
@@ -802,4 +855,4 @@ declare function installSkill(options?: SkillInstallOptions): SkillInstallResult
802
855
  */
803
856
  declare function smoke(options: SmokeOptions): Promise<void>;
804
857
 
805
- 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 ListGitHubSecuritySourcesOptions, type ListHostedSecurityJobsOptions, type LoadedProjectConfig, type LocalCredentials, 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 };
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 };
package/dist/index.js CHANGED
@@ -38,7 +38,7 @@ import {
38
38
  secretsSetClerkKey,
39
39
  smoke,
40
40
  startHostedSecurityJob
41
- } from "./chunk-Y4HWUEFF.js";
41
+ } from "./chunk-I7XDJZB6.js";
42
42
  export {
43
43
  AGENT_HARNESSES,
44
44
  CAPABILITIES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odla-ai/cli",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "description": "Agent-operable CLI for odla provisioning, calendar consent and sync lifecycle, System AI administration, Worker secrets, security jobs, and smoke checks.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://odla.ai/docs/packages/cli",
@@ -57,7 +57,7 @@
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
62
  "@odla-ai/db": "^0.6.4",
63
63
  "@odla-ai/security": "^0.3.1"
@@ -102,7 +102,8 @@ guessing which platform/credential steps need manual work. Then:
102
102
  persisted, so once the human approves, re-run the same command and it
103
103
  resumes the same code and collects the token. It creates the app,
104
104
  enables services, issues or reuses configured credentials (db key + o11y
105
- ingest token when enabled), pushes schema + rules, writes `.dev.vars`, and
105
+ ingest token when enabled), composes declared integration schema/rules and
106
+ guarded seeds, writes `.dev.vars`, and
106
107
  transfers Worker secrets through Wrangler stdin. With calendar enabled it
107
108
  then prints a second, server-issued Google URL; the human grants booking
108
109
  consent in a browser and the connection is immediately live — nothing
@@ -134,8 +135,9 @@ requires `--yes` and removes only this connection's sealed grant — Google
134
135
  keeps every booked event.
135
136
 
136
137
  The CLI owns deterministic platform work from `odla.config.mjs`: service
137
- enablement, credential issuance/storage, `.dev.vars`, and Wrangler secret
138
- transfer. You own source changes — install `@odla-ai/o11y`, add
138
+ enablement, integration schema/rules/seeds, credential issuance/storage,
139
+ `.dev.vars`, and Wrangler secret transfer. You own source changes — install
140
+ runtime capability packages, mount their routes, supply authorization, add
139
141
  `withObservability`, create the Wrangler config, and choose application-specific
140
142
  signals. The human owns device approval, production consent, and explicit
141
143
  destructive rotation. If an
@@ -15,6 +15,12 @@ deny-all rules from the schema. To turn on auth/observability, add `"o11y"` to
15
15
  `services` and an `auth.clerk` block in `odla.config.mjs` (init leaves it
16
16
  commented).
17
17
 
18
+ For an npm app capability such as `@odla-ai/crm`, import its data-only
19
+ descriptor into `odla.config.mjs` and add it under `integrations`; do not add
20
+ the capability id to `services`. Provision collision-checks and merges its
21
+ schema/rules, creates guarded seeds only when absent, and leaves runtime package
22
+ installation and route mounting to the source step.
23
+
18
24
  For Google Calendar booking, include both `"db"` and `"calendar"`. Configure
19
25
  `calendar.google.availabilityCalendars` for every env (start with
20
26
  `"primary"`; 1–10 per env) and optionally `bookingCalendar` (defaults to the
@@ -50,10 +56,11 @@ Prints a short device code and a link. ⏸ That same account opens the link, sig
50
56
  in, explicitly reviews the exact code, and approves it — loading the URL alone
51
57
  does not claim access, and no secret passes through the chat. Provision then:
52
58
  creates the app, enables its services, issues or reuses the db key (and the
53
- o11y ingest token when o11y is enabled), pushes schema + rules, writes
59
+ o11y ingest token when o11y is enabled), pushes the composed app + integration
60
+ schema/rules, creates missing guarded seeds, writes
54
61
  `.dev.vars`, and transfers configured Worker secrets through Wrangler stdin.
55
62
  Local credential files are `0600` and gitignored. Verify with
56
- `npx @odla-ai/cli doctor` — it prints the app, envs, services, and flags
63
+ `npx @odla-ai/cli doctor` — it prints the app, envs, services, integrations, and flags
57
64
  anything unset. `--push-secrets` preflights the Wrangler config and login before
58
65
  issuing or rotating a shown-once credential.
59
66
 
@@ -83,6 +83,31 @@ await ai.chat({ messages }); // provider/model + key resolved from the platform
83
83
  No API key in your code or env — it lives in the tenant vault; `provision`
84
84
  stores it when the configured `ai.keyEnv` is set at provision time.
85
85
 
86
+ ## @odla-ai/crm — records, pipelines, follow-ups, and contactability
87
+
88
+ Define the CRM once in an app module, mount `createCrmRoutes` in trusted Worker
89
+ code behind the app's admin authorization, and render the optional admin kit
90
+ from `@odla-ai/crm/ui`. Declare `createCrmIntegration(crm, options)` under
91
+ `odla.config.mjs` `integrations`—never under `services`.
92
+
93
+ ```ts
94
+ import { createCrmIntegration } from "@odla-ai/crm";
95
+ import { crm } from "./src/crm.js";
96
+
97
+ export default {
98
+ app: { id: "my-app", name: "My App" },
99
+ services: ["db"],
100
+ integrations: [createCrmIntegration(crm, { basePath: "/api/crm" })],
101
+ links: { dev: "https://dev.example.com" },
102
+ };
103
+ ```
104
+
105
+ Provision merges the CRM schema/rules and creates `crm_config` only when
106
+ absent. Doctor checks the composed contract offline; smoke calls the records
107
+ route anonymously and requires `401`. The CLI does not edit the Worker or
108
+ invent `authorize`. Billing is an optional injected `BillingProvider`; reuse
109
+ app-owned payment code when present rather than assuming another package.
110
+
86
111
  ## @odla-ai/o11y — observability (Cloudflare Workers)
87
112
 
88
113
  ```ts
@@ -11,8 +11,8 @@ opens the review page in interactive terminals; loading it alone is inert.
11
11
 
12
12
  ## Steps
13
13
 
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`.
14
+ 1. Require `npm view @odla-ai/cli@0.13.0 version` to succeed, then run
15
+ `npm i -D --save-exact @odla-ai/cli@0.13.0` and `npm i @odla-ai/db`.
16
16
  2. `npx @odla-ai/cli init --app-id <id> --name "<Name>" --env dev --services db`
17
17
  Review `odla.config.mjs`. Keep `envs: ["dev"]` — prod is Phase 5. Set
18
18
  `links.dev` to the URL the Phase 1 `wrangler deploy` **actually printed** —