@happyvertical/smrt-scanner 0.43.9 → 0.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { n as ManifestAdapter, t as OxcScanner } from "./chunks/scanner-CW9g-vyS.js";
3
- import { dirname, resolve } from "node:path";
2
+ import { n as ManifestAdapter, t as OxcScanner } from "./chunks/scanner-C3VqXyzB.js";
4
3
  import { readFileSync, writeFileSync } from "node:fs";
4
+ import { dirname, resolve } from "node:path";
5
5
  import { fileURLToPath } from "node:url";
6
6
  //#region src/cli.ts
7
7
  function parseArgs(args) {
package/dist/index.d.ts CHANGED
@@ -1,3 +1,97 @@
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
+ * A recognized declaration that is not emittable.
17
+ *
18
+ * Never a silent omission: every message names `useWebMcpTool`, the escape
19
+ * hatch for a genuinely computed tool set.
20
+ */
21
+ export declare interface AgentSurfaceDiagnostic {
22
+ code: AgentSurfaceDiagnosticCode;
23
+ helper: AgentSurfaceHelper;
24
+ message: string;
25
+ filePath: string;
26
+ line?: number;
27
+ column?: number;
28
+ }
29
+
30
+ /** Why a recognized declaration could not be emitted. */
31
+ export declare type AgentSurfaceDiagnosticCode = 'non-literal-argument' | 'not-module-scope' | 'argument-count' | 'incomplete-declaration' | 'invalid-identity' | 'svelte-declaration' | 'duplicate-identity';
32
+
33
+ /**
34
+ * Effect classification, mirroring `CapabilityEffect` in
35
+ * `@happyvertical/smrt-types`. Mirrored rather than imported because this
36
+ * package carries no `@happyvertical/*` dependency — core depends on it, and
37
+ * importing back would close the cycle.
38
+ */
39
+ export declare type AgentSurfaceEffect = 'read' | 'write' | 'destructive';
40
+
41
+ /** The two module-scope helpers the agent-surface matcher recognizes. */
42
+ export declare type AgentSurfaceHelper = 'defineIntent' | 'definePlaybook';
43
+
44
+ /** One emitted view intent (#2588). */
45
+ export declare interface AgentSurfaceIntent {
46
+ kind: 'intent';
47
+ /** Declared, dot-namespaced identity. This is the entry's stable identity. */
48
+ id: string;
49
+ description: string;
50
+ capability: AgentSurfaceCapability;
51
+ target: Record<string, unknown>;
52
+ /** Whether the declaration carried an `inputSchema` object. */
53
+ hasInputSchema: boolean;
54
+ /**
55
+ * Always exactly `['browser']`. An intent moves mounted browser state; a
56
+ * server-side agent reaches one only through the #2446 command/ack bridge,
57
+ * which the referencing PLAYBOOK declares. Typed as the literal tuple rather
58
+ * than the open plane list so the contract cannot be read as wider than it is.
59
+ */
60
+ planes: ['browser'];
61
+ /** Declaring module, relativized by the emitting caller. */
62
+ filePath: string;
63
+ }
64
+
65
+ /** Plane a declaration is valid on. */
66
+ export declare type AgentSurfacePlane = 'browser' | 'server';
67
+
68
+ /** One emitted playbook (#2589). */
69
+ export declare interface AgentSurfacePlaybook {
70
+ kind: 'playbook';
71
+ /** Declared registry key. This is the entry's stable identity. */
72
+ key: string;
73
+ title: string;
74
+ description: string;
75
+ steps: AgentSurfacePlaybookStep[];
76
+ planes: AgentSurfacePlane[];
77
+ /** False when `planes` was derived from the step kinds rather than declared. */
78
+ planesDeclared: boolean;
79
+ onStepFailure: 'abort' | 'continue';
80
+ enabled: boolean;
81
+ /** Declaring module, relativized by the emitting caller. */
82
+ filePath: string;
83
+ }
84
+
85
+ /** One step of an emitted playbook (#2589). Playbooks cannot nest. */
86
+ export declare type AgentSurfacePlaybookStep = {
87
+ kind: 'operation';
88
+ model: string;
89
+ action: string;
90
+ } | {
91
+ kind: 'intent';
92
+ id: string;
93
+ };
94
+
1
95
  declare interface ArrayExpression extends BaseNode {
2
96
  type: 'ArrayExpression';
3
97
  elements: (Expression | SpreadElement | null)[];
@@ -73,6 +167,9 @@ declare interface Decorator extends BaseNode {
73
167
  */
74
168
  export declare function discoverSourceFiles(options: SourceDiscoveryOptions): Promise<string[]>;
75
169
 
170
+ /** An empty surface, for callers that skipped the scan. */
171
+ export declare function emptyAgentSurface(): AgentSurface;
172
+
76
173
  declare interface ExportDefaultDeclaration extends BaseNode {
77
174
  type: 'ExportDefaultDeclaration';
78
175
  declaration: Statement | Expression;
@@ -113,6 +210,24 @@ export declare interface ExternalManifest {
113
210
  classes: Map<string, RawClassDefinition>;
114
211
  }
115
212
 
213
+ /**
214
+ * Match `defineIntent(...)` / `definePlaybook(...)` declarations in one parsed
215
+ * module.
216
+ *
217
+ * @returns Emittable entries plus a diagnostic for every recognized call that
218
+ * is not emittable. A recognized call always produces exactly one of the two.
219
+ */
220
+ export declare function extractAgentSurface(options: ExtractAgentSurfaceOptions): AgentSurface;
221
+
222
+ export declare interface ExtractAgentSurfaceOptions {
223
+ /** Program body from an OXC parse. */
224
+ body: readonly unknown[];
225
+ /** Full source text, used for diagnostic line/column. */
226
+ sourceText: string;
227
+ /** Path recorded on every emitted entry and diagnostic. */
228
+ filePath: string;
229
+ }
230
+
116
231
  /* Excluded from this release type: extractSmrtImports */
117
232
 
118
233
  declare interface FieldDefinition {
@@ -183,6 +298,12 @@ export declare interface FileScanResult {
183
298
  typeAliases: Record<string, string>;
184
299
  /** SMRT package imports found in file (package name → Set of imported class names) */
185
300
  smrtImports?: Map<string, Set<string>>;
301
+ /**
302
+ * Declared view intents and playbooks found in the file, plus a diagnostic
303
+ * for every recognized declaration that is not statically emittable (#2591).
304
+ * Omitted when the file declares none.
305
+ */
306
+ agentSurface?: AgentSurface;
186
307
  }
187
308
 
188
309
  declare interface FunctionExpression extends BaseNode {
@@ -465,6 +586,41 @@ export declare class InheritanceResolver {
465
586
  };
466
587
  }
467
588
 
589
+ /**
590
+ * Whether the agent-surface emitter reads this file. **This is the one
591
+ * authority on that question.**
592
+ *
593
+ * Both the scanner's declaration pass and `dev:knowledge-check`'s freshness
594
+ * re-scan call it, because the two answering differently is not a cosmetic
595
+ * inconsistency: a file the emitter reads but the checker skips is reported as
596
+ * "no longer present in source" on every run, and a file the checker reads but
597
+ * the emitter skips is reported as "missing from smrt-knowledge.json" — both
598
+ * unclearable by any rebuild. It is a path predicate rather than a glob so the
599
+ * two sides cannot drift through differing glob semantics either.
600
+ *
601
+ * Callers still pass globs to prune the WALK for speed; this decides what
602
+ * counts.
603
+ */
604
+ export declare function isAgentSurfaceSourcePath(filePath: string, rootDir?: string): boolean;
605
+
606
+ /**
607
+ * Whether a path lies in a directory declarations are never read from,
608
+ * measured **relative to the project root**.
609
+ *
610
+ * `rootDir` is not optional in spirit. Matching these segments against an
611
+ * absolute path would disable the entire feature for a checkout that merely
612
+ * LIVES under one — a container with `WORKDIR /build`, or a clone in
613
+ * `~/build/…` — and it would do so with no diagnostic at all, because the
614
+ * freshness check applies the same predicate and would agree that nothing is
615
+ * declared. That is the silent drop this module exists to prevent, so the same
616
+ * care `discovery.ts` takes to rewrite globs relative to `cwd` applies here.
617
+ *
618
+ * Exported so the `.svelte` pass and `dev:knowledge-check`'s walk prune
619
+ * identically; a `.svelte` file cannot go through
620
+ * {@link isAgentSurfaceSourcePath}, which rejects it on extension.
621
+ */
622
+ export declare function isPrunedAgentSurfacePath(filePath: string, rootDir?: string): boolean;
623
+
468
624
  /**
469
625
  * Report every persisted `number` field whose declared precision contradicts
470
626
  * its name — money declared decimal, or a rate declared integer.
@@ -678,6 +834,27 @@ declare interface MemberExpression extends BaseNode {
678
834
  computed: boolean;
679
835
  }
680
836
 
837
+ /**
838
+ * Merge per-file results into ONE deterministic surface.
839
+ *
840
+ * Emission must not depend on the order the file system happened to hand files
841
+ * to the scanner — a cross-profile parity snapshot that churns on directory
842
+ * order proves nothing. So identity is total and content-derived:
843
+ *
844
+ * - an intent is identified by its `id`, a playbook by its `key`;
845
+ * - entries sort by that identity, then by the recorded source path;
846
+ * - when two files declare the same identity, the entry from the
847
+ * lexicographically smaller path wins and the other is reported as a
848
+ * `duplicate-identity` diagnostic — a rule that gives the same answer for
849
+ * every input order, which "first one scanned wins" does not;
850
+ * - diagnostics sort by path, then line, column, code, and message.
851
+ *
852
+ * `relativize` maps an absolute scan path to the stable path recorded in the
853
+ * artifact; callers pass the package root's relativizer so a checked-in
854
+ * artifact never carries a machine-specific absolute path.
855
+ */
856
+ export declare function mergeAgentSurfaces(surfaces: readonly AgentSurface[], relativize?: (filePath: string) => string): AgentSurface;
857
+
681
858
  declare interface MethodDefinition {
682
859
  name: string;
683
860
  async: boolean;
@@ -945,6 +1122,37 @@ export declare class OxcScanner {
945
1122
  * or `~/.cache` would then match nothing at all, silently.
946
1123
  */
947
1124
  private discoverFiles;
1125
+ /**
1126
+ * Find declarations in files the CLASS scan did not cover.
1127
+ *
1128
+ * The class `include` is routinely narrowed to where models live, but an
1129
+ * intent sidecar lives beside its component. Without this pass those
1130
+ * declarations would be missing from every artifact with no diagnostic — a
1131
+ * silent omission, and in the shipped SvelteKit template's own layout at
1132
+ * that. Files already parsed by the class scan are skipped so a declaration
1133
+ * is never counted twice and cannot collide with itself.
1134
+ *
1135
+ * @param alreadyScanned - Absolute paths the class scan already parsed.
1136
+ */
1137
+ private scanDeclarationsOutsideClassGlob;
1138
+ /**
1139
+ * Search `.svelte` files for declarations the scanner can never read.
1140
+ *
1141
+ * A `.svelte` file is not a TypeScript program and is never parsed here, so
1142
+ * this pass produces diagnostics only — never an emitted entry. It exists
1143
+ * because the alternative is silence: an intent declared inline in a
1144
+ * component simply would not appear anywhere, with nothing to explain why.
1145
+ */
1146
+ private scanSvelteDeclarations;
1147
+ /**
1148
+ * Record a declaring module as a `cwd`-relative POSIX path.
1149
+ *
1150
+ * Emitted entries land in checked-in artifacts, so an absolute path would
1151
+ * make them machine-specific and a Windows separator would make them
1152
+ * platform-specific — either one churns a snapshot that is supposed to prove
1153
+ * two builds agree.
1154
+ */
1155
+ private relativizeSourcePath;
948
1156
  /**
949
1157
  * Parse a single file with timing
950
1158
  */
@@ -987,8 +1195,47 @@ export declare interface OxcScannerOptions {
987
1195
  * stays on real directories unless a caller explicitly opts back in.
988
1196
  */
989
1197
  followSymbolicLinks?: boolean;
1198
+ /**
1199
+ * Match module-scope `defineIntent()` / `definePlaybook()` declarations and
1200
+ * report `.svelte` declarations the scanner can never read (#2591). Defaults
1201
+ * to `true`.
1202
+ */
1203
+ agentSurface?: boolean;
1204
+ /**
1205
+ * Glob patterns searched for `.svelte` declarations the scanner cannot read.
1206
+ * Only used when {@link OxcScannerOptions.agentSurface} is enabled.
1207
+ */
1208
+ svelteInclude?: string[];
1209
+ /**
1210
+ * Glob patterns searched for `defineIntent` / `definePlaybook` declarations,
1211
+ * independently of {@link OxcScannerOptions.include}.
1212
+ *
1213
+ * A model scan is routinely narrowed to where models live, but an intent
1214
+ * sidecar lives beside the component that uses it; binding declaration
1215
+ * discovery to the class glob would silently drop those. Only used when
1216
+ * {@link OxcScannerOptions.agentSurface} is enabled.
1217
+ */
1218
+ agentSurfaceInclude?: string[];
990
1219
  }
991
1220
 
1221
+ /**
1222
+ * Read one file for agent-surface declarations ONLY (#2591).
1223
+ *
1224
+ * Exists because the agent surface must not be confined to the class scan's
1225
+ * `include` glob: an application that scans `src/lib/objects/**` for its models
1226
+ * — the shipped template does exactly that — would otherwise never see a
1227
+ * `src/lib/agent/Foo.intents.ts` sidecar, and the declaration would vanish from
1228
+ * every artifact with no diagnostic. Silent omission is the one failure this
1229
+ * matcher exists to prevent, so declarations are discovered on their own terms.
1230
+ *
1231
+ * The token pre-filter runs before the parse, so a file that declares nothing
1232
+ * costs one read and one `String.includes`.
1233
+ *
1234
+ * @returns The file's surface, or `undefined` when it declares nothing or
1235
+ * cannot be read.
1236
+ */
1237
+ export declare function parseAgentSurfaceFile(filePath: string): AgentSurface | undefined;
1238
+
992
1239
  /**
993
1240
  * Parse a single TypeScript file and extract SMRT class definitions.
994
1241
  *
@@ -1290,8 +1537,15 @@ export declare interface ScanResults {
1290
1537
  typeAliases: Record<string, string>;
1291
1538
  /** Accumulated SMRT package imports across all files (package name → Set of imported class names) */
1292
1539
  smrtImports?: Map<string, Set<string>>;
1540
+ /**
1541
+ * The project's declared agent-addressable surface, merged across files with
1542
+ * deterministic identity so emission never depends on file order (#2591).
1543
+ */
1544
+ agentSurface: AgentSurface;
1293
1545
  }
1294
1546
 
1547
+ export declare function scanSvelteAgentSurface(filePath: string, sourceText?: string): AgentSurfaceDiagnostic[];
1548
+
1295
1549
  declare interface SmartObjectConfig {
1296
1550
  tableStrategy?: 'sti' | 'cti';
1297
1551
  idType?: 'uuid' | 'text';
@@ -1376,6 +1630,13 @@ declare interface SourceLocation {
1376
1630
  */
1377
1631
  export declare function sourceMayContainNumericPrecisionIssue(source: string): boolean;
1378
1632
 
1633
+ /**
1634
+ * Fast pre-check: a file that names neither helper cannot declare either, so
1635
+ * the AST walk is skipped entirely. Callers use it to keep the matcher off the
1636
+ * hot path of a large scan.
1637
+ */
1638
+ export declare function sourceMayDeclareAgentSurface(sourceText: string): boolean;
1639
+
1379
1640
  /**
1380
1641
  * Split an identifier into lowercase words on camelCase, PascalCase, digits,
1381
1642
  * and underscores. `totalAmountCents` → `['total', 'amount', 'cents']`.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { a as parseSource, c as normalizeGlobSeparators, i as parseFile, l as relativeGlobToCwd, n as ManifestAdapter, o as InheritanceResolver, r as extractSmrtImports, s as discoverSourceFiles, t as OxcScanner } from "./chunks/scanner-CW9g-vyS.js";
1
+ import { _ as sourceMayDeclareAgentSurface, a as parseFile, c as discoverSourceFiles, d as emptyAgentSurface, f as extractAgentSurface, g as scanSvelteAgentSurface, h as mergeAgentSurfaces, i as parseAgentSurfaceFile, l as normalizeGlobSeparators, m as isPrunedAgentSurfacePath, n as ManifestAdapter, o as parseSource, p as isAgentSurfaceSourcePath, r as extractSmrtImports, s as InheritanceResolver, t as OxcScanner, u as relativeGlobToCwd } from "./chunks/scanner-C3VqXyzB.js";
2
2
  import "./types.js";
3
- import { basename, resolve } from "node:path";
4
3
  import { existsSync, readFileSync } from "node:fs";
4
+ import { basename, resolve } from "node:path";
5
5
  //#region src/numeric-precision-lint.ts
6
6
  var MONEY_HEAD_WORDS = /* @__PURE__ */ new Set([
7
7
  "amount",
@@ -272,6 +272,6 @@ async function verifyManifestCompleteness(options) {
272
272
  };
273
273
  }
274
274
  //#endregion
275
- export { InheritanceResolver, ManifestAdapter, OxcScanner, classifyNumericFieldName, discoverSourceFiles, extractSmrtImports, lintNumericPrecision, normalizeGlobSeparators, parseFile, parseSource, relativeGlobToCwd, sourceMayContainNumericPrecisionIssue, splitIdentifierWords, verifyManifestCompleteness };
275
+ export { InheritanceResolver, ManifestAdapter, OxcScanner, classifyNumericFieldName, discoverSourceFiles, emptyAgentSurface, extractAgentSurface, extractSmrtImports, isAgentSurfaceSourcePath, isPrunedAgentSurfacePath, lintNumericPrecision, mergeAgentSurfaces, normalizeGlobSeparators, parseAgentSurfaceFile, parseFile, parseSource, relativeGlobToCwd, scanSvelteAgentSurface, sourceMayContainNumericPrecisionIssue, sourceMayDeclareAgentSurface, splitIdentifierWords, verifyManifestCompleteness };
276
276
 
277
277
  //# sourceMappingURL=index.js.map
package/dist/types.d.ts CHANGED
@@ -1,3 +1,97 @@
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
+ * A recognized declaration that is not emittable.
17
+ *
18
+ * Never a silent omission: every message names `useWebMcpTool`, the escape
19
+ * hatch for a genuinely computed tool set.
20
+ */
21
+ export declare interface AgentSurfaceDiagnostic {
22
+ code: AgentSurfaceDiagnosticCode;
23
+ helper: AgentSurfaceHelper;
24
+ message: string;
25
+ filePath: string;
26
+ line?: number;
27
+ column?: number;
28
+ }
29
+
30
+ /** Why a recognized declaration could not be emitted. */
31
+ export declare type AgentSurfaceDiagnosticCode = 'non-literal-argument' | 'not-module-scope' | 'argument-count' | 'incomplete-declaration' | 'invalid-identity' | 'svelte-declaration' | 'duplicate-identity';
32
+
33
+ /**
34
+ * Effect classification, mirroring `CapabilityEffect` in
35
+ * `@happyvertical/smrt-types`. Mirrored rather than imported because this
36
+ * package carries no `@happyvertical/*` dependency — core depends on it, and
37
+ * importing back would close the cycle.
38
+ */
39
+ export declare type AgentSurfaceEffect = 'read' | 'write' | 'destructive';
40
+
41
+ /** The two module-scope helpers the agent-surface matcher recognizes. */
42
+ export declare type AgentSurfaceHelper = 'defineIntent' | 'definePlaybook';
43
+
44
+ /** One emitted view intent (#2588). */
45
+ export declare interface AgentSurfaceIntent {
46
+ kind: 'intent';
47
+ /** Declared, dot-namespaced identity. This is the entry's stable identity. */
48
+ id: string;
49
+ description: string;
50
+ capability: AgentSurfaceCapability;
51
+ target: Record<string, unknown>;
52
+ /** Whether the declaration carried an `inputSchema` object. */
53
+ hasInputSchema: boolean;
54
+ /**
55
+ * Always exactly `['browser']`. An intent moves mounted browser state; a
56
+ * server-side agent reaches one only through the #2446 command/ack bridge,
57
+ * which the referencing PLAYBOOK declares. Typed as the literal tuple rather
58
+ * than the open plane list so the contract cannot be read as wider than it is.
59
+ */
60
+ planes: ['browser'];
61
+ /** Declaring module, relativized by the emitting caller. */
62
+ filePath: string;
63
+ }
64
+
65
+ /** Plane a declaration is valid on. */
66
+ export declare type AgentSurfacePlane = 'browser' | 'server';
67
+
68
+ /** One emitted playbook (#2589). */
69
+ export declare interface AgentSurfacePlaybook {
70
+ kind: 'playbook';
71
+ /** Declared registry key. This is the entry's stable identity. */
72
+ key: string;
73
+ title: string;
74
+ description: string;
75
+ steps: AgentSurfacePlaybookStep[];
76
+ planes: AgentSurfacePlane[];
77
+ /** False when `planes` was derived from the step kinds rather than declared. */
78
+ planesDeclared: boolean;
79
+ onStepFailure: 'abort' | 'continue';
80
+ enabled: boolean;
81
+ /** Declaring module, relativized by the emitting caller. */
82
+ filePath: string;
83
+ }
84
+
85
+ /** One step of an emitted playbook (#2589). Playbooks cannot nest. */
86
+ export declare type AgentSurfacePlaybookStep = {
87
+ kind: 'operation';
88
+ model: string;
89
+ action: string;
90
+ } | {
91
+ kind: 'intent';
92
+ id: string;
93
+ };
94
+
1
95
  /**
2
96
  * Describes a pre-loaded manifest from an installed SMRT package, used by
3
97
  * {@link InheritanceResolver} to resolve base classes that originate outside
@@ -67,6 +161,12 @@ export declare interface FileScanResult {
67
161
  typeAliases: Record<string, string>;
68
162
  /** SMRT package imports found in file (package name → Set of imported class names) */
69
163
  smrtImports?: Map<string, Set<string>>;
164
+ /**
165
+ * Declared view intents and playbooks found in the file, plus a diagnostic
166
+ * for every recognized declaration that is not statically emittable (#2591).
167
+ * Omitted when the file declares none.
168
+ */
169
+ agentSurface?: AgentSurface;
70
170
  }
71
171
 
72
172
  /**
@@ -127,6 +227,27 @@ export declare interface OxcScannerOptions {
127
227
  * stays on real directories unless a caller explicitly opts back in.
128
228
  */
129
229
  followSymbolicLinks?: boolean;
230
+ /**
231
+ * Match module-scope `defineIntent()` / `definePlaybook()` declarations and
232
+ * report `.svelte` declarations the scanner can never read (#2591). Defaults
233
+ * to `true`.
234
+ */
235
+ agentSurface?: boolean;
236
+ /**
237
+ * Glob patterns searched for `.svelte` declarations the scanner cannot read.
238
+ * Only used when {@link OxcScannerOptions.agentSurface} is enabled.
239
+ */
240
+ svelteInclude?: string[];
241
+ /**
242
+ * Glob patterns searched for `defineIntent` / `definePlaybook` declarations,
243
+ * independently of {@link OxcScannerOptions.include}.
244
+ *
245
+ * A model scan is routinely narrowed to where models live, but an intent
246
+ * sidecar lives beside the component that uses it; binding declaration
247
+ * discovery to the class glob would silently drop those. Only used when
248
+ * {@link OxcScannerOptions.agentSurface} is enabled.
249
+ */
250
+ agentSurfaceInclude?: string[];
130
251
  }
131
252
 
132
253
  /**
@@ -328,6 +449,11 @@ export declare interface ScanResults {
328
449
  typeAliases: Record<string, string>;
329
450
  /** Accumulated SMRT package imports across all files (package name → Set of imported class names) */
330
451
  smrtImports?: Map<string, Set<string>>;
452
+ /**
453
+ * The project's declared agent-addressable surface, merged across files with
454
+ * deterministic identity so emission never depends on file order (#2591).
455
+ */
456
+ agentSurface: AgentSurface;
331
457
  }
332
458
 
333
459
  export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-scanner",
3
- "version": "0.43.9",
3
+ "version": "0.44.0",
4
4
  "description": "High-performance TypeScript scanner using OXC for SMRT manifest generation",
5
5
  "author": "HappyVertical",
6
6
  "type": "module",