@happyvertical/smrt-config 0.51.32 → 0.51.34

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/types.d.ts CHANGED
@@ -1,858 +1,711 @@
1
- import { DomainKnowledgeConfig } from '@happyvertical/smrt-types';
2
-
3
- /** Canonical config stored at `runtime` in `smrt.config.ts`. */
4
- declare interface ApplicationRuntimeConfig {
5
- profile: ApplicationRuntimeProfile;
6
- providers?: RuntimeProviderOverrides;
7
- }
8
-
9
- /**
10
- * Stable application-runtime profile contract.
11
- *
12
- * Profiles select infrastructure composition only. Domain models, generated
13
- * surfaces, effect metadata, and approval policy are deliberately outside the
14
- * override surface so moving an application cannot silently change behavior.
15
- */
16
- declare type ApplicationRuntimeProfile = 'local' | 'self-hosted' | 'cloud';
17
-
18
- declare type AssetOwnership = 'user' | 'operator' | 'managed';
19
-
20
- declare type AssetStorageProvider = 'local-files' | 's3-compatible' | 'managed-object-storage';
21
-
22
- declare type AuthenticationProvider = 'owner-bootstrap' | 'oidc' | 'magic-link' | 'hosted-identity';
23
-
24
- /**
25
- * CLI package configuration.
26
- *
27
- * Placed under the `cli` key in `smrt.config.js`. Consumed by
28
- * `@happyvertical/smrt-cli` for `smrt db:*` and migration commands.
29
- *
30
- * @example
31
- * ```js
32
- * export default defineConfig({
33
- * cli: {
34
- * database: { type: 'sqlite', url: 'file:./local.db' },
35
- * migrations: { mode: 'dynamic', directory: './migrations' },
36
- * },
37
- * });
38
- * ```
39
- *
40
- * @see {@link DatabaseConfig}
41
- * @see {@link MigrationsConfig}
42
- */
43
- export declare interface CliConfig {
44
- /**
45
- * Database connection settings
46
- */
47
- database?: DatabaseConfig;
48
- /**
49
- * Migration settings
50
- */
51
- migrations?: MigrationsConfig;
52
- /**
53
- * Required manifest/object/field/database-shape contract for schema commands.
54
- */
55
- schemaContract?: SchemaContractConfig;
56
- }
57
-
58
- declare type ConnectionOwnership = 'user' | 'operator' | 'managed';
59
-
60
- /**
61
- * Database connection configuration for CLI commands.
62
- *
63
- * Placed under `cli.database` in `smrt.config.js`. Used by
64
- * `@happyvertical/smrt-cli` to connect for migration and inspection commands.
65
- *
66
- * @see {@link CliConfig}
67
- */
68
- export declare interface DatabaseConfig {
69
- /**
70
- * Database type
71
- *
72
- * @default 'sqlite'
73
- */
74
- type?: 'sqlite' | 'postgres' | 'duckdb';
75
- /**
76
- * Database connection URL
77
- *
78
- * For SQLite: file path or ':memory:'
79
- * For PostgreSQL: postgresql://user:pass@host:port/dbname
80
- */
81
- url?: string;
82
- }
83
-
84
- declare type DatabaseEngine = 'sqlite' | 'postgres';
85
-
86
- /**
87
- * Export configuration for static site generation.
88
- *
89
- * Placed under the `export` key in `smrt.config.js`. Controls how database
90
- * records are exported to static files during SSG builds. Each additional
91
- * key beyond `fieldExportDefault` and `format` defines a named export file.
92
- *
93
- * @example
94
- * ```js
95
- * export default defineConfig({
96
- * export: {
97
- * fieldExportDefault: true,
98
- * articles: { types: ['Article'], filters: { status: ['published'] } },
99
- * games: { types: ['Game'], orderBy: '-date', format: 'ndjson' },
100
- * },
101
- * });
102
- * ```
103
- *
104
- * @see {@link ExportFileConfig}
105
- * @see {@link exportConfig}
106
- */
107
- export declare interface ExportConfig {
108
- /**
109
- * Default export behavior for fields without explicit `exported` annotation
110
- *
111
- * - true: Export all fields by default (simpler, for most sites)
112
- * - false: Only export fields with explicit `exported: true`
113
- *
114
- * @default true
115
- */
116
- fieldExportDefault?: boolean;
117
- /**
118
- * Default output format for all exports
119
- * @default 'json'
120
- */
121
- format?: 'json' | 'ndjson' | 'csv' | 'sqlite';
122
- /**
123
- * Export file configurations
124
- * Keys become filenames (e.g., 'contents' -> 'contents.json')
125
- */
126
- [filename: string]: ExportFileConfig | boolean | string | undefined;
127
- }
128
-
129
- /**
130
- * Configuration for a single SSG export file.
131
- *
132
- * Each key in {@link ExportConfig} (besides `fieldExportDefault` and `format`)
133
- * becomes the output filename. Records are queried from the database, filtered,
134
- * ordered, and written to `{key}.json` (or the specified format).
135
- *
136
- * @example
137
- * ```js
138
- * export default defineConfig({
139
- * export: {
140
- * articles: {
141
- * types: ['Article'],
142
- * filters: { status: ['published'] },
143
- * orderBy: '-publishDate',
144
- * limit: 500,
145
- * },
146
- * },
147
- * });
148
- * ```
149
- *
150
- * @see {@link ExportConfig}
151
- * @see {@link ExportFilterValue}
152
- */
153
- export declare interface ExportFileConfig {
154
- /**
155
- * SMRT object types to include in this export
156
- * Uses className (e.g., 'MeetingRecap', 'Game')
157
- */
158
- types: string[];
159
- /**
160
- * Field whitelist - only export these fields
161
- * If specified, overrides exclude and fieldExportDefault
162
- */
163
- include?: string[];
164
- /**
165
- * Field blacklist - exclude these fields
166
- * Applied after schema-level exported: false check
167
- */
168
- exclude?: string[];
169
- /**
170
- * Filters to apply when querying records
171
- * Keys are field names, values are filter conditions
172
- *
173
- * @example
174
- * filters: {
175
- * status: ['published'], // shorthand for status IN ('published')
176
- * publish_date: { gte: '2025-01-01' },
177
- * council_slug: ['town-of-bentley'],
178
- * }
179
- */
180
- filters?: Record<string, string[] | number[] | ExportFilterValue>;
181
- /**
182
- * Output format for this file
183
- * @default 'json'
184
- */
185
- format?: 'json' | 'ndjson' | 'csv' | 'sqlite';
186
- /**
187
- * Field to order by
188
- * Prefix with '-' for descending (e.g., '-publish_date')
189
- */
190
- orderBy?: string;
191
- /**
192
- * Maximum records per file
193
- * If exceeded, creates paginated files (e.g., contents-1.json, contents-2.json)
194
- */
195
- limit?: number;
196
- /**
197
- * Create separate files per unique value of this field
198
- * e.g., shardBy: 'year' creates contents-2024.json, contents-2025.json
199
- */
200
- shardBy?: string;
201
- }
202
-
203
- /**
204
- * Filter operators for export queries.
205
- *
206
- * Used as values in {@link ExportFileConfig.filters} to build SQL `WHERE`
207
- * clauses when exporting records to static files.
208
- *
209
- * @example
210
- * ```js
211
- * filters: {
212
- * publishDate: { gte: '2025-01-01', lt: '2026-01-01' },
213
- * status: { in: ['published', 'featured'] },
214
- * }
215
- * ```
216
- *
217
- * @see {@link ExportFileConfig}
218
- */
219
- export declare interface ExportFilterValue {
220
- /** Equals (shorthand: just the value) */
221
- eq?: string | number | boolean;
222
- /** Not equals */
223
- ne?: string | number | boolean;
224
- /** Greater than */
225
- gt?: string | number;
226
- /** Greater than or equal */
227
- gte?: string | number;
228
- /** Less than */
229
- lt?: string | number;
230
- /** Less than or equal */
231
- lte?: string | number;
232
- /** In array */
233
- in?: (string | number)[];
234
- /** Contains (text) */
235
- contains?: string;
236
- }
237
-
238
- declare type JobTopology = 'inline' | 'embedded' | 'external' | 'scalable';
239
-
240
- /**
241
- * Options accepted by {@link loadConfig}.
242
- *
243
- * All fields are optional; omitting them triggers cosmiconfig's default
244
- * search behaviour (scan `cwd` upward for `smrt.config.{js,mjs,cjs,json}`).
245
- */
246
- export declare interface LoadConfigOptions {
247
- /**
248
- * Absolute or relative path to a specific config file.
249
- * When provided, cosmiconfig loads this file directly instead of searching.
250
- */
251
- configPath?: string;
252
- /**
253
- * Whether to search parent directories when no config is found in `cwd`.
254
- *
255
- * @default true
256
- */
257
- searchParents?: boolean;
258
- /**
259
- * Directory to start the config search from. Defaults to `process.cwd()`.
260
- * Ignored when `configPath` is provided. Useful for tests and for tools that
261
- * resolve config relative to a project root other than the current directory.
262
- */
263
- searchFrom?: string;
264
- /**
265
- * Whether to cache the loaded config in `globalThis.__smrtLoaderCachedConfig`.
266
- * Disable for test isolation or hot-reload scenarios.
267
- *
268
- * @default true
269
- */
270
- cache?: boolean;
271
- }
272
-
273
- /**
274
- * Database migrations configuration.
275
- *
276
- * Controls how migrations are generated, stored, and applied. Placed under
277
- * the `cli.migrations` key in `smrt.config.js` and consumed by
278
- * `@happyvertical/smrt-cli` migration commands (`smrt db:migrate`, etc.).
279
- *
280
- * @see {@link CliConfig}
281
- */
282
- export declare interface MigrationsConfig {
283
- /**
284
- * Directory for migration files (relative to project root)
285
- *
286
- * @default './migrations'
287
- */
288
- directory?: string;
289
- /**
290
- * Table name for tracking applied migrations
291
- *
292
- * @default '_smrt_schema_migrations'
293
- */
294
- table?: string;
295
- /**
296
- * Legacy file format setting. File-backed migration generation is not supported.
297
- *
298
- * @default 'sql'
299
- */
300
- format?: 'sql' | 'typescript';
301
- /**
302
- * Migration file naming strategy
303
- *
304
- * - 'sequence': Sequential numbers (0001, 0002, ...)
305
- * - 'timestamp': Unix timestamp-based (20240115143052)
306
- *
307
- * @default 'sequence'
308
- */
309
- naming?: 'sequence' | 'timestamp';
310
- /**
311
- * Migration mode.
312
- *
313
- * SMRT schema migrations are manifest-driven. File-backed modes are not
314
- * supported unless a future file migration executor is implemented.
315
- *
316
- * @default 'dynamic'
317
- */
318
- mode?: 'dynamic';
319
- /**
320
- * Configure mode per environment.
321
- *
322
- * Overrides the `mode` setting based on NODE_ENV
323
- */
324
- modeByEnvironment?: {
325
- development?: 'dynamic';
326
- test?: 'dynamic';
327
- staging?: 'dynamic';
328
- production?: 'dynamic';
329
- };
330
- /**
331
- * Automatically generate DOWN scripts where safe
332
- *
333
- * Some operations (DROP COLUMN) may lose data and should be reviewed.
334
- *
335
- * @default true
336
- */
337
- autoGenerateDown?: boolean;
338
- /**
339
- * PostgreSQL-specific settings
340
- */
341
- postgres?: MigrationsPostgresConfig;
342
- }
343
-
344
- /**
345
- * PostgreSQL-specific migration settings.
346
- *
347
- * Nested under `migrations.postgres` in {@link MigrationsConfig}.
348
- */
349
- export declare interface MigrationsPostgresConfig {
350
- /**
351
- * Allow `CREATE INDEX CONCURRENTLY` when concurrent-index mode is requested
352
- * with `smrt db:migrate --postgres-safe`.
353
- *
354
- * Concurrent builds avoid the batch's table locks but cannot run inside a
355
- * transaction, so that mode is not atomic. Setting this to `false` vetoes
356
- * the flag: index DDL then stays inside the atomic transaction, still bounded
357
- * by the timeouts below. The flag is the opt-in — this key alone does not
358
- * enable concurrent mode.
359
- *
360
- * @default true
361
- */
362
- useConcurrently?: boolean;
363
- /**
364
- * `lock_timeout` applied to every PostgreSQL migration statement.
365
- *
366
- * Accepts a bare millisecond count or an `ms`/`s`/`min`/`h` suffix. `'0'`
367
- * disables the timeout, as PostgreSQL defines it.
368
- *
369
- * @default '30s'
370
- */
371
- lockTimeout?: string;
372
- /**
373
- * `statement_timeout` applied to every PostgreSQL migration statement.
374
- *
375
- * Same accepted forms as {@link MigrationsPostgresConfig.lockTimeout}.
376
- *
377
- * @default '60s'
378
- */
379
- statementTimeout?: string;
380
- }
381
-
382
- declare type NetworkExposure = 'loopback' | 'public';
383
-
384
- declare type OwnerBootstrapMode = 'single-use' | 'disabled';
385
-
386
- /** PostgreSQL ACL contract. Applied only through explicit db:permissions. */
387
- export declare interface PostgresPermissionsConfig {
388
- schema: string;
389
- /** Assert this schema is dedicated to the managed application. */
390
- schemaExclusive: true;
391
- migrationOwner: string;
392
- runtimeRole: string;
393
- /** Additional managed tables beyond discovered models and present system tables. */
394
- managedTables?: string[];
395
- /** Existing operator-owned tables retained outside the runtime data surface. */
396
- retainedTables?: string[];
397
- /** Exact zero-argument trigger functions bound only to managed tables. */
398
- managedTriggerFunctions?: string[];
399
- /** Explicit safe monitoring columns; there is no default table-wide access. */
400
- monitor?: {
401
- role: string;
402
- tables: Record<string, string[]>;
403
- };
404
- }
405
-
406
- declare interface RuntimeAssetProvider {
407
- readonly provider: AssetStorageProvider;
408
- readonly ownership: AssetOwnership;
409
- }
410
-
411
- declare interface RuntimeAuthenticationProvider {
412
- readonly provider: AuthenticationProvider;
413
- readonly ownerBootstrap: OwnerBootstrapMode;
414
- }
415
-
416
- declare interface RuntimeDatabaseProvider {
417
- readonly engine: DatabaseEngine;
418
- readonly connectionOwnership: ConnectionOwnership;
419
- }
420
-
421
- declare interface RuntimeJobProvider {
422
- readonly topology: JobTopology;
423
- }
424
-
425
- declare interface RuntimeNetworkProvider {
426
- readonly exposure: NetworkExposure;
427
- readonly tls: boolean;
428
- }
429
-
430
- /**
431
- * Explicit provider changes layered over a profile's safe preset.
432
- *
433
- * Every override is revalidated with the completed composition. Capability and
434
- * surface-policy fields are intentionally absent: providers cannot use this
435
- * seam to weaken cross-profile invariants.
436
- */
437
- declare interface RuntimeProviderOverrides {
438
- database?: Partial<RuntimeDatabaseProvider>;
439
- authentication?: Partial<RuntimeAuthenticationProvider>;
440
- tenancy?: Partial<RuntimeTenancyProvider>;
441
- assets?: Partial<RuntimeAssetProvider>;
442
- secrets?: Partial<RuntimeSecretProvider>;
443
- jobs?: Partial<RuntimeJobProvider>;
444
- network?: Partial<RuntimeNetworkProvider>;
445
- }
446
-
447
- declare interface RuntimeSecretProvider {
448
- readonly provider: SecretProvider;
449
- readonly ownership: SecretOwnership;
450
- }
451
-
452
- declare interface RuntimeTenancyProvider {
453
- readonly mode: TenancyMode;
454
- readonly context: TenantContextMode;
455
- readonly isolation: TenantIsolation;
456
- }
457
-
458
- /**
459
- * Semantic schema contract enforced by SMRT schema commands.
460
- *
461
- * Object and field requirements are checked against the loaded SMRT registry.
462
- * Required fields are also translated to physical table/column checks after
463
- * migration/status introspection. `requiredDatabaseShape` is reserved for
464
- * database objects that SMRT cannot infer from manifests.
465
- */
466
- export declare interface SchemaContractConfig {
467
- requiredObjects?: string[];
468
- requiredFields?: string[];
469
- requiredDatabaseShape?: {
470
- tables?: string[];
471
- columns?: string[];
472
- indexes?: string[];
473
- };
474
- }
475
-
476
- declare type SecretOwnership = 'user' | 'operator' | 'managed';
477
-
478
- declare type SecretProvider = 'local-file' | 'environment' | 'external' | 'managed';
479
-
480
- /**
481
- * Site identity and configuration for SMRT site templates.
482
- *
483
- * Placed under the `site` key in `smrt.config.js`. Retrieved at runtime
484
- * via {@link getSiteConfig}. Used by site templates
485
- * (`template-sveltekit`, `template-site-static-json`) to define name,
486
- * description, navigation, location, and theme.
487
- *
488
- * @example
489
- * ```js
490
- * export default defineConfig({
491
- * site: {
492
- * name: 'Bentley Alberta',
493
- * description: 'Community news for Bentley, AB',
494
- * url: 'https://bentley.ca',
495
- * location: { name: 'Bentley', latitude: 52.4, longitude: -113.9, timezone: 'America/Edmonton' },
496
- * navigation: { primary: [{ label: 'Home', href: '/' }] },
497
- * },
498
- * });
499
- * ```
500
- *
501
- * @see {@link getSiteConfig}
502
- * @see {@link SiteLocation}
503
- * @see {@link SiteNavigation}
504
- * @see {@link SiteTheme}
505
- */
506
- export declare interface SiteConfig {
507
- /** Full site name (e.g., "Bentley Alberta") */
508
- name: string;
509
- /** Short name for mobile/compact displays */
510
- shortName?: string;
511
- /** Site description for SEO */
512
- description: string;
513
- /** Production URL */
514
- url?: string;
515
- /** Contact email for the site */
516
- contactEmail?: string;
517
- /** Publisher/organization info */
518
- publisher?: SitePublisher;
519
- /** Geographic location */
520
- location: SiteLocation;
521
- /** Navigation structure */
522
- navigation: SiteNavigation;
523
- /** Theme/branding */
524
- theme?: SiteTheme;
525
- /** Additional metadata */
526
- meta?: {
527
- /** Theme color for mobile browsers */
528
- themeColor?: string;
529
- /** Open Graph locale */
530
- ogLocale?: string;
531
- /** Google Tag Manager ID */
532
- gtmId?: string;
533
- };
534
- }
535
-
536
- /**
537
- * Geographic location for the site, used for proximity search and display.
538
- *
539
- * @see {@link SiteConfig}
540
- */
541
- export declare interface SiteLocation {
542
- /** Display name (e.g., "Bentley" or "Bentley, AB") */
543
- name: string;
544
- /** Latitude coordinate */
545
- latitude: number;
546
- /** Longitude coordinate */
547
- longitude: number;
548
- /** IANA timezone (e.g., "America/Edmonton") */
549
- timezone: string;
550
- }
551
-
552
- /**
553
- * Site navigation structure containing primary and optional footer links.
554
- *
555
- * @see {@link SiteConfig}
556
- * @see {@link SiteNavigationLink}
557
- */
558
- export declare interface SiteNavigation {
559
- /** Primary navigation links (header) */
560
- primary: SiteNavigationLink[];
561
- /** Footer navigation links */
562
- footer?: SiteNavigationLink[];
563
- }
564
-
565
- /**
566
- * A single navigation link item used in site menus.
567
- *
568
- * @see {@link SiteNavigation}
569
- */
570
- export declare interface SiteNavigationLink {
571
- label: string;
572
- href: string;
573
- icon?: string;
574
- }
575
-
576
- /**
577
- * Publisher or organization information displayed in site footers and metadata.
578
- *
579
- * @see {@link SiteConfig}
580
- */
581
- export declare interface SitePublisher {
582
- /** Organization name (e.g., "Blindman Press") */
583
- name: string;
584
- /** Organization website URL */
585
- url?: string;
586
- /** GitHub organization URL */
587
- github?: string;
588
- }
589
-
590
- /**
591
- * Site theme and branding color palette.
592
- *
593
- * Colors should be provided as CSS hex values (e.g., `'#3b82f6'`).
594
- *
595
- * @see {@link SiteConfig}
596
- */
597
- export declare interface SiteTheme {
598
- /** Primary brand color (hex) */
599
- primaryColor: string;
600
- /** Light variant of primary color */
601
- primaryLight?: string;
602
- /** Dark variant of primary color */
603
- primaryDark?: string;
604
- }
605
-
606
- /**
607
- * Root SMRT configuration structure.
608
- *
609
- * This is the shape of the object returned by `smrt.config.{js,ts,json}` and
610
- * consumed by {@link loadConfig}. Use {@link defineConfig} for type-safe
611
- * authoring with IDE auto-completion.
612
- *
613
- * Priority order (highest to lowest):
614
- * 1. Runtime overrides set via {@link setConfig}
615
- * 2. File-based config loaded by {@link loadConfig}
616
- * 3. Defaults passed to {@link getModuleConfig} / {@link getPackageConfig}
617
- *
618
- * @example
619
- * ```js
620
- * // smrt.config.js
621
- * import { defineConfig } from '@happyvertical/smrt-config';
622
- *
623
- * export default defineConfig({
624
- * smrt: { logLevel: 'info', environment: 'production' },
625
- * site: { name: 'My Site', ... },
626
- * modules: { praeco: { rssLimit: 50 } },
627
- * packages: { ai: { defaultModel: 'gpt-4o' } },
628
- * });
629
- * ```
630
- *
631
- * @see {@link loadConfig}
632
- * @see {@link defineConfig}
633
- * @see {@link SmrtGlobalConfig}
634
- */
635
- export declare interface SmrtConfig {
636
- /** Global SMRT framework options — lowest-priority base for all modules. */
637
- smrt?: SmrtGlobalConfig;
638
- /** Site identity and configuration (for site templates). */
639
- site?: SiteConfig;
640
- /** Export configuration for static site generation. */
641
- export?: ExportConfig;
642
- /** Domain-scoped agent/developer knowledge generation and exposure. */
643
- knowledge?: DomainKnowledgeConfig;
644
- /** Validated application infrastructure composition. */
645
- runtime?: ApplicationRuntimeConfig;
646
- /**
647
- * Module-scoped configurations keyed by module name.
648
- * Retrieved via {@link getModuleConfig}.
649
- */
650
- modules?: {
651
- [moduleName: string]: Record<string, unknown>;
652
- };
653
- /**
654
- * Package-scoped configurations keyed by package name.
655
- * Retrieved via {@link getPackageConfig}.
656
- */
657
- packages?: {
658
- [packageName: string]: Record<string, unknown>;
659
- };
660
- }
661
-
662
- /**
663
- * Global SMRT framework options that apply to all modules unless overridden.
664
- *
665
- * Placed under the `smrt` key in `smrt.config.js`. Values here propagate
666
- * as the lowest-priority base for every `getModuleConfig()` and
667
- * `getPackageConfig()` call.
668
- *
669
- * @example
670
- * ```js
671
- * // smrt.config.js
672
- * export default defineConfig({
673
- * smrt: {
674
- * logLevel: 'debug',
675
- * environment: 'development',
676
- * embeddings: { provider: 'local' },
677
- * },
678
- * });
679
- * ```
680
- *
681
- * @see {@link SmrtConfig}
682
- * @see {@link getModuleConfig}
683
- * @see {@link getPackageConfig}
684
- */
685
- export declare interface SmrtGlobalConfig {
686
- postgresPermissions?: PostgresPermissionsConfig;
687
- cacheDir?: string;
688
- logLevel?: 'debug' | 'info' | 'warn' | 'error';
689
- environment?: 'development' | 'production' | 'test';
690
- /**
691
- * Schema migration strategy when parent class schema changes
692
- *
693
- * Options:
694
- * - 'warn': Log warning about schema mismatch, require manual migration (safest)
695
- * - 'auto-add': Automatically ALTER TABLE to add new parent fields (default, convenient)
696
- *
697
- * Note: Removing columns is never automatic - always requires manual migration
698
- *
699
- * @default 'auto-add'
700
- */
701
- schemaMigration?: {
702
- strategy?: 'warn' | 'auto-add';
703
- };
704
- /**
705
- * Inheritance configuration
706
- */
707
- inheritance?: {
708
- /**
709
- * Behavior when an ancestor class is missing from the registry
710
- *
711
- * Options:
712
- * - 'error': Throw an error (strict, catches bugs)
713
- * - 'warn': Log warning and skip (lenient, default)
714
- *
715
- * @default 'warn'
716
- */
717
- onMissingAncestor?: 'error' | 'warn';
718
- /**
719
- * Size of LRU cache for inheritance chains and merged fields
720
- *
721
- * Higher values improve performance but use more memory.
722
- * Each entry stores one inheritance chain (array of strings).
723
- *
724
- * @default 200
725
- */
726
- cacheSize?: number;
727
- };
728
- /**
729
- * Embedding configuration for semantic search
730
- *
731
- * Project-level settings that apply to all SMRT objects
732
- * unless overridden in the @smrt() decorator.
733
- */
734
- embeddings?: {
735
- /**
736
- * Standard dimensions for embeddings in this project
737
- *
738
- * All embeddings should use the same dimensions for consistency.
739
- * Common values: 384, 768, 1536
740
- *
741
- * @default 768
742
- */
743
- dimensions?: number;
744
- /**
745
- * Embedding provider type
746
- *
747
- * - 'local': Use local Node.js model (@xenova/transformers)
748
- * - 'ai': Use AI library (OpenAI, etc.)
749
- * - 'auto': Try local first, fallback to AI
750
- *
751
- * @default 'local'
752
- */
753
- provider?: 'local' | 'ai' | 'auto';
754
- /**
755
- * Local model to use (when provider is 'local' or 'auto')
756
- *
757
- * Hugging Face model ID for @xenova/transformers.
758
- * Model is downloaded on first use (~440MB for bge-base-en-v1.5).
759
- *
760
- * @default 'Xenova/bge-base-en-v1.5'
761
- */
762
- localModel?: string;
763
- /**
764
- * AI model to use (when provider is 'ai' or fallback)
765
- *
766
- * OpenAI embedding model name.
767
- *
768
- * @default 'text-embedding-3-small'
769
- */
770
- aiModel?: string;
771
- /**
772
- * Whether to fallback to AI if local embedding fails
773
- *
774
- * Only applies when provider is 'auto'.
775
- *
776
- * @default true
777
- */
778
- fallbackToAI?: boolean;
779
- /**
780
- * Storage mode for embeddings
781
- *
782
- * - 'json': Store as JSON text, in-memory similarity (works everywhere)
783
- * - 'native': Use database vector operations when available, fallback to json
784
- *
785
- * @default 'json'
786
- */
787
- storage?: 'json' | 'native';
788
- };
789
- /**
790
- * Optional typed-decision provider configuration. This is deliberately
791
- * separate from generation configuration: configuring decisions never
792
- * changes the client used by `do()` or `describe()`.
793
- */
794
- decisions?: {
795
- /** The currently supported typed-decision provider. */
796
- type: 'typesafe';
797
- /** Provider credential. Prefer an environment-backed value in deployments. */
798
- apiKey?: string;
799
- /** Optional provider endpoint override, primarily for approved test hosts. */
800
- baseUrl?: string;
801
- /** Default decision model; individual evaluations may override it. */
802
- defaultModel?: string;
803
- /** Inclusive predicate threshold. A probability equal to it is true. */
804
- threshold?: number;
805
- /**
806
- * Opt in to a generative tie-break only when the probability is inside the
807
- * finite band centered on the threshold. Provider failures never use it.
808
- */
809
- uncertaintyFallback?: {
810
- band: number;
811
- };
812
- };
813
- [key: string]: unknown;
814
- }
815
-
816
- declare type TenancyMode = 'default-tenant' | 'single-tenant' | 'multi-tenant';
817
-
818
- declare type TenantContextMode = 'defaulted' | 'required';
819
-
820
- declare type TenantIsolation = 'application' | 'database-rls';
821
-
822
- export { }
823
-
824
-
1
+ import type { DomainKnowledgeConfig } from '@happyvertical/smrt-types';
2
+ import type { ApplicationRuntimeConfig } from './runtime-profile.js';
3
+ /** PostgreSQL ACL contract. Applied only through explicit db:permissions. */
4
+ export interface PostgresPermissionsConfig {
5
+ schema: string;
6
+ /** Assert this schema is dedicated to the managed application. */
7
+ schemaExclusive: true;
8
+ migrationOwner: string;
9
+ runtimeRole: string;
10
+ /** Additional managed tables beyond discovered models and present system tables. */
11
+ managedTables?: string[];
12
+ /** Existing operator-owned tables retained outside the runtime data surface. */
13
+ retainedTables?: string[];
14
+ /** Exact zero-argument trigger functions bound only to managed tables. */
15
+ managedTriggerFunctions?: string[];
16
+ /** Explicit safe monitoring columns; there is no default table-wide access. */
17
+ monitor?: {
18
+ role: string;
19
+ tables: Record<string, string[]>;
20
+ };
21
+ }
22
+ /**
23
+ * Global SMRT framework options that apply to all modules unless overridden.
24
+ *
25
+ * Placed under the `smrt` key in `smrt.config.js`. Values here propagate
26
+ * as the lowest-priority base for every `getModuleConfig()` and
27
+ * `getPackageConfig()` call.
28
+ *
29
+ * @example
30
+ * ```js
31
+ * // smrt.config.js
32
+ * export default defineConfig({
33
+ * smrt: {
34
+ * logLevel: 'debug',
35
+ * environment: 'development',
36
+ * embeddings: { provider: 'local' },
37
+ * },
38
+ * });
39
+ * ```
40
+ *
41
+ * @see {@link SmrtConfig}
42
+ * @see {@link getModuleConfig}
43
+ * @see {@link getPackageConfig}
44
+ */
45
+ export interface SmrtGlobalConfig {
46
+ postgresPermissions?: PostgresPermissionsConfig;
47
+ cacheDir?: string;
48
+ logLevel?: 'debug' | 'info' | 'warn' | 'error';
49
+ environment?: 'development' | 'production' | 'test';
50
+ /**
51
+ * Schema migration strategy when parent class schema changes
52
+ *
53
+ * Options:
54
+ * - 'warn': Log warning about schema mismatch, require manual migration (safest)
55
+ * - 'auto-add': Automatically ALTER TABLE to add new parent fields (default, convenient)
56
+ *
57
+ * Note: Removing columns is never automatic - always requires manual migration
58
+ *
59
+ * @default 'auto-add'
60
+ */
61
+ schemaMigration?: {
62
+ strategy?: 'warn' | 'auto-add';
63
+ };
64
+ /**
65
+ * Inheritance configuration
66
+ */
67
+ inheritance?: {
68
+ /**
69
+ * Behavior when an ancestor class is missing from the registry
70
+ *
71
+ * Options:
72
+ * - 'error': Throw an error (strict, catches bugs)
73
+ * - 'warn': Log warning and skip (lenient, default)
74
+ *
75
+ * @default 'warn'
76
+ */
77
+ onMissingAncestor?: 'error' | 'warn';
78
+ /**
79
+ * Size of LRU cache for inheritance chains and merged fields
80
+ *
81
+ * Higher values improve performance but use more memory.
82
+ * Each entry stores one inheritance chain (array of strings).
83
+ *
84
+ * @default 200
85
+ */
86
+ cacheSize?: number;
87
+ };
88
+ /**
89
+ * Embedding configuration for semantic search
90
+ *
91
+ * Project-level settings that apply to all SMRT objects
92
+ * unless overridden in the @smrt() decorator.
93
+ */
94
+ embeddings?: {
95
+ /**
96
+ * Standard dimensions for embeddings in this project
97
+ *
98
+ * All embeddings should use the same dimensions for consistency.
99
+ * Common values: 384, 768, 1536
100
+ *
101
+ * @default 768
102
+ */
103
+ dimensions?: number;
104
+ /**
105
+ * Embedding provider type
106
+ *
107
+ * - 'local': Use local Node.js model (@xenova/transformers)
108
+ * - 'ai': Use AI library (OpenAI, etc.)
109
+ * - 'auto': Try local first, fallback to AI
110
+ *
111
+ * @default 'local'
112
+ */
113
+ provider?: 'local' | 'ai' | 'auto';
114
+ /**
115
+ * Local model to use (when provider is 'local' or 'auto')
116
+ *
117
+ * Hugging Face model ID for @xenova/transformers.
118
+ * Model is downloaded on first use (~440MB for bge-base-en-v1.5).
119
+ *
120
+ * @default 'Xenova/bge-base-en-v1.5'
121
+ */
122
+ localModel?: string;
123
+ /**
124
+ * AI model to use (when provider is 'ai' or fallback)
125
+ *
126
+ * OpenAI embedding model name.
127
+ *
128
+ * @default 'text-embedding-3-small'
129
+ */
130
+ aiModel?: string;
131
+ /**
132
+ * Whether to fallback to AI if local embedding fails
133
+ *
134
+ * Only applies when provider is 'auto'.
135
+ *
136
+ * @default true
137
+ */
138
+ fallbackToAI?: boolean;
139
+ /**
140
+ * Storage mode for embeddings
141
+ *
142
+ * - 'json': Store as JSON text, in-memory similarity (works everywhere)
143
+ * - 'native': Use database vector operations when available, fallback to json
144
+ *
145
+ * @default 'json'
146
+ */
147
+ storage?: 'json' | 'native';
148
+ };
149
+ /**
150
+ * Optional typed-decision provider configuration. This is deliberately
151
+ * separate from generation configuration: configuring decisions never
152
+ * changes the client used by `do()` or `describe()`.
153
+ */
154
+ decisions?: {
155
+ /** The currently supported typed-decision provider. */
156
+ type: 'typesafe';
157
+ /** Provider credential. Prefer an environment-backed value in deployments. */
158
+ apiKey?: string;
159
+ /** Optional provider endpoint override, primarily for approved test hosts. */
160
+ baseUrl?: string;
161
+ /** Default decision model; individual evaluations may override it. */
162
+ defaultModel?: string;
163
+ /** Inclusive predicate threshold. A probability equal to it is true. */
164
+ threshold?: number;
165
+ /**
166
+ * Opt in to a generative tie-break only when the probability is inside the
167
+ * finite band centered on the threshold. Provider failures never use it.
168
+ */
169
+ uncertaintyFallback?: {
170
+ band: number;
171
+ };
172
+ };
173
+ [key: string]: unknown;
174
+ }
175
+ /**
176
+ * PostgreSQL-specific migration settings.
177
+ *
178
+ * Nested under `migrations.postgres` in {@link MigrationsConfig}.
179
+ */
180
+ export interface MigrationsPostgresConfig {
181
+ /**
182
+ * Allow `CREATE INDEX CONCURRENTLY` when concurrent-index mode is requested
183
+ * with `smrt db:migrate --postgres-safe`.
184
+ *
185
+ * Concurrent builds avoid the batch's table locks but cannot run inside a
186
+ * transaction, so that mode is not atomic. Setting this to `false` vetoes
187
+ * the flag: index DDL then stays inside the atomic transaction, still bounded
188
+ * by the timeouts below. The flag is the opt-in — this key alone does not
189
+ * enable concurrent mode.
190
+ *
191
+ * @default true
192
+ */
193
+ useConcurrently?: boolean;
194
+ /**
195
+ * `lock_timeout` applied to every PostgreSQL migration statement.
196
+ *
197
+ * Accepts a bare millisecond count or an `ms`/`s`/`min`/`h` suffix. `'0'`
198
+ * disables the timeout, as PostgreSQL defines it.
199
+ *
200
+ * @default '30s'
201
+ */
202
+ lockTimeout?: string;
203
+ /**
204
+ * `statement_timeout` applied to every PostgreSQL migration statement.
205
+ *
206
+ * Same accepted forms as {@link MigrationsPostgresConfig.lockTimeout}.
207
+ *
208
+ * @default '60s'
209
+ */
210
+ statementTimeout?: string;
211
+ }
212
+ /**
213
+ * Semantic schema contract enforced by SMRT schema commands.
214
+ *
215
+ * Object and field requirements are checked against the loaded SMRT registry.
216
+ * Required fields are also translated to physical table/column checks after
217
+ * migration/status introspection. `requiredDatabaseShape` is reserved for
218
+ * database objects that SMRT cannot infer from manifests.
219
+ */
220
+ export interface SchemaContractConfig {
221
+ requiredObjects?: string[];
222
+ requiredFields?: string[];
223
+ requiredDatabaseShape?: {
224
+ tables?: string[];
225
+ columns?: string[];
226
+ indexes?: string[];
227
+ };
228
+ }
229
+ /**
230
+ * Database migrations configuration.
231
+ *
232
+ * Controls how migrations are generated, stored, and applied. Placed under
233
+ * the `cli.migrations` key in `smrt.config.js` and consumed by
234
+ * `@happyvertical/smrt-cli` migration commands (`smrt db:migrate`, etc.).
235
+ *
236
+ * @see {@link CliConfig}
237
+ */
238
+ export interface MigrationsConfig {
239
+ /**
240
+ * Directory for migration files (relative to project root)
241
+ *
242
+ * @default './migrations'
243
+ */
244
+ directory?: string;
245
+ /**
246
+ * Table name for tracking applied migrations
247
+ *
248
+ * @default '_smrt_schema_migrations'
249
+ */
250
+ table?: string;
251
+ /**
252
+ * Legacy file format setting. File-backed migration generation is not supported.
253
+ *
254
+ * @default 'sql'
255
+ */
256
+ format?: 'sql' | 'typescript';
257
+ /**
258
+ * Migration file naming strategy
259
+ *
260
+ * - 'sequence': Sequential numbers (0001, 0002, ...)
261
+ * - 'timestamp': Unix timestamp-based (20240115143052)
262
+ *
263
+ * @default 'sequence'
264
+ */
265
+ naming?: 'sequence' | 'timestamp';
266
+ /**
267
+ * Migration mode.
268
+ *
269
+ * SMRT schema migrations are manifest-driven. File-backed modes are not
270
+ * supported unless a future file migration executor is implemented.
271
+ *
272
+ * @default 'dynamic'
273
+ */
274
+ mode?: 'dynamic';
275
+ /**
276
+ * Configure mode per environment.
277
+ *
278
+ * Overrides the `mode` setting based on NODE_ENV
279
+ */
280
+ modeByEnvironment?: {
281
+ development?: 'dynamic';
282
+ test?: 'dynamic';
283
+ staging?: 'dynamic';
284
+ production?: 'dynamic';
285
+ };
286
+ /**
287
+ * Automatically generate DOWN scripts where safe
288
+ *
289
+ * Some operations (DROP COLUMN) may lose data and should be reviewed.
290
+ *
291
+ * @default true
292
+ */
293
+ autoGenerateDown?: boolean;
294
+ /**
295
+ * PostgreSQL-specific settings
296
+ */
297
+ postgres?: MigrationsPostgresConfig;
298
+ }
299
+ /**
300
+ * Database connection configuration for CLI commands.
301
+ *
302
+ * Placed under `cli.database` in `smrt.config.js`. Used by
303
+ * `@happyvertical/smrt-cli` to connect for migration and inspection commands.
304
+ *
305
+ * @see {@link CliConfig}
306
+ */
307
+ export interface DatabaseConfig {
308
+ /**
309
+ * Database type
310
+ *
311
+ * @default 'sqlite'
312
+ */
313
+ type?: 'sqlite' | 'postgres' | 'duckdb';
314
+ /**
315
+ * Database connection URL
316
+ *
317
+ * For SQLite: file path or ':memory:'
318
+ * For PostgreSQL: postgresql://user:pass@host:port/dbname
319
+ */
320
+ url?: string;
321
+ }
322
+ /**
323
+ * CLI package configuration.
324
+ *
325
+ * Placed under the `cli` key in `smrt.config.js`. Consumed by
326
+ * `@happyvertical/smrt-cli` for `smrt db:*` and migration commands.
327
+ *
328
+ * @example
329
+ * ```js
330
+ * export default defineConfig({
331
+ * cli: {
332
+ * database: { type: 'sqlite', url: 'file:./local.db' },
333
+ * migrations: { mode: 'dynamic', directory: './migrations' },
334
+ * },
335
+ * });
336
+ * ```
337
+ *
338
+ * @see {@link DatabaseConfig}
339
+ * @see {@link MigrationsConfig}
340
+ */
341
+ export interface CliConfig {
342
+ /**
343
+ * Database connection settings
344
+ */
345
+ database?: DatabaseConfig;
346
+ /**
347
+ * Migration settings
348
+ */
349
+ migrations?: MigrationsConfig;
350
+ /**
351
+ * Required manifest/object/field/database-shape contract for schema commands.
352
+ */
353
+ schemaContract?: SchemaContractConfig;
354
+ }
355
+ /**
356
+ * A single navigation link item used in site menus.
357
+ *
358
+ * @see {@link SiteNavigation}
359
+ */
360
+ export interface SiteNavigationLink {
361
+ label: string;
362
+ href: string;
363
+ icon?: string;
364
+ }
365
+ /**
366
+ * Site navigation structure containing primary and optional footer links.
367
+ *
368
+ * @see {@link SiteConfig}
369
+ * @see {@link SiteNavigationLink}
370
+ */
371
+ export interface SiteNavigation {
372
+ /** Primary navigation links (header) */
373
+ primary: SiteNavigationLink[];
374
+ /** Footer navigation links */
375
+ footer?: SiteNavigationLink[];
376
+ }
825
377
  /**
826
- * Extend globalThis to include our config cache properties.
827
- * Using globalThis ensures all module instances share the same config,
828
- * which is critical in monorepos where the same package can be loaded
829
- * from different paths (e.g., pnpm store vs workspace symlink).
378
+ * Geographic location for the site, used for proximity search and display.
830
379
  *
831
- * This fixes issue #543: external packages not receiving user config
832
- * when smrt-cli loads them.
380
+ * @see {@link SiteConfig}
381
+ */
382
+ export interface SiteLocation {
383
+ /** Display name (e.g., "Bentley" or "Bentley, AB") */
384
+ name: string;
385
+ /** Latitude coordinate */
386
+ latitude: number;
387
+ /** Longitude coordinate */
388
+ longitude: number;
389
+ /** IANA timezone (e.g., "America/Edmonton") */
390
+ timezone: string;
391
+ }
392
+ /**
393
+ * Site theme and branding color palette.
394
+ *
395
+ * Colors should be provided as CSS hex values (e.g., `'#3b82f6'`).
396
+ *
397
+ * @see {@link SiteConfig}
398
+ */
399
+ export interface SiteTheme {
400
+ /** Primary brand color (hex) */
401
+ primaryColor: string;
402
+ /** Light variant of primary color */
403
+ primaryLight?: string;
404
+ /** Dark variant of primary color */
405
+ primaryDark?: string;
406
+ }
407
+ /**
408
+ * Publisher or organization information displayed in site footers and metadata.
409
+ *
410
+ * @see {@link SiteConfig}
411
+ */
412
+ export interface SitePublisher {
413
+ /** Organization name (e.g., "Blindman Press") */
414
+ name: string;
415
+ /** Organization website URL */
416
+ url?: string;
417
+ /** GitHub organization URL */
418
+ github?: string;
419
+ }
420
+ /**
421
+ * Site identity and configuration for SMRT site templates.
422
+ *
423
+ * Placed under the `site` key in `smrt.config.js`. Retrieved at runtime
424
+ * via {@link getSiteConfig}. Used by site templates
425
+ * (`template-sveltekit`, `template-site-static-json`) to define name,
426
+ * description, navigation, location, and theme.
427
+ *
428
+ * @example
429
+ * ```js
430
+ * export default defineConfig({
431
+ * site: {
432
+ * name: 'Bentley Alberta',
433
+ * description: 'Community news for Bentley, AB',
434
+ * url: 'https://bentley.ca',
435
+ * location: { name: 'Bentley', latitude: 52.4, longitude: -113.9, timezone: 'America/Edmonton' },
436
+ * navigation: { primary: [{ label: 'Home', href: '/' }] },
437
+ * },
438
+ * });
439
+ * ```
440
+ *
441
+ * @see {@link getSiteConfig}
442
+ * @see {@link SiteLocation}
443
+ * @see {@link SiteNavigation}
444
+ * @see {@link SiteTheme}
445
+ */
446
+ export interface SiteConfig {
447
+ /** Full site name (e.g., "Bentley Alberta") */
448
+ name: string;
449
+ /** Short name for mobile/compact displays */
450
+ shortName?: string;
451
+ /** Site description for SEO */
452
+ description: string;
453
+ /** Production URL */
454
+ url?: string;
455
+ /** Contact email for the site */
456
+ contactEmail?: string;
457
+ /** Publisher/organization info */
458
+ publisher?: SitePublisher;
459
+ /** Geographic location */
460
+ location: SiteLocation;
461
+ /** Navigation structure */
462
+ navigation: SiteNavigation;
463
+ /** Theme/branding */
464
+ theme?: SiteTheme;
465
+ /** Additional metadata */
466
+ meta?: {
467
+ /** Theme color for mobile browsers */
468
+ themeColor?: string;
469
+ /** Open Graph locale */
470
+ ogLocale?: string;
471
+ /** Google Tag Manager ID */
472
+ gtmId?: string;
473
+ };
474
+ }
475
+ /**
476
+ * Filter operators for export queries.
477
+ *
478
+ * Used as values in {@link ExportFileConfig.filters} to build SQL `WHERE`
479
+ * clauses when exporting records to static files.
480
+ *
481
+ * @example
482
+ * ```js
483
+ * filters: {
484
+ * publishDate: { gte: '2025-01-01', lt: '2026-01-01' },
485
+ * status: { in: ['published', 'featured'] },
486
+ * }
487
+ * ```
833
488
  *
834
- * @see https://github.com/happyvertical/smrt/issues/543
489
+ * @see {@link ExportFileConfig}
835
490
  */
836
- declare global {
837
- var __smrtConfigCache: SmrtConfig | null | undefined;
838
- var __smrtRuntimeConfig: Partial<SmrtConfig> | undefined;
491
+ export interface ExportFilterValue {
492
+ /** Equals (shorthand: just the value) */
493
+ eq?: string | number | boolean;
494
+ /** Not equals */
495
+ ne?: string | number | boolean;
496
+ /** Greater than */
497
+ gt?: string | number;
498
+ /** Greater than or equal */
499
+ gte?: string | number;
500
+ /** Less than */
501
+ lt?: string | number;
502
+ /** Less than or equal */
503
+ lte?: string | number;
504
+ /** In array */
505
+ in?: (string | number)[];
506
+ /** Contains (text) */
507
+ contains?: string;
839
508
  }
840
-
841
-
842
- declare global {
843
- var __smrtRuntimeConfig: Partial<SmrtConfig> | undefined;
509
+ /**
510
+ * Configuration for a single SSG export file.
511
+ *
512
+ * Each key in {@link ExportConfig} (besides `fieldExportDefault` and `format`)
513
+ * becomes the output filename. Records are queried from the database, filtered,
514
+ * ordered, and written to `{key}.json` (or the specified format).
515
+ *
516
+ * @example
517
+ * ```js
518
+ * export default defineConfig({
519
+ * export: {
520
+ * articles: {
521
+ * types: ['Article'],
522
+ * filters: { status: ['published'] },
523
+ * orderBy: '-publishDate',
524
+ * limit: 500,
525
+ * },
526
+ * },
527
+ * });
528
+ * ```
529
+ *
530
+ * @see {@link ExportConfig}
531
+ * @see {@link ExportFilterValue}
532
+ */
533
+ export interface ExportFileConfig {
534
+ /**
535
+ * SMRT object types to include in this export
536
+ * Uses className (e.g., 'MeetingRecap', 'Game')
537
+ */
538
+ types: string[];
539
+ /**
540
+ * Field whitelist - only export these fields
541
+ * If specified, overrides exclude and fieldExportDefault
542
+ */
543
+ include?: string[];
544
+ /**
545
+ * Field blacklist - exclude these fields
546
+ * Applied after schema-level exported: false check
547
+ */
548
+ exclude?: string[];
549
+ /**
550
+ * Filters to apply when querying records
551
+ * Keys are field names, values are filter conditions
552
+ *
553
+ * @example
554
+ * filters: {
555
+ * status: ['published'], // shorthand for status IN ('published')
556
+ * publish_date: { gte: '2025-01-01' },
557
+ * council_slug: ['town-of-bentley'],
558
+ * }
559
+ */
560
+ filters?: Record<string, string[] | number[] | ExportFilterValue>;
561
+ /**
562
+ * Output format for this file
563
+ * @default 'json'
564
+ */
565
+ format?: 'json' | 'ndjson' | 'csv' | 'sqlite';
566
+ /**
567
+ * Field to order by
568
+ * Prefix with '-' for descending (e.g., '-publish_date')
569
+ */
570
+ orderBy?: string;
571
+ /**
572
+ * Maximum records per file
573
+ * If exceeded, creates paginated files (e.g., contents-1.json, contents-2.json)
574
+ */
575
+ limit?: number;
576
+ /**
577
+ * Create separate files per unique value of this field
578
+ * e.g., shardBy: 'year' creates contents-2024.json, contents-2025.json
579
+ */
580
+ shardBy?: string;
581
+ }
582
+ /**
583
+ * Export configuration for static site generation.
584
+ *
585
+ * Placed under the `export` key in `smrt.config.js`. Controls how database
586
+ * records are exported to static files during SSG builds. Each additional
587
+ * key beyond `fieldExportDefault` and `format` defines a named export file.
588
+ *
589
+ * @example
590
+ * ```js
591
+ * export default defineConfig({
592
+ * export: {
593
+ * fieldExportDefault: true,
594
+ * articles: { types: ['Article'], filters: { status: ['published'] } },
595
+ * games: { types: ['Game'], orderBy: '-date', format: 'ndjson' },
596
+ * },
597
+ * });
598
+ * ```
599
+ *
600
+ * @see {@link ExportFileConfig}
601
+ * @see {@link exportConfig}
602
+ */
603
+ export interface ExportConfig {
604
+ /**
605
+ * Default export behavior for fields without explicit `exported` annotation
606
+ *
607
+ * - true: Export all fields by default (simpler, for most sites)
608
+ * - false: Only export fields with explicit `exported: true`
609
+ *
610
+ * @default true
611
+ */
612
+ fieldExportDefault?: boolean;
613
+ /**
614
+ * Default output format for all exports
615
+ * @default 'json'
616
+ */
617
+ format?: 'json' | 'ndjson' | 'csv' | 'sqlite';
618
+ /**
619
+ * Export file configurations
620
+ * Keys become filenames (e.g., 'contents' -> 'contents.json')
621
+ */
622
+ [filename: string]: ExportFileConfig | boolean | string | undefined;
623
+ }
624
+ /**
625
+ * Root SMRT configuration structure.
626
+ *
627
+ * This is the shape of the object returned by `smrt.config.{js,ts,json}` and
628
+ * consumed by {@link loadConfig}. Use {@link defineConfig} for type-safe
629
+ * authoring with IDE auto-completion.
630
+ *
631
+ * Priority order (highest to lowest):
632
+ * 1. Runtime overrides set via {@link setConfig}
633
+ * 2. File-based config loaded by {@link loadConfig}
634
+ * 3. Defaults passed to {@link getModuleConfig} / {@link getPackageConfig}
635
+ *
636
+ * @example
637
+ * ```js
638
+ * // smrt.config.js
639
+ * import { defineConfig } from '@happyvertical/smrt-config';
640
+ *
641
+ * export default defineConfig({
642
+ * smrt: { logLevel: 'info', environment: 'production' },
643
+ * site: { name: 'My Site', ... },
644
+ * modules: { praeco: { rssLimit: 50 } },
645
+ * packages: { ai: { defaultModel: 'gpt-4o' } },
646
+ * });
647
+ * ```
648
+ *
649
+ * @see {@link loadConfig}
650
+ * @see {@link defineConfig}
651
+ * @see {@link SmrtGlobalConfig}
652
+ */
653
+ export interface SmrtConfig {
654
+ /** Global SMRT framework options — lowest-priority base for all modules. */
655
+ smrt?: SmrtGlobalConfig;
656
+ /** Site identity and configuration (for site templates). */
657
+ site?: SiteConfig;
658
+ /** Export configuration for static site generation. */
659
+ export?: ExportConfig;
660
+ /** Domain-scoped agent/developer knowledge generation and exposure. */
661
+ knowledge?: DomainKnowledgeConfig;
662
+ /** Validated application infrastructure composition. */
663
+ runtime?: ApplicationRuntimeConfig;
664
+ /**
665
+ * Module-scoped configurations keyed by module name.
666
+ * Retrieved via {@link getModuleConfig}.
667
+ */
668
+ modules?: {
669
+ [moduleName: string]: Record<string, unknown>;
670
+ };
671
+ /**
672
+ * Package-scoped configurations keyed by package name.
673
+ * Retrieved via {@link getPackageConfig}.
674
+ */
675
+ packages?: {
676
+ [packageName: string]: Record<string, unknown>;
677
+ };
844
678
  }
845
-
846
-
847
679
  /**
848
- * Extend globalThis to include loader cache properties.
849
- * Using globalThis ensures all module instances share the same loader state,
850
- * which is critical in monorepos where the same package can be loaded
851
- * from different paths (e.g., pnpm store vs workspace symlink).
680
+ * Options accepted by {@link loadConfig}.
852
681
  *
853
- * @see https://github.com/happyvertical/smrt/issues/543
682
+ * All fields are optional; omitting them triggers cosmiconfig's default
683
+ * search behaviour (scan `cwd` upward for `smrt.config.{js,mjs,cjs,json}`).
854
684
  */
855
- declare global {
856
- var __smrtLoaderCachedConfig: SmrtConfig | null | undefined;
857
- var __smrtLoaderExplorer: ReturnType<typeof cosmiconfig> | null | undefined;
685
+ export interface LoadConfigOptions {
686
+ /**
687
+ * Absolute or relative path to a specific config file.
688
+ * When provided, cosmiconfig loads this file directly instead of searching.
689
+ */
690
+ configPath?: string;
691
+ /**
692
+ * Whether to search parent directories when no config is found in `cwd`.
693
+ *
694
+ * @default true
695
+ */
696
+ searchParents?: boolean;
697
+ /**
698
+ * Directory to start the config search from. Defaults to `process.cwd()`.
699
+ * Ignored when `configPath` is provided. Useful for tests and for tools that
700
+ * resolve config relative to a project root other than the current directory.
701
+ */
702
+ searchFrom?: string;
703
+ /**
704
+ * Whether to cache the loaded config in `globalThis.__smrtLoaderCachedConfig`.
705
+ * Disable for test isolation or hot-reload scenarios.
706
+ *
707
+ * @default true
708
+ */
709
+ cache?: boolean;
858
710
  }
711
+ //# sourceMappingURL=types.d.ts.map