@happyvertical/smrt-scanner 0.57.46 → 0.57.48

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/AGENTS.md CHANGED
@@ -55,7 +55,8 @@ executes the source.
55
55
  - `verifyManifestCompleteness({ packageDir })` — publish guard: re-scans `src/`
56
56
  and asserts every `@smrt()` object reached `dist/manifest.json` (issue #1483).
57
57
  Returns `ok` / `incomplete` / `missing-manifest` / `scan-error` / `skipped`.
58
- Driven by `scripts/verify-manifest-completeness.mjs` from `prepack`.
58
+ Driven by `scripts/verify-manifest-completeness.mjs` (prepack; release
59
+ `--release` = `requireManifestExport`, #2853).
59
60
  - `discoverSourceFiles(options)` — shared bounded source-discovery policy used
60
61
  by `OxcScanner` and the core manifest preflight.
61
62
  - `extractAgentSurface` / `scanSvelteAgentSurface` / `mergeAgentSurfaces` —
@@ -325,11 +326,11 @@ place, `toKnowledgeAgentSurface` in `vite-plugin/index.ts`.
325
326
  access) — `type` still reads `'any'` for compatibility, so that flag is the
326
327
  only thing separating it from an authored `any`. `memberTypes` carries the
327
328
  members of an INLINE object literal, which `extractTypeName` otherwise
328
- flattens to `'object'`; NAMED bags stay unexpanded on purpose. Core's API
329
- wire-ability gate fails closed on both (#2686). The bare `object` keyword is
330
- resolved for parameters only — `ManifestAdapter.inferFromAnnotation` gives an
331
- `object`-typed FIELD a `{}` column default, so naming it in `extractTypeName`
332
- would silently change DDL.
329
+ flattens to `'object'`; NAMED bags stay unexpanded. Core's API
330
+ wire-ability gate fails closed on both (#2686). Bare `object` resolves for
331
+ parameters only: `ManifestAdapter.inferFromAnnotation` gives an `object`
332
+ FIELD a `{}` column default, so naming it in `extractTypeName` would change
333
+ DDL. Same-module aliases: `resolvedType` (#4327).
333
334
  - **`@method()` config is read with `requireLiteralValues`**, like `@smrt()`: an
334
335
  unresolvable value is a scan error, because a dropped `expose: false` restores
335
336
  the routing the author was withholding. `decoratorConfig` is `undefined` for
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { dirname, isAbsolute, relative, resolve, sep, win32 } from "node:path";
3
- import { glob } from "tinyglobby";
3
+ import { glob, isDynamicPattern } from "tinyglobby";
4
4
  import { parseSync } from "oxc-parser";
5
5
  //#region src/source-location.ts
6
6
  function getLineColumn(sourceText, offset) {
@@ -725,15 +725,40 @@ var MANDATORY_DISCOVERY_EXCLUDES = Object.freeze([
725
725
  ]);
726
726
  async function discoverSourceFiles(options) {
727
727
  const cwd = resolve(options.cwd);
728
- return glob(options.include.map((pattern) => relativeGlobToCwd(pattern, cwd)), {
729
- cwd,
728
+ const patterns = options.include.map((pattern) => relativeGlobToCwd(pattern, cwd));
729
+ const exclusions = options.exclude.map((pattern) => relativeGlobToCwd(pattern, cwd));
730
+ let discoveryCwd = cwd;
731
+ for (const pattern of [...patterns, ...exclusions]) {
732
+ const target = resolve(cwd, pattern.startsWith("!") && !pattern.startsWith("!(") ? pattern.slice(1) : pattern);
733
+ while (relative(discoveryCwd, target).split(sep)[0] === "..") discoveryCwd = dirname(discoveryCwd);
734
+ }
735
+ const rebase = (pattern, bound) => {
736
+ const negative = pattern.startsWith("!") && !pattern.startsWith("!(");
737
+ const body = negative ? pattern.slice(1) : pattern;
738
+ const rebased = bound && (body === "**" || body.startsWith("**/")) ? body : normalizeGlobSeparators(relative(discoveryCwd, resolve(cwd, body)));
739
+ return negative ? `!${rebased}` : rebased;
740
+ };
741
+ const sourcePrunes = /* @__PURE__ */ new Set();
742
+ const files = await glob(patterns.filter((pattern) => {
743
+ if (pattern.startsWith("!") && !pattern.startsWith("!(")) return true;
744
+ const parts = normalizeGlobSeparators(relative(cwd, resolve(cwd, pattern))).split("/");
745
+ const dynamic = parts.findIndex((part) => isDynamicPattern(part));
746
+ const literal = dynamic < 0 ? parts : parts.slice(0, dynamic);
747
+ if (literal.some((part) => part === "node_modules" || part.startsWith(".") && part !== "." && part !== "..")) return false;
748
+ const prefix = dynamic < 0 ? literal.slice(0, -1) : literal;
749
+ const root = normalizeGlobSeparators(relative(discoveryCwd, resolve(cwd, ...prefix)));
750
+ for (const prune of MANDATORY_DISCOVERY_EXCLUDES) sourcePrunes.add(root ? `${root}/${prune}` : prune);
751
+ return true;
752
+ }).map((pattern) => rebase(pattern, pattern.startsWith("!") && !pattern.startsWith("!("))), {
753
+ cwd: discoveryCwd,
730
754
  expandDirectories: false,
731
- ignore: [...options.exclude.map((pattern) => relativeGlobToCwd(pattern, cwd)), ...MANDATORY_DISCOVERY_EXCLUDES],
755
+ ignore: [...exclusions.map((pattern) => rebase(pattern, true)), ...sourcePrunes],
732
756
  absolute: true,
733
757
  onlyFiles: true,
734
758
  dot: true,
735
759
  followSymbolicLinks: options.followSymbolicLinks ?? false
736
760
  });
761
+ return [...new Set(files)].sort();
737
762
  }
738
763
  function relativeGlobToCwd(pattern, cwd) {
739
764
  const windowsAbsolute = win32.isAbsolute(pattern);
@@ -2606,6 +2631,7 @@ function parseFile(filePath) {
2606
2631
  const extracted = extractClassFromNode(node, filePath, sourceText, importAliases, ctx);
2607
2632
  if (extracted) classes.push(extracted);
2608
2633
  }
2634
+ resolveLocalParameterAliases(classes, typeAliases);
2609
2635
  reportUnresolvedSpreads(ctx.unresolved, filePath, sourceText, errors);
2610
2636
  agentSurface = maybeExtractAgentSurface(program, sourceText, filePath);
2611
2637
  if (sourceMayDeclareRecipe(sourceText)) {
@@ -2746,6 +2772,7 @@ function parseSource(sourceText, filename = "test.ts") {
2746
2772
  const extracted = extractClassFromNode(node, filename, sourceText, importAliases, ctx);
2747
2773
  if (extracted) classes.push(extracted);
2748
2774
  }
2775
+ resolveLocalParameterAliases(classes, typeAliases);
2749
2776
  reportUnresolvedSpreads(ctx.unresolved, filename, sourceText, errors);
2750
2777
  agentSurface = maybeExtractAgentSurface(program, sourceText, filename);
2751
2778
  if (sourceMayDeclareRecipe(sourceText)) {
@@ -2872,6 +2899,27 @@ function extractTypeAliases(body) {
2872
2899
  }
2873
2900
  return aliases;
2874
2901
  }
2902
+ var MAX_PARAMETER_ALIAS_DEPTH = 8;
2903
+ var BARE_TYPE_IDENTIFIER = /^[A-Za-z_$][\w$]*$/;
2904
+ function resolveParameterAlias(type, aliases) {
2905
+ if (!type || !BARE_TYPE_IDENTIFIER.test(type) || !Object.hasOwn(aliases, type)) return;
2906
+ const seen = /* @__PURE__ */ new Set();
2907
+ let current = type;
2908
+ while (BARE_TYPE_IDENTIFIER.test(current) && Object.hasOwn(aliases, current)) {
2909
+ if (seen.has(current) || seen.size >= MAX_PARAMETER_ALIAS_DEPTH) return { aliasUnresolved: true };
2910
+ seen.add(current);
2911
+ current = aliases[current].trim();
2912
+ }
2913
+ return { resolvedType: current };
2914
+ }
2915
+ function resolveLocalParameterAliases(classes, aliases) {
2916
+ if (Object.keys(aliases).length === 0) return;
2917
+ for (const classDef of classes) for (const method of classDef.methods) for (const parameter of method.parameters) {
2918
+ if (parameter.typeUnresolved) continue;
2919
+ const resolution = resolveParameterAlias(parameter.type, aliases);
2920
+ if (resolution) Object.assign(parameter, resolution);
2921
+ }
2922
+ }
2875
2923
  function enumMembersToUnion(members) {
2876
2924
  const values = [];
2877
2925
  let next = 0;
@@ -4049,7 +4097,10 @@ var ManifestAdapter = class ManifestAdapter {
4049
4097
  * and type alias resolution (up to depth 5).
4050
4098
  * 4. **Numeric literal without annotation** — `version = 1` → `integer`.
4051
4099
  * 5. **Boolean literal without annotation** — `isRead = false` → `boolean`.
4052
- * 6. **Default** — falls back to `text`.
4100
+ * 6. **Boolean `@field({ default })` with no annotation or initializer** —
4101
+ * `@field({ default: false }) archived;` → `boolean`, matching runtime
4102
+ * decorator-only inference (#4295; code step 3.7).
4103
+ * 7. **Default** — falls back to `text`.
4053
4104
  *
4054
4105
  * @param field - The raw field definition to analyse.
4055
4106
  * @returns A {@link FieldTypeInference} describing the inferred type,
@@ -4081,6 +4132,13 @@ var ManifestAdapter = class ManifestAdapter {
4081
4132
  defaultValue: field.initializer === "true",
4082
4133
  source: "heuristic"
4083
4134
  };
4135
+ const booleanDefault = this.decoratorBooleanDefault(field);
4136
+ if (booleanDefault !== void 0) return {
4137
+ type: "boolean",
4138
+ required: false,
4139
+ defaultValue: booleanDefault,
4140
+ source: "decorator"
4141
+ };
4084
4142
  const hasDefaultValue = field.initializer !== null;
4085
4143
  return {
4086
4144
  type: "text",
@@ -4100,6 +4158,16 @@ var ManifestAdapter = class ManifestAdapter {
4100
4158
  return null;
4101
4159
  }
4102
4160
  /**
4161
+ * The boolean `default` of a `@field()` decorator on `field`, if any.
4162
+ */
4163
+ decoratorBooleanDefault(field) {
4164
+ for (const decorator of field.decorators) {
4165
+ if (decorator.name !== "field") continue;
4166
+ const fieldDefault = this.parseFieldDecoratorOptions(decorator.arguments[0])?.default;
4167
+ if (typeof fieldDefault === "boolean") return fieldDefault;
4168
+ }
4169
+ }
4170
+ /**
4103
4171
  * Infer type from field decorator
4104
4172
  */
4105
4173
  inferFromDecorator(decorator, field) {
@@ -4532,7 +4600,9 @@ var ManifestAdapter = class ManifestAdapter {
4532
4600
  default: p.defaultValue ? this.parseDefaultValue(p.defaultValue, "string") : void 0,
4533
4601
  ...p.typeUnresolved ? { typeUnresolved: true } : {},
4534
4602
  ...p.memberTypes ? { memberTypes: p.memberTypes } : {},
4535
- ...p.unionBranches ? { unionBranches: p.unionBranches } : {}
4603
+ ...p.unionBranches ? { unionBranches: p.unionBranches } : {},
4604
+ ...p.resolvedType ? { resolvedType: p.resolvedType } : {},
4605
+ ...p.aliasUnresolved ? { aliasUnresolved: true } : {}
4536
4606
  })),
4537
4607
  returnType: method.returnType || "any",
4538
4608
  description: method.description || void 0,
@@ -5058,4 +5128,4 @@ var OxcScanner = class {
5058
5128
  //#endregion
5059
5129
  export { isPrunedAgentSurfacePath as C, sourceMayDeclareAgentSurface as E, isAgentSurfaceSourcePath as S, scanSvelteAgentSurface as T, normalizeGlobSeparators as _, extractSmrtImports as a, emptyAgentSurface as b, parseRecipeFile as c, extractRecipes as d, resolveRecipes as f, discoverSourceFiles as g, resolveEnumValues as h, defaultCollectionName as i, parseSource as l, InheritanceResolver as m, parseUiSelectorsFile as n, parseAgentSurfaceFile as o, sourceMayDeclareRecipe as p, ManifestAdapter as r, parseFile as s, OxcScanner as t, deriveHelpFieldRefs as u, relativeGlobToCwd as v, mergeAgentSurfaces as w, extractAgentSurface as x, checkAgentSurfaceToolNames as y };
5060
5130
 
5061
- //# sourceMappingURL=scanner-QMkE5DFY.js.map
5131
+ //# sourceMappingURL=scanner-D-vcuXjW.js.map