@happyvertical/smrt-scanner 0.51.32 → 0.51.35

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,522 +1,497 @@
1
- /** The declared agent-addressable surface found by one scan. */
2
- export declare interface AgentSurface {
3
- intents: AgentSurfaceIntent[];
4
- playbooks: AgentSurfacePlaybook[];
5
- diagnostics: AgentSurfaceDiagnostic[];
6
- }
7
-
8
- /** A fully resolved classification (#2587's fail-closed rule already applied). */
9
- export declare interface AgentSurfaceCapability {
10
- effect: AgentSurfaceEffect;
11
- idempotent: boolean;
12
- openWorld: boolean;
13
- }
14
-
15
- /**
16
- * Something a reader of the emitted surface has to know about a declaration.
17
- *
18
- * Two kinds, and the difference is whether the entry survived. Every code but
19
- * `tool-name-collision` reports a declaration that is NOT emitted — never a
20
- * silent omission, so each of those messages names `useWebMcpTool`, the escape
21
- * hatch for a genuinely computed tool set. A `tool-name-collision` is
22
- * advisory: the declaration IS emitted, and the diagnostic records that its
23
- * derived WebMCP tool name is already spoken for by something outside the
24
- * declared surface.
25
- */
26
- export declare interface AgentSurfaceDiagnostic {
27
- code: AgentSurfaceDiagnosticCode;
28
- helper: AgentSurfaceHelper;
29
- message: string;
30
- filePath: string;
31
- line?: number;
32
- column?: number;
33
- }
34
-
35
- /** Why a recognized declaration could not be emitted. */
36
- export declare type AgentSurfaceDiagnosticCode = 'non-literal-argument' | 'not-module-scope' | 'argument-count' | 'incomplete-declaration' | 'invalid-identity' | 'svelte-declaration' | 'duplicate-identity' | 'tool-name-collision';
37
-
38
- /**
39
- * Effect classification, mirroring `CapabilityEffect` in
40
- * `@happyvertical/smrt-types`. Mirrored rather than imported because this
41
- * package carries no `@happyvertical/*` dependency — core depends on it, and
42
- * importing back would close the cycle.
43
- */
44
- export declare type AgentSurfaceEffect = 'read' | 'write' | 'destructive';
45
-
46
- /** The two module-scope helpers the agent-surface matcher recognizes. */
47
- export declare type AgentSurfaceHelper = 'defineIntent' | 'definePlaybook';
48
-
49
- /** One emitted view intent (#2588). */
50
- export declare interface AgentSurfaceIntent {
51
- kind: 'intent';
52
- /** Declared, dot-namespaced identity. This is the entry's stable identity. */
53
- id: string;
54
- description: string;
55
- capability: AgentSurfaceCapability;
56
- target: Record<string, unknown>;
57
- /** Whether the declaration carried an `inputSchema` object. */
58
- hasInputSchema: boolean;
59
- /**
60
- * Always exactly `['browser']`. An intent moves mounted browser state; a
61
- * server-side agent reaches one only through the #2446 command/ack bridge,
62
- * which the referencing PLAYBOOK declares. Typed as the literal tuple rather
63
- * than the open plane list so the contract cannot be read as wider than it is.
64
- */
65
- planes: ['browser'];
66
- /** Declaring module, relativized by the emitting caller. */
67
- filePath: string;
68
- }
69
-
70
- /** Plane a declaration is valid on. */
71
- export declare type AgentSurfacePlane = 'browser' | 'server';
72
-
73
- /** One emitted playbook (#2589). */
74
- export declare interface AgentSurfacePlaybook {
75
- kind: 'playbook';
76
- /** Declared registry key. This is the entry's stable identity. */
77
- key: string;
78
- title: string;
79
- description: string;
80
- steps: AgentSurfacePlaybookStep[];
81
- planes: AgentSurfacePlane[];
82
- /** False when `planes` was derived from the step kinds rather than declared. */
83
- planesDeclared: boolean;
84
- onStepFailure: 'abort' | 'continue';
85
- enabled: boolean;
86
- /** Declaring module, relativized by the emitting caller. */
87
- filePath: string;
88
- }
89
-
90
- /** One step of an emitted playbook (#2589). Playbooks cannot nest. */
91
- export declare type AgentSurfacePlaybookStep = {
92
- kind: 'operation';
93
- model: string;
94
- action: string;
95
- } | {
96
- kind: 'intent';
97
- id: string;
98
- };
99
-
100
- /**
101
- * Describes a pre-loaded manifest from an installed SMRT package, used by
102
- * {@link InheritanceResolver} to resolve base classes that originate outside
103
- * the local project source.
104
- *
105
- * Build tooling (e.g. the SMRT CLI / vitest plugin) loads each installed
106
- * `@happyvertical/smrt-*` package's `manifest.json` and converts it into an
107
- * `ExternalManifest` before passing it to the scanner.
108
- *
109
- * @see {@link OxcScannerOptions.externalManifests}
110
- * @see {@link InheritanceResolver.addExternalManifest}
111
- */
112
- export declare interface ExternalManifest {
113
- /** npm package name, e.g. `'@happyvertical/smrt-profiles'`. */
114
- packageName: string;
115
- /** SemVer version string of the installed package. */
116
- packageVersion: string;
117
- /** All class definitions exported by the package, keyed by class name. */
118
- classes: Map<string, RawClassDefinition>;
119
- }
120
-
121
- /**
122
- * Result produced by {@link ManifestAdapter.inferFieldType} for a single field.
123
- *
124
- * In addition to the inferred `type`, carries the `source` of the inference
125
- * so callers can distinguish authoritative decorator-driven results from
126
- * heuristic guesses and provide better diagnostics.
127
- *
128
- * @see {@link InferredFieldType} for valid `type` values.
129
- * @see {@link ManifestAdapter.inferFieldType} for inference priority rules.
130
- */
131
- export declare interface FieldTypeInference {
132
- /** Inferred SMRT type */
133
- type: InferredFieldType;
134
- /** Related class for relationship types */
135
- related?: string;
136
- /** Default value if extractable */
137
- defaultValue?: unknown;
138
- /** Whether field is required */
139
- required: boolean;
140
- /** Inference source for debugging */
141
- source: 'helper' | 'decorator' | 'annotation' | 'heuristic' | 'default';
142
- /** Underlying type for meta fields (e.g., 'string' inside Meta<string>) */
143
- underlyingType?: InferredFieldType;
144
- /**
145
- * Decorator-derived metadata that should be merged into the manifest
146
- * field's `_meta` object. Used by `@crossPackageRef`, `@manyToMany`,
147
- * `@meta` to carry options (`validate`, `through`, `indexed`, `idType`,
148
- * etc.) that don't fit on the top-level FieldDefinition.
149
- */
150
- _meta?: Record<string, unknown>;
151
- }
152
-
153
- /**
154
- * Result from scanning a single file
155
- */
156
- export declare interface FileScanResult {
157
- /** Source file path */
158
- filePath: string;
159
- /** Classes found in file */
160
- classes: RawClassDefinition[];
161
- /** Scan errors */
162
- errors: ScanError[];
163
- /** Parse time in milliseconds */
164
- parseTimeMs: number;
165
- /** Type alias declarations found in file (name → resolved type string) */
166
- typeAliases: Record<string, string>;
167
- /** SMRT package imports found in file (package name → Set of imported class names) */
168
- smrtImports?: Map<string, Set<string>>;
169
- /**
170
- * Declared view intents and playbooks found in the file, plus a diagnostic
171
- * for every recognized declaration that is not statically emittable (#2591).
172
- * Omitted when the file declares none.
173
- */
174
- agentSurface?: AgentSurface;
175
- }
176
-
177
- /**
178
- * The set of SMRT column types that the scanner can infer for a field.
179
- *
180
- * | Value | DB column type | Notes |
181
- * |---|---|---|
182
- * | `text` | `TEXT` / `VARCHAR` | Default for `string` and unknown types |
183
- * | `integer` | `INTEGER` | `number` with `= 0` initialiser |
184
- * | `decimal` | `DECIMAL` | `number` with `= 0.0` initialiser |
185
- * | `boolean` | `BOOLEAN` | `boolean` annotation or literal initialiser |
186
- * | `datetime` | `DATETIME` | `Date` annotation |
187
- * | `json` | `JSON` / `TEXT` | Arrays, `Record<>`, object types |
188
- * | `foreignKey` | `UUID` by default (FK column) | `@foreignKey(Class)` decorator |
189
- * | `crossPackageRef` | `UUID` by default (no FK constraint) | `@crossPackageRef('@pkg:Class')` decorator |
190
- * | `oneToMany` | — (virtual) | `@oneToMany(Class)` decorator |
191
- * | `manyToMany` | — (virtual) | `@manyToMany(Class)` decorator |
192
- * | `meta` | Stored in `_meta_data` | STI child field wrapped in `Meta<T>` |
193
- * | `unknown` | — | Could not be determined |
194
- *
195
- * @see {@link FieldTypeInference} for the full inference result shape.
196
- */
197
- export declare type InferredFieldType = 'text' | 'integer' | 'decimal' | 'boolean' | 'datetime' | 'json' | 'foreignKey' | 'crossPackageRef' | 'oneToMany' | 'manyToMany' | 'meta' | 'unknown';
198
-
199
- /**
200
- * Configuration options for {@link OxcScanner}.
201
- *
202
- * All fields are optional; reasonable defaults are applied when omitted.
203
- *
204
- * @see {@link OxcScanner}
205
- */
206
- export declare interface OxcScannerOptions {
207
- /** Glob patterns to include */
208
- include?: string[];
209
- /** Glob patterns to exclude */
210
- exclude?: string[];
211
- /** Base directory for scanning */
212
- cwd?: string;
213
- /** Path to tsconfig.json for module resolution */
214
- tsconfig?: string;
215
- /** Whether to follow imports to find base classes */
216
- followImports?: boolean;
217
- /** Known base classes (avoid resolution) */
218
- baseClasses?: string[];
219
- /** Include private methods in output */
220
- includePrivateMethods?: boolean;
221
- /** Include static methods in output */
222
- includeStaticMethods?: boolean;
223
- /** External package manifests for base class resolution */
224
- externalManifests?: Map<string, ExternalManifest>;
225
- /**
226
- * Follow symbolic links while discovering files. Defaults to `false`.
227
- *
228
- * A package's own sources are real files, while a pnpm `node_modules` is a
229
- * symlink graph with cycles: every store entry links back out to its
230
- * siblings, so a link-following walk reaches the same real directory once per
231
- * path that leads to it and never terminates in practice. Discovery therefore
232
- * stays on real directories unless a caller explicitly opts back in.
233
- */
234
- followSymbolicLinks?: boolean;
235
- /**
236
- * Match module-scope `defineIntent()` / `definePlaybook()` declarations and
237
- * report `.svelte` declarations the scanner can never read (#2591). Defaults
238
- * to `true`.
239
- */
240
- agentSurface?: boolean;
241
- /**
242
- * Glob patterns searched for `.svelte` declarations the scanner cannot read.
243
- * Only used when {@link OxcScannerOptions.agentSurface} is enabled.
244
- */
245
- svelteInclude?: string[];
246
- /**
247
- * Glob patterns searched for `defineIntent` / `definePlaybook` declarations,
248
- * independently of {@link OxcScannerOptions.include}.
249
- *
250
- * A model scan is routinely narrowed to where models live, but an intent
251
- * sidecar lives beside the component that uses it; binding declaration
252
- * discovery to the class glob would silently drop those. Only used when
253
- * {@link OxcScannerOptions.agentSurface} is enabled.
254
- */
255
- agentSurfaceInclude?: string[];
256
- }
257
-
258
- /** One branch of a top-level union parameter type (#2686). */
259
- export declare interface ParameterTypeBranch {
260
- /** The branch's own type name, e.g. `string` or `object`. */
261
- type: string;
262
- /** Inline object members declared by THIS branch only. */
263
- memberTypes?: string[];
264
- }
265
-
266
- /**
267
- * Type definitions for OXC-based SMRT scanner
268
- *
269
- * This module defines:
270
- * 1. Raw types - Intermediate representation from OXC parsing (Phase 1)
271
- * 2. Resolved types - After inheritance resolution (Phase 2)
272
- * 3. Re-exports of smrt-core types for compatibility
273
- */
274
- /**
275
- * Raw class definition extracted from OXC AST
276
- * Contains only syntactic information, no semantic resolution
277
- */
278
- export declare interface RawClassDefinition {
279
- /** Class name as declared in source */
280
- className: string;
281
- /** Absolute path to source file */
282
- filePath: string;
283
- /** Parent class name from extends clause (null if none) */
284
- extendsClause: string | null;
285
- /** Generic type argument from extends (e.g., "Meeting" from SmrtCollection<Meeting>) */
286
- extendsTypeArg: string | null;
287
- /** Parsed @smrt() decorator configuration object */
288
- decoratorConfig: RawDecoratorConfig | null;
289
- /** Has @smrt() decorator */
290
- hasSmartDecorator: boolean;
291
- /** Class properties/fields */
292
- fields: RawFieldDefinition[];
293
- /** Class methods */
294
- methods: RawMethodDefinition[];
295
- /** Start line in source file */
296
- startLine: number;
297
- /** End line in source file */
298
- endLine: number;
299
- }
300
-
301
- /**
302
- * Raw decorator information
303
- */
304
- export declare interface RawDecorator {
305
- /** Decorator name (e.g., "field", "foreignKey") */
306
- name: string;
307
- /** Raw arguments as strings */
308
- arguments: string[];
309
- }
310
-
311
- /**
312
- * Raw @smrt() decorator configuration
313
- */
314
- export declare interface RawDecoratorConfig {
315
- /** Table strategy: 'sti' | 'cti' */
316
- tableStrategy?: 'sti' | 'cti';
317
- /** Storage type for the generated id primary key */
318
- idType?: 'uuid' | 'text';
319
- /** Code-owned feature toggle declarations */
320
- features?: Record<string, {
321
- defaultEnabled: boolean;
322
- label?: string;
323
- description?: string;
324
- metadata?: Record<string, unknown>;
325
- }>;
326
- /** API configuration */
327
- api?: {
328
- include?: string[];
329
- exclude?: string[];
330
- };
331
- /** CLI configuration */
332
- cli?: boolean | {
333
- include?: string[];
334
- exclude?: string[];
335
- skipApiCheck?: boolean | string[];
336
- http?: boolean;
337
- };
338
- /** MCP configuration */
339
- mcp?: {
340
- include?: string[];
341
- exclude?: string[];
342
- };
343
- /** Raw config object for unknown properties */
344
- [key: string]: unknown;
345
- }
346
-
347
- /**
348
- * Raw field definition from OXC AST
349
- */
350
- export declare interface RawFieldDefinition {
351
- /** Field name */
352
- name: string;
353
- /** TypeScript type annotation as string (e.g., "string", "number", "Date") */
354
- typeAnnotation: string | null;
355
- /** Raw initializer expression as string */
356
- initializer: string | null;
357
- /** For numeric literals: whether it contains a decimal point */
358
- hasDecimalPoint: boolean;
359
- /** For numeric literals: the actual numeric value */
360
- numericValue: number | null;
361
- /** Decorators applied to this field */
362
- decorators: RawDecorator[];
363
- /** Whether field is optional (has ?) */
364
- optional: boolean;
365
- /** Whether field is static */
366
- isStatic: boolean;
367
- /** Whether field is readonly */
368
- readonly: boolean;
369
- /** Whether field is private/protected */
370
- accessibility: 'public' | 'private' | 'protected';
371
- /** Start line in source */
372
- line: number;
373
- }
374
-
375
- /**
376
- * Raw method definition from OXC AST
377
- */
378
- export declare interface RawMethodDefinition {
379
- /** Method name */
380
- name: string;
381
- /** Whether method is async */
382
- async: boolean;
383
- /** Whether method is static */
384
- isStatic: boolean;
385
- /** Accessibility modifier */
386
- accessibility: 'public' | 'private' | 'protected';
387
- /** Method parameters */
388
- parameters: RawParameterDefinition[];
389
- /** Return type annotation as string */
390
- returnType: string | null;
391
- /** JSDoc description if present */
392
- description: string | null;
393
- /**
394
- * Config object of an `@method()` decorator on this method, when one is
395
- * present. `{}` for a bare `@method()`; `undefined` when the method carries
396
- * no `@method()` decorator at all — the two are distinct, because an
397
- * explicit bare decorator still marks the method as deliberately reviewed.
398
- *
399
- * Values are extracted with the same literal-only rules the class-level
400
- * `@smrt()` config uses, so an expression the scanner cannot resolve becomes
401
- * a scan error rather than a silently dropped `expose: false`.
402
- */
403
- decoratorConfig?: Record<string, unknown>;
404
- /** Start line in source */
405
- line: number;
406
- }
407
-
408
- /**
409
- * Raw parameter definition
410
- */
411
- export declare interface RawParameterDefinition {
412
- /** Parameter name */
413
- name: string;
414
- /** Type annotation as string */
415
- type: string | null;
416
- /** Whether parameter is optional */
417
- optional: boolean;
418
- /** Default value as string */
419
- defaultValue: string | null;
420
- /**
421
- * True when the parameter carries a type annotation the scanner could not
422
- * express as a string — an intersection, tuple, conditional, mapped,
423
- * `typeof`, or indexed-access type — or when an inline object literal
424
- * contains such a member.
425
- *
426
- * This is the provenance that separates "the author wrote `any`" from "the
427
- * scanner gave up": both previously reached the manifest as the string
428
- * `'any'`. Consumers that must fail closed on an uncertain type (the API
429
- * wire-ability gate) read this rather than trusting `type`.
430
- *
431
- * `type: null` with `typeUnresolved` absent means the parameter simply has
432
- * no annotation, which is an implicit — and genuinely authored — `any`.
433
- */
434
- typeUnresolved?: boolean;
435
- /**
436
- * Resolved member types of an INLINE object-literal annotation
437
- * (`{ onDone: () => void; target: Content }` → `['Function', 'Content']`),
438
- * flattened across nested literals, arrays, and unions.
439
- *
440
- * `extractTypeName` collapses every inline literal to the single string
441
- * `'object'`, which erases exactly the members a caller needs to judge
442
- * whether the bag can cross a wire. NAMED bags (an interface, type alias,
443
- * `Partial<>`/`Pick<>`) are deliberately NOT expanded — resolving them needs
444
- * cross-file type resolution this AST layer does not do, and they are
445
- * accepted heuristically by the consumers that care.
446
- */
447
- memberTypes?: string[];
448
- /**
449
- * For a top-level UNION, each branch with the inline members IT declared.
450
- *
451
- * `memberTypes` above flattens across branches, which lets one branch veto
452
- * another: `{ callback: () => void } | string` is wire-able through its
453
- * string branch, but the flattened `Function` rejected the whole parameter.
454
- * A consumer that understands this field MUST prefer it over `memberTypes`
455
- * for unions. Absent on a non-union parameter and on manifests generated
456
- * before #2686.
457
- */
458
- unionBranches?: ParameterTypeBranch[];
459
- }
460
-
461
- /**
462
- * Resolved class definition with inheritance chain
463
- */
464
- export declare interface ResolvedClassDefinition extends RawClassDefinition {
465
- /** Full inheritance chain from base to this class */
466
- inheritanceChain: string[];
467
- /** STI base class name (if part of STI hierarchy) */
468
- stiBase: string | null;
469
- /** Effective table strategy (inherited or declared) */
470
- effectiveTableStrategy: 'sti' | 'cti';
471
- /** Whether this class uses STI (convenience boolean) */
472
- isSTI: boolean;
473
- /** Whether this class is a framework base class */
474
- isFrameworkBase: boolean;
475
- /** All fields including inherited (for STI) */
476
- allFields: RawFieldDefinition[];
477
- /** Package this class belongs to (if external) */
478
- packageName: string | null;
479
- }
480
-
481
- /**
482
- * Scan error
483
- */
484
- export declare interface ScanError {
485
- /** Error message */
486
- message: string;
487
- /** Source file */
488
- filePath: string;
489
- /** Line number (1-based) */
490
- line?: number;
491
- /** Column number (1-based) */
492
- column?: number;
493
- /** Error severity */
494
- severity: 'error' | 'warning';
495
- }
496
-
497
- /**
498
- * Result from scanning multiple files
499
- */
500
- export declare interface ScanResults {
501
- /** All scanned files */
502
- files: FileScanResult[];
503
- /** All classes found (flattened) */
504
- classes: RawClassDefinition[];
505
- /** All errors (flattened) */
506
- errors: ScanError[];
507
- /** Total parse time in milliseconds */
508
- totalParseTimeMs: number;
509
- /** Number of files scanned */
510
- fileCount: number;
511
- /** Accumulated type aliases across all files */
512
- typeAliases: Record<string, string>;
513
- /** Accumulated SMRT package imports across all files (package name → Set of imported class names) */
514
- smrtImports?: Map<string, Set<string>>;
515
- /**
516
- * The project's declared agent-addressable surface, merged across files with
517
- * deterministic identity so emission never depends on file order (#2591).
518
- */
519
- agentSurface: AgentSurface;
520
- }
521
-
522
- export { }
1
+ /**
2
+ * Type definitions for OXC-based SMRT scanner
3
+ *
4
+ * This module defines:
5
+ * 1. Raw types - Intermediate representation from OXC parsing (Phase 1)
6
+ * 2. Resolved types - After inheritance resolution (Phase 2)
7
+ * 3. Re-exports of smrt-core types for compatibility
8
+ */
9
+ /**
10
+ * Raw class definition extracted from OXC AST
11
+ * Contains only syntactic information, no semantic resolution
12
+ */
13
+ export interface RawClassDefinition {
14
+ /** Class name as declared in source */
15
+ className: string;
16
+ /** Absolute path to source file */
17
+ filePath: string;
18
+ /** Parent class name from extends clause (null if none) */
19
+ extendsClause: string | null;
20
+ /** Generic type argument from extends (e.g., "Meeting" from SmrtCollection<Meeting>) */
21
+ extendsTypeArg: string | null;
22
+ /** Parsed @smrt() decorator configuration object */
23
+ decoratorConfig: RawDecoratorConfig | null;
24
+ /** Has @smrt() decorator */
25
+ hasSmartDecorator: boolean;
26
+ /** Class properties/fields */
27
+ fields: RawFieldDefinition[];
28
+ /** Class methods */
29
+ methods: RawMethodDefinition[];
30
+ /** Start line in source file */
31
+ startLine: number;
32
+ /** End line in source file */
33
+ endLine: number;
34
+ }
35
+ /**
36
+ * Raw @smrt() decorator configuration
37
+ */
38
+ export interface RawDecoratorConfig {
39
+ /** Table strategy: 'sti' | 'cti' */
40
+ tableStrategy?: 'sti' | 'cti';
41
+ /** Storage type for the generated id primary key */
42
+ idType?: 'uuid' | 'text';
43
+ /** Code-owned feature toggle declarations */
44
+ features?: Record<string, {
45
+ defaultEnabled: boolean;
46
+ label?: string;
47
+ description?: string;
48
+ metadata?: Record<string, unknown>;
49
+ }>;
50
+ /** API configuration */
51
+ api?: {
52
+ include?: string[];
53
+ exclude?: string[];
54
+ };
55
+ /** CLI configuration */
56
+ cli?: boolean | {
57
+ include?: string[];
58
+ exclude?: string[];
59
+ skipApiCheck?: boolean | string[];
60
+ http?: boolean;
61
+ };
62
+ /** MCP configuration */
63
+ mcp?: {
64
+ include?: string[];
65
+ exclude?: string[];
66
+ };
67
+ /** Raw config object for unknown properties */
68
+ [key: string]: unknown;
69
+ }
70
+ /**
71
+ * Raw field definition from OXC AST
72
+ */
73
+ export interface RawFieldDefinition {
74
+ /** Field name */
75
+ name: string;
76
+ /** TypeScript type annotation as string (e.g., "string", "number", "Date") */
77
+ typeAnnotation: string | null;
78
+ /** Raw initializer expression as string */
79
+ initializer: string | null;
80
+ /** For numeric literals: whether it contains a decimal point */
81
+ hasDecimalPoint: boolean;
82
+ /** For numeric literals: the actual numeric value */
83
+ numericValue: number | null;
84
+ /** Decorators applied to this field */
85
+ decorators: RawDecorator[];
86
+ /** Whether field is optional (has ?) */
87
+ optional: boolean;
88
+ /** Whether field is static */
89
+ isStatic: boolean;
90
+ /** Whether field is readonly */
91
+ readonly: boolean;
92
+ /** Whether field is private/protected */
93
+ accessibility: 'public' | 'private' | 'protected';
94
+ /** Start line in source */
95
+ line: number;
96
+ }
97
+ /**
98
+ * Raw decorator information
99
+ */
100
+ export interface RawDecorator {
101
+ /** Decorator name (e.g., "field", "foreignKey") */
102
+ name: string;
103
+ /** Raw arguments as strings */
104
+ arguments: string[];
105
+ }
106
+ /**
107
+ * Raw method definition from OXC AST
108
+ */
109
+ export interface RawMethodDefinition {
110
+ /** Method name */
111
+ name: string;
112
+ /** Whether method is async */
113
+ async: boolean;
114
+ /** Whether method is static */
115
+ isStatic: boolean;
116
+ /** Accessibility modifier */
117
+ accessibility: 'public' | 'private' | 'protected';
118
+ /** Method parameters */
119
+ parameters: RawParameterDefinition[];
120
+ /** Return type annotation as string */
121
+ returnType: string | null;
122
+ /** JSDoc description if present */
123
+ description: string | null;
124
+ /**
125
+ * Config object of an `@method()` decorator on this method, when one is
126
+ * present. `{}` for a bare `@method()`; `undefined` when the method carries
127
+ * no `@method()` decorator at all — the two are distinct, because an
128
+ * explicit bare decorator still marks the method as deliberately reviewed.
129
+ *
130
+ * Values are extracted with the same literal-only rules the class-level
131
+ * `@smrt()` config uses, so an expression the scanner cannot resolve becomes
132
+ * a scan error rather than a silently dropped `expose: false`.
133
+ */
134
+ decoratorConfig?: Record<string, unknown>;
135
+ /** Start line in source */
136
+ line: number;
137
+ }
138
+ /**
139
+ * Raw parameter definition
140
+ */
141
+ export interface RawParameterDefinition {
142
+ /** Parameter name */
143
+ name: string;
144
+ /** Type annotation as string */
145
+ type: string | null;
146
+ /** Whether parameter is optional */
147
+ optional: boolean;
148
+ /** Default value as string */
149
+ defaultValue: string | null;
150
+ /**
151
+ * True when the parameter carries a type annotation the scanner could not
152
+ * express as a string — an intersection, tuple, conditional, mapped,
153
+ * `typeof`, or indexed-access type — or when an inline object literal
154
+ * contains such a member.
155
+ *
156
+ * This is the provenance that separates "the author wrote `any`" from "the
157
+ * scanner gave up": both previously reached the manifest as the string
158
+ * `'any'`. Consumers that must fail closed on an uncertain type (the API
159
+ * wire-ability gate) read this rather than trusting `type`.
160
+ *
161
+ * `type: null` with `typeUnresolved` absent means the parameter simply has
162
+ * no annotation, which is an implicit — and genuinely authored — `any`.
163
+ */
164
+ typeUnresolved?: boolean;
165
+ /**
166
+ * Resolved member types of an INLINE object-literal annotation
167
+ * (`{ onDone: () => void; target: Content }` → `['Function', 'Content']`),
168
+ * flattened across nested literals, arrays, and unions.
169
+ *
170
+ * `extractTypeName` collapses every inline literal to the single string
171
+ * `'object'`, which erases exactly the members a caller needs to judge
172
+ * whether the bag can cross a wire. NAMED bags (an interface, type alias,
173
+ * `Partial<>`/`Pick<>`) are deliberately NOT expanded — resolving them needs
174
+ * cross-file type resolution this AST layer does not do, and they are
175
+ * accepted heuristically by the consumers that care.
176
+ */
177
+ memberTypes?: string[];
178
+ /**
179
+ * For a top-level UNION, each branch with the inline members IT declared.
180
+ *
181
+ * `memberTypes` above flattens across branches, which lets one branch veto
182
+ * another: `{ callback: () => void } | string` is wire-able through its
183
+ * string branch, but the flattened `Function` rejected the whole parameter.
184
+ * A consumer that understands this field MUST prefer it over `memberTypes`
185
+ * for unions. Absent on a non-union parameter and on manifests generated
186
+ * before #2686.
187
+ */
188
+ unionBranches?: ParameterTypeBranch[];
189
+ }
190
+ /** One branch of a top-level union parameter type (#2686). */
191
+ export interface ParameterTypeBranch {
192
+ /** The branch's own type name, e.g. `string` or `object`. */
193
+ type: string;
194
+ /** Inline object members declared by THIS branch only. */
195
+ memberTypes?: string[];
196
+ }
197
+ /**
198
+ * Resolved class definition with inheritance chain
199
+ */
200
+ export interface ResolvedClassDefinition extends RawClassDefinition {
201
+ /** Full inheritance chain from base to this class */
202
+ inheritanceChain: string[];
203
+ /** STI base class name (if part of STI hierarchy) */
204
+ stiBase: string | null;
205
+ /** Effective table strategy (inherited or declared) */
206
+ effectiveTableStrategy: 'sti' | 'cti';
207
+ /** Whether this class uses STI (convenience boolean) */
208
+ isSTI: boolean;
209
+ /** Whether this class is a framework base class */
210
+ isFrameworkBase: boolean;
211
+ /** All fields including inherited (for STI) */
212
+ allFields: RawFieldDefinition[];
213
+ /** Package this class belongs to (if external) */
214
+ packageName: string | null;
215
+ }
216
+ /** The two module-scope helpers the agent-surface matcher recognizes. */
217
+ export type AgentSurfaceHelper = 'defineIntent' | 'definePlaybook';
218
+ /**
219
+ * Effect classification, mirroring `CapabilityEffect` in
220
+ * `@happyvertical/smrt-types`. Mirrored rather than imported because this
221
+ * package carries no `@happyvertical/*` dependency — core depends on it, and
222
+ * importing back would close the cycle.
223
+ */
224
+ export type AgentSurfaceEffect = 'read' | 'write' | 'destructive';
225
+ /** A fully resolved classification (#2587's fail-closed rule already applied). */
226
+ export interface AgentSurfaceCapability {
227
+ effect: AgentSurfaceEffect;
228
+ idempotent: boolean;
229
+ openWorld: boolean;
230
+ }
231
+ /** Plane a declaration is valid on. */
232
+ export type AgentSurfacePlane = 'browser' | 'server';
233
+ /** One emitted view intent (#2588). */
234
+ export interface AgentSurfaceIntent {
235
+ kind: 'intent';
236
+ /** Declared, dot-namespaced identity. This is the entry's stable identity. */
237
+ id: string;
238
+ description: string;
239
+ capability: AgentSurfaceCapability;
240
+ target: Record<string, unknown>;
241
+ /** Whether the declaration carried an `inputSchema` object. */
242
+ hasInputSchema: boolean;
243
+ /**
244
+ * Always exactly `['browser']`. An intent moves mounted browser state; a
245
+ * server-side agent reaches one only through the #2446 command/ack bridge,
246
+ * which the referencing PLAYBOOK declares. Typed as the literal tuple rather
247
+ * than the open plane list so the contract cannot be read as wider than it is.
248
+ */
249
+ planes: ['browser'];
250
+ /** Declaring module, relativized by the emitting caller. */
251
+ filePath: string;
252
+ }
253
+ /** One step of an emitted playbook (#2589). Playbooks cannot nest. */
254
+ export type AgentSurfacePlaybookStep = {
255
+ kind: 'operation';
256
+ model: string;
257
+ action: string;
258
+ } | {
259
+ kind: 'intent';
260
+ id: string;
261
+ };
262
+ /** One emitted playbook (#2589). */
263
+ export interface AgentSurfacePlaybook {
264
+ kind: 'playbook';
265
+ /** Declared registry key. This is the entry's stable identity. */
266
+ key: string;
267
+ title: string;
268
+ description: string;
269
+ steps: AgentSurfacePlaybookStep[];
270
+ planes: AgentSurfacePlane[];
271
+ /** False when `planes` was derived from the step kinds rather than declared. */
272
+ planesDeclared: boolean;
273
+ onStepFailure: 'abort' | 'continue';
274
+ enabled: boolean;
275
+ /** Declaring module, relativized by the emitting caller. */
276
+ filePath: string;
277
+ }
278
+ /** Why a recognized declaration could not be emitted. */
279
+ export type AgentSurfaceDiagnosticCode = 'non-literal-argument' | 'not-module-scope' | 'argument-count' | 'incomplete-declaration' | 'invalid-identity' | 'svelte-declaration' | 'duplicate-identity' | 'tool-name-collision';
280
+ /**
281
+ * Something a reader of the emitted surface has to know about a declaration.
282
+ *
283
+ * Two kinds, and the difference is whether the entry survived. Every code but
284
+ * `tool-name-collision` reports a declaration that is NOT emitted — never a
285
+ * silent omission, so each of those messages names `useWebMcpTool`, the escape
286
+ * hatch for a genuinely computed tool set. A `tool-name-collision` is
287
+ * advisory: the declaration IS emitted, and the diagnostic records that its
288
+ * derived WebMCP tool name is already spoken for by something outside the
289
+ * declared surface.
290
+ */
291
+ export interface AgentSurfaceDiagnostic {
292
+ code: AgentSurfaceDiagnosticCode;
293
+ helper: AgentSurfaceHelper;
294
+ message: string;
295
+ filePath: string;
296
+ line?: number;
297
+ column?: number;
298
+ }
299
+ /** The declared agent-addressable surface found by one scan. */
300
+ export interface AgentSurface {
301
+ intents: AgentSurfaceIntent[];
302
+ playbooks: AgentSurfacePlaybook[];
303
+ diagnostics: AgentSurfaceDiagnostic[];
304
+ }
305
+ /**
306
+ * Result from scanning a single file
307
+ */
308
+ export interface FileScanResult {
309
+ /** Source file path */
310
+ filePath: string;
311
+ /** Classes found in file */
312
+ classes: RawClassDefinition[];
313
+ /** Scan errors */
314
+ errors: ScanError[];
315
+ /** Parse time in milliseconds */
316
+ parseTimeMs: number;
317
+ /** Type alias declarations found in file (name → resolved type string) */
318
+ typeAliases: Record<string, string>;
319
+ /** SMRT package imports found in file (package name → Set of imported class names) */
320
+ smrtImports?: Map<string, Set<string>>;
321
+ /**
322
+ * Declared view intents and playbooks found in the file, plus a diagnostic
323
+ * for every recognized declaration that is not statically emittable (#2591).
324
+ * Omitted when the file declares none.
325
+ */
326
+ agentSurface?: AgentSurface;
327
+ }
328
+ /**
329
+ * Scan error
330
+ */
331
+ export interface ScanError {
332
+ /** Error message */
333
+ message: string;
334
+ /** Source file */
335
+ filePath: string;
336
+ /** Line number (1-based) */
337
+ line?: number;
338
+ /** Column number (1-based) */
339
+ column?: number;
340
+ /** Error severity */
341
+ severity: 'error' | 'warning';
342
+ }
343
+ /**
344
+ * Result from scanning multiple files
345
+ */
346
+ export interface ScanResults {
347
+ /** All scanned files */
348
+ files: FileScanResult[];
349
+ /** All classes found (flattened) */
350
+ classes: RawClassDefinition[];
351
+ /** All errors (flattened) */
352
+ errors: ScanError[];
353
+ /** Total parse time in milliseconds */
354
+ totalParseTimeMs: number;
355
+ /** Number of files scanned */
356
+ fileCount: number;
357
+ /** Accumulated type aliases across all files */
358
+ typeAliases: Record<string, string>;
359
+ /** Accumulated SMRT package imports across all files (package name → Set of imported class names) */
360
+ smrtImports?: Map<string, Set<string>>;
361
+ /**
362
+ * The project's declared agent-addressable surface, merged across files with
363
+ * deterministic identity so emission never depends on file order (#2591).
364
+ */
365
+ agentSurface: AgentSurface;
366
+ }
367
+ /**
368
+ * Configuration options for {@link OxcScanner}.
369
+ *
370
+ * All fields are optional; reasonable defaults are applied when omitted.
371
+ *
372
+ * @see {@link OxcScanner}
373
+ */
374
+ export interface OxcScannerOptions {
375
+ /** Glob patterns to include */
376
+ include?: string[];
377
+ /** Glob patterns to exclude */
378
+ exclude?: string[];
379
+ /** Base directory for scanning */
380
+ cwd?: string;
381
+ /** Path to tsconfig.json for module resolution */
382
+ tsconfig?: string;
383
+ /** Whether to follow imports to find base classes */
384
+ followImports?: boolean;
385
+ /** Known base classes (avoid resolution) */
386
+ baseClasses?: string[];
387
+ /** Include private methods in output */
388
+ includePrivateMethods?: boolean;
389
+ /** Include static methods in output */
390
+ includeStaticMethods?: boolean;
391
+ /** External package manifests for base class resolution */
392
+ externalManifests?: Map<string, ExternalManifest>;
393
+ /**
394
+ * Follow symbolic links while discovering files. Defaults to `false`.
395
+ *
396
+ * A package's own sources are real files, while a pnpm `node_modules` is a
397
+ * symlink graph with cycles: every store entry links back out to its
398
+ * siblings, so a link-following walk reaches the same real directory once per
399
+ * path that leads to it and never terminates in practice. Discovery therefore
400
+ * stays on real directories unless a caller explicitly opts back in.
401
+ */
402
+ followSymbolicLinks?: boolean;
403
+ /**
404
+ * Match module-scope `defineIntent()` / `definePlaybook()` declarations and
405
+ * report `.svelte` declarations the scanner can never read (#2591). Defaults
406
+ * to `true`.
407
+ */
408
+ agentSurface?: boolean;
409
+ /**
410
+ * Glob patterns searched for `.svelte` declarations the scanner cannot read.
411
+ * Only used when {@link OxcScannerOptions.agentSurface} is enabled.
412
+ */
413
+ svelteInclude?: string[];
414
+ /**
415
+ * Glob patterns searched for `defineIntent` / `definePlaybook` declarations,
416
+ * independently of {@link OxcScannerOptions.include}.
417
+ *
418
+ * A model scan is routinely narrowed to where models live, but an intent
419
+ * sidecar lives beside the component that uses it; binding declaration
420
+ * discovery to the class glob would silently drop those. Only used when
421
+ * {@link OxcScannerOptions.agentSurface} is enabled.
422
+ */
423
+ agentSurfaceInclude?: string[];
424
+ }
425
+ /**
426
+ * Describes a pre-loaded manifest from an installed SMRT package, used by
427
+ * {@link InheritanceResolver} to resolve base classes that originate outside
428
+ * the local project source.
429
+ *
430
+ * Build tooling (e.g. the SMRT CLI / vitest plugin) loads each installed
431
+ * `@happyvertical/smrt-*` package's `manifest.json` and converts it into an
432
+ * `ExternalManifest` before passing it to the scanner.
433
+ *
434
+ * @see {@link OxcScannerOptions.externalManifests}
435
+ * @see {@link InheritanceResolver.addExternalManifest}
436
+ */
437
+ export interface ExternalManifest {
438
+ /** npm package name, e.g. `'@happyvertical/smrt-profiles'`. */
439
+ packageName: string;
440
+ /** SemVer version string of the installed package. */
441
+ packageVersion: string;
442
+ /** All class definitions exported by the package, keyed by class name. */
443
+ classes: Map<string, RawClassDefinition>;
444
+ }
445
+ /**
446
+ * The set of SMRT column types that the scanner can infer for a field.
447
+ *
448
+ * | Value | DB column type | Notes |
449
+ * |---|---|---|
450
+ * | `text` | `TEXT` / `VARCHAR` | Default for `string` and unknown types |
451
+ * | `integer` | `INTEGER` | `number` with `= 0` initialiser |
452
+ * | `decimal` | `DECIMAL` | `number` with `= 0.0` initialiser |
453
+ * | `boolean` | `BOOLEAN` | `boolean` annotation or literal initialiser |
454
+ * | `datetime` | `DATETIME` | `Date` annotation |
455
+ * | `json` | `JSON` / `TEXT` | Arrays, `Record<>`, object types |
456
+ * | `foreignKey` | `UUID` by default (FK column) | `@foreignKey(Class)` decorator |
457
+ * | `crossPackageRef` | `UUID` by default (no FK constraint) | `@crossPackageRef('@pkg:Class')` decorator |
458
+ * | `oneToMany` | — (virtual) | `@oneToMany(Class)` decorator |
459
+ * | `manyToMany` | — (virtual) | `@manyToMany(Class)` decorator |
460
+ * | `meta` | Stored in `_meta_data` | STI child field wrapped in `Meta<T>` |
461
+ * | `unknown` | — | Could not be determined |
462
+ *
463
+ * @see {@link FieldTypeInference} for the full inference result shape.
464
+ */
465
+ export type InferredFieldType = 'text' | 'integer' | 'decimal' | 'boolean' | 'datetime' | 'json' | 'foreignKey' | 'crossPackageRef' | 'oneToMany' | 'manyToMany' | 'meta' | 'unknown';
466
+ /**
467
+ * Result produced by {@link ManifestAdapter.inferFieldType} for a single field.
468
+ *
469
+ * In addition to the inferred `type`, carries the `source` of the inference
470
+ * so callers can distinguish authoritative decorator-driven results from
471
+ * heuristic guesses and provide better diagnostics.
472
+ *
473
+ * @see {@link InferredFieldType} for valid `type` values.
474
+ * @see {@link ManifestAdapter.inferFieldType} for inference priority rules.
475
+ */
476
+ export interface FieldTypeInference {
477
+ /** Inferred SMRT type */
478
+ type: InferredFieldType;
479
+ /** Related class for relationship types */
480
+ related?: string;
481
+ /** Default value if extractable */
482
+ defaultValue?: unknown;
483
+ /** Whether field is required */
484
+ required: boolean;
485
+ /** Inference source for debugging */
486
+ source: 'helper' | 'decorator' | 'annotation' | 'heuristic' | 'default';
487
+ /** Underlying type for meta fields (e.g., 'string' inside Meta<string>) */
488
+ underlyingType?: InferredFieldType;
489
+ /**
490
+ * Decorator-derived metadata that should be merged into the manifest
491
+ * field's `_meta` object. Used by `@crossPackageRef`, `@manyToMany`,
492
+ * `@meta` to carry options (`validate`, `through`, `indexed`, `idType`,
493
+ * etc.) that don't fit on the top-level FieldDefinition.
494
+ */
495
+ _meta?: Record<string, unknown>;
496
+ }
497
+ //# sourceMappingURL=types.d.ts.map