@agent-scope/manifest 1.19.0 → 1.20.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/index.cjs +113 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +49 -1
- package/dist/index.d.ts +49 -1
- package/dist/index.js +113 -4
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -489,6 +489,53 @@ function nodeReturnsJsx(node) {
|
|
|
489
489
|
visit(node);
|
|
490
490
|
return found;
|
|
491
491
|
}
|
|
492
|
+
function matchGlob(pattern, value) {
|
|
493
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
494
|
+
const regexStr = escaped.replace(/\*\*/g, "\xA7GLOBSTAR\xA7").replace(/\*/g, "[^/]*").replace(/§GLOBSTAR§/g, ".*");
|
|
495
|
+
const regex = new RegExp(`^${regexStr}$`, "i");
|
|
496
|
+
return regex.test(value);
|
|
497
|
+
}
|
|
498
|
+
function extractTsDocTags(declNode) {
|
|
499
|
+
let collection;
|
|
500
|
+
let internal = false;
|
|
501
|
+
const nodeWithDocs = declNode;
|
|
502
|
+
if (typeof nodeWithDocs.getJsDocs !== "function") {
|
|
503
|
+
return { collection, internal };
|
|
504
|
+
}
|
|
505
|
+
const jsDocs = nodeWithDocs.getJsDocs();
|
|
506
|
+
for (const jsDoc of jsDocs) {
|
|
507
|
+
for (const tag of jsDoc.getTags()) {
|
|
508
|
+
const tagName = tag.getTagName();
|
|
509
|
+
if (tagName === "collection") {
|
|
510
|
+
const comment = tag.getComment();
|
|
511
|
+
if (comment && typeof comment === "string") {
|
|
512
|
+
collection = comment.trim();
|
|
513
|
+
}
|
|
514
|
+
} else if (tagName === "internal") {
|
|
515
|
+
internal = true;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return { collection, internal };
|
|
520
|
+
}
|
|
521
|
+
function readCollectionFromScopeFile(scopeFilePath, project) {
|
|
522
|
+
let sf = project.getSourceFile(scopeFilePath);
|
|
523
|
+
if (!sf) {
|
|
524
|
+
sf = project.addSourceFileAtPath(scopeFilePath);
|
|
525
|
+
}
|
|
526
|
+
for (const varStmt of sf.getVariableStatements()) {
|
|
527
|
+
if (!varStmt.isExported()) continue;
|
|
528
|
+
for (const varDecl of varStmt.getDeclarations()) {
|
|
529
|
+
if (varDecl.getName() !== "collection") continue;
|
|
530
|
+
const initializer = varDecl.getInitializer();
|
|
531
|
+
if (!initializer) continue;
|
|
532
|
+
if (tsMorph.Node.isStringLiteral(initializer)) {
|
|
533
|
+
return initializer.getLiteralValue();
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
return void 0;
|
|
538
|
+
}
|
|
492
539
|
function processSourceFile(sourceFile, rootDir, project) {
|
|
493
540
|
const results = [];
|
|
494
541
|
const filePath = path.relative(rootDir, sourceFile.getFilePath());
|
|
@@ -549,7 +596,9 @@ function processSourceFile(sourceFile, rootDir, project) {
|
|
|
549
596
|
detectedHooks: detectHooks(fn),
|
|
550
597
|
requiredContexts: detectRequiredContexts(fn, sourceFile, project),
|
|
551
598
|
sideEffects: detectSideEffects(fn),
|
|
552
|
-
scopeFile: null
|
|
599
|
+
scopeFile: null,
|
|
600
|
+
// collection and internal will be filled in after all components are collected
|
|
601
|
+
internal: false
|
|
553
602
|
}
|
|
554
603
|
});
|
|
555
604
|
}
|
|
@@ -614,7 +663,8 @@ function processSourceFile(sourceFile, rootDir, project) {
|
|
|
614
663
|
detectedHooks: detectHooks(bodyNode),
|
|
615
664
|
requiredContexts: detectRequiredContexts(bodyNode, sourceFile, project),
|
|
616
665
|
sideEffects: detectSideEffects(bodyNode),
|
|
617
|
-
scopeFile: null
|
|
666
|
+
scopeFile: null,
|
|
667
|
+
internal: false
|
|
618
668
|
}
|
|
619
669
|
});
|
|
620
670
|
}
|
|
@@ -663,7 +713,8 @@ function processSourceFile(sourceFile, rootDir, project) {
|
|
|
663
713
|
detectedHooks: [],
|
|
664
714
|
requiredContexts: [],
|
|
665
715
|
sideEffects: detectSideEffects(cls),
|
|
666
|
-
scopeFile: null
|
|
716
|
+
scopeFile: null,
|
|
717
|
+
internal: false
|
|
667
718
|
}
|
|
668
719
|
});
|
|
669
720
|
}
|
|
@@ -731,11 +782,69 @@ function generateManifest(config) {
|
|
|
731
782
|
desc.scopeFile = scopeMeta;
|
|
732
783
|
}
|
|
733
784
|
}
|
|
785
|
+
const configCollections = config.collections ?? [];
|
|
786
|
+
const internalPatterns = config.internalPatterns ?? [];
|
|
787
|
+
for (const [compName, desc] of Object.entries(allComponents)) {
|
|
788
|
+
const absFilePath = desc.filePath.startsWith("/") ? desc.filePath : path.join(rootDir, desc.filePath);
|
|
789
|
+
const sf = project.getSourceFile(absFilePath);
|
|
790
|
+
let tsdocCollection;
|
|
791
|
+
let tsdocInternal = false;
|
|
792
|
+
if (sf) {
|
|
793
|
+
const fn = sf.getFunction(compName);
|
|
794
|
+
if (fn) {
|
|
795
|
+
const tags = extractTsDocTags(fn);
|
|
796
|
+
tsdocCollection = tags.collection;
|
|
797
|
+
tsdocInternal = tags.internal;
|
|
798
|
+
}
|
|
799
|
+
if (tsdocCollection === void 0 && !tsdocInternal) {
|
|
800
|
+
const varDecl = sf.getVariableDeclaration(compName);
|
|
801
|
+
if (varDecl) {
|
|
802
|
+
const varStmt = varDecl.getVariableStatement();
|
|
803
|
+
if (varStmt) {
|
|
804
|
+
const tags = extractTsDocTags(varStmt);
|
|
805
|
+
tsdocCollection = tags.collection;
|
|
806
|
+
tsdocInternal = tags.internal;
|
|
807
|
+
}
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
if (tsdocCollection === void 0 && !tsdocInternal) {
|
|
811
|
+
const cls = sf.getClass(compName);
|
|
812
|
+
if (cls) {
|
|
813
|
+
const tags = extractTsDocTags(cls);
|
|
814
|
+
tsdocCollection = tags.collection;
|
|
815
|
+
tsdocInternal = tags.internal;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
let scopeFileCollection;
|
|
820
|
+
if (desc.scopeFile) {
|
|
821
|
+
scopeFileCollection = readCollectionFromScopeFile(desc.scopeFile.filePath, project);
|
|
822
|
+
}
|
|
823
|
+
let configCollection;
|
|
824
|
+
for (const colConfig of configCollections) {
|
|
825
|
+
if (colConfig.patterns.some((p) => matchGlob(p, desc.filePath))) {
|
|
826
|
+
configCollection = colConfig.name;
|
|
827
|
+
break;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
let configInternal = false;
|
|
831
|
+
if (internalPatterns.length > 0) {
|
|
832
|
+
configInternal = internalPatterns.some(
|
|
833
|
+
(p) => matchGlob(p, desc.filePath) || matchGlob(p, desc.displayName)
|
|
834
|
+
);
|
|
835
|
+
}
|
|
836
|
+
const resolvedCollection = tsdocCollection ?? scopeFileCollection ?? configCollection;
|
|
837
|
+
if (resolvedCollection !== void 0) {
|
|
838
|
+
desc.collection = resolvedCollection;
|
|
839
|
+
}
|
|
840
|
+
desc.internal = tsdocInternal || configInternal;
|
|
841
|
+
}
|
|
734
842
|
return {
|
|
735
843
|
version: "0.1",
|
|
736
844
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
737
845
|
components: allComponents,
|
|
738
|
-
tree
|
|
846
|
+
tree,
|
|
847
|
+
collections: configCollections
|
|
739
848
|
};
|
|
740
849
|
}
|
|
741
850
|
var SCOPE_EXTENSIONS = [".scope.tsx", ".scope.ts", ".scope.jsx", ".scope.js"];
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/analysis.ts","../src/parser.ts"],"names":["Node","relative","join","Project","existsSync"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Phase 6 analysis functions for @agent-scope/manifest.\n *\n * This module is responsible for:\n * 1. Complexity classification (`complexityClass`)\n * 2. Required context detection (`requiredContexts`)\n * 3. Hook detection (`detectedHooks`)\n * 4. Side-effect tracking (`sideEffects`)\n *\n * All functions accept ts-morph `Node` / `SourceFile` / `Project` values and\n * return plain data — no mutations to the AST.\n */\n\nimport { Node, type Project, type SourceFile } from \"ts-morph\";\nimport type { ComplexityClass, SideEffects } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Collect all CallExpression nodes beneath a node (inclusive). */\nfunction collectCallExpressions(root: Node): Node[] {\n const results: Node[] = [];\n root.forEachDescendant((n) => {\n if (Node.isCallExpression(n)) {\n results.push(n);\n }\n });\n return results;\n}\n\n/** Return the callee string for a CallExpression node (e.g. \"window.addEventListener\"). */\nfunction calleeText(callExpr: Node): string {\n if (!Node.isCallExpression(callExpr)) return \"\";\n return callExpr.getExpression().getText().trim();\n}\n\n// ---------------------------------------------------------------------------\n// 1. Complexity classification\n// ---------------------------------------------------------------------------\n\n/**\n * CSS property names / values that force `complex` classification.\n * Any inline-style key matching this set triggers complexity.\n */\nconst COMPLEX_STYLE_KEYS = new Set([\n \"position\",\n \"gridTemplate\",\n \"gridTemplateColumns\",\n \"gridTemplateRows\",\n \"gridArea\",\n \"gridColumn\",\n \"gridRow\",\n \"grid\",\n \"animation\",\n \"animationName\",\n \"animationDuration\",\n \"transition\",\n \"transform\",\n \"transformOrigin\",\n \"clip\",\n \"clipPath\",\n \"willChange\",\n \"contain\",\n]);\n\n/**\n * Inline-style *value* fragments that imply complex layout even when the key\n * is safe (e.g. `position: \"absolute\"`).\n */\nconst COMPLEX_POSITION_VALUES = new Set([\"absolute\", \"fixed\", \"sticky\"]);\n\n/**\n * CSS properties that begin with these prefixes are complex\n * (e.g. \"gridTemplateAreas\").\n */\nconst COMPLEX_KEY_PREFIXES = [\"grid\", \"animation\", \"transition\"];\n\nfunction isComplexStyleKey(key: string): boolean {\n if (COMPLEX_STYLE_KEYS.has(key)) return true;\n return COMPLEX_KEY_PREFIXES.some((p) => key.startsWith(p));\n}\n\n/**\n * Scan JSX attribute `style={{ ... }}` inline-object expressions for complex\n * CSS properties. Returns true if any complex property is detected.\n */\nfunction hasCssComplexity(root: Node): boolean {\n let complex = false;\n\n root.forEachDescendant((n) => {\n if (complex) return;\n\n // --- Inline style object: style={{ position: \"absolute\", ... }} ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"style\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // style={{ ... }} → JsxExpression wrapping an ObjectLiteralExpression\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n if (!inner || !Node.isObjectLiteralExpression(inner)) return;\n\n for (const prop of inner.getProperties()) {\n if (complex) break;\n if (!Node.isPropertyAssignment(prop) && !Node.isShorthandPropertyAssignment(prop)) {\n continue;\n }\n\n const keyText = prop.getNameNode().getText();\n\n if (isComplexStyleKey(keyText)) {\n complex = true;\n break;\n }\n\n // Check value for position: \"absolute\" | \"fixed\" | \"sticky\"\n if (keyText === \"position\" && Node.isPropertyAssignment(prop)) {\n const val = prop.getInitializer();\n if (val) {\n const raw = val.getText().replace(/['\"]/g, \"\").trim().toLowerCase();\n if (COMPLEX_POSITION_VALUES.has(raw)) {\n complex = true;\n break;\n }\n }\n }\n }\n }\n return;\n }\n\n // --- Styled-components / css template literals ---\n // These are too opaque to analyze reliably; treat as complex\n if (Node.isTaggedTemplateExpression(n)) {\n const tag = n.getTag().getText();\n // styled.div`...`, styled(Component)`...`, css`...`\n if (tag.startsWith(\"styled\") || tag === \"css\" || tag === \"keyframes\") {\n complex = true;\n }\n return;\n }\n\n // --- className with a non-trivial expression → can't analyze, default complex ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"className\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // className=\"literal\" is fine; className={expr} is opaque\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n // Allow simple string concatenation / template literals - skip\n // Identifiers / call expressions pointing to CSS modules → complex\n if (\n inner &&\n (Node.isIdentifier(inner) ||\n Node.isCallExpression(inner) ||\n Node.isPropertyAccessExpression(inner))\n ) {\n complex = true;\n }\n }\n }\n });\n\n return complex;\n}\n\n/**\n * Classify a component body as `\"simple\"` or `\"complex\"`.\n *\n * Rule: any use of complex CSS properties (grid, absolute/fixed/sticky\n * positioning, animations, transforms, transitions) OR styled-components\n * OR opaque className references → `\"complex\"`.\n *\n * Default is `\"simple\"` when nothing complex is detected.\n * Callers should pass `\"complex\"` as the safe fallback for class components\n * or other patterns where analysis is not possible.\n */\nexport function analyzeComplexity(bodyNode: Node): ComplexityClass {\n return hasCssComplexity(bodyNode) ? \"complex\" : \"simple\";\n}\n\n// ---------------------------------------------------------------------------\n// 2. Hook detection\n// ---------------------------------------------------------------------------\n\nconst HOOK_REGEX = /^use[A-Z]/;\n\n/**\n * Collect all hook calls within a node.\n * A \"hook\" is any call expression whose callee matches /^use[A-Z]/.\n *\n * Returns a de-duplicated, sorted array of hook names.\n */\nexport function detectHooks(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n // Only the base name — drop member access (e.g. React.useState → useState)\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base)) {\n names.add(base);\n }\n });\n\n return Array.from(names).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 3. Required context detection\n// ---------------------------------------------------------------------------\n\n/**\n * Map from callee text → context variable name patterns.\n * We look for `useContext(SomeCtx)` patterns.\n */\nfunction extractDirectContextNames(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (base !== \"useContext\") return;\n\n const args = (Node.isCallExpression(callExpr) ? callExpr : null)?.getArguments() ?? [];\n const firstArg = args[0];\n if (!firstArg) return;\n\n // useContext(ThemeCtx) → \"ThemeCtx\"\n const argText = firstArg.getText().trim();\n if (argText) {\n names.add(argText);\n }\n });\n\n return Array.from(names);\n}\n\n/**\n * Given a custom hook name imported from a specifier, resolve its source file\n * and extract any `useContext(...)` calls it makes.\n *\n * Returns context variable names, e.g. [\"ThemeCtx\", \"AuthCtx\"].\n */\nfunction resolveHookContexts(\n hookName: string,\n importingFile: SourceFile,\n importSpecifier: string,\n project: Project,\n): string[] {\n // Attempt to resolve via ts-morph project\n const allFiles = project.getSourceFiles();\n const importingDir = importingFile.getDirectoryPath();\n\n // Build candidate paths for the specifier\n const specParts = importSpecifier.replace(/^\\.\\.?\\//, \"\");\n const candidates = allFiles.filter((sf) => {\n const fp = sf.getFilePath();\n // Must be relative to the same directory tree\n if (!fp.startsWith(importingDir.split(\"/src/\")[0] ?? importingDir)) return false;\n const basename = fp.split(\"/\").pop() ?? \"\";\n const specBase = specParts.split(\"/\").pop() ?? specParts;\n return (\n basename === `${specBase}.ts` ||\n basename === `${specBase}.tsx` ||\n basename === `${specBase}.js` ||\n basename === `${specBase}.jsx` ||\n fp.endsWith(`${specParts}.ts`) ||\n fp.endsWith(`${specParts}.tsx`) ||\n fp.endsWith(`${importSpecifier}.ts`) ||\n fp.endsWith(`${importSpecifier}.tsx`)\n );\n });\n\n for (const candidate of candidates) {\n // Find the hook function in this file\n const hookFunctions = [\n ...candidate.getFunctions().filter((f) => f.getName() === hookName),\n ...candidate.getVariableDeclarations().filter((v) => v.getName() === hookName),\n ];\n\n for (const fn of hookFunctions) {\n const ctxNames = extractDirectContextNames(fn);\n if (ctxNames.length > 0) return ctxNames;\n }\n\n // Also try arrow functions assigned to const hookName = () => ...\n // (already covered by getVariableDeclarations above)\n }\n\n return [];\n}\n\n/**\n * Detect all React context identifiers required by a component.\n *\n * Algorithm:\n * 1. Scan the component body for direct `useContext(X)` calls.\n * 2. Find all `import { useXxx } from './...'` statements.\n * 3. For each imported custom hook (matching /^use[A-Z]/), resolve its\n * source file and scan it for `useContext()` calls.\n * 4. Merge and de-duplicate.\n *\n * Returns a sorted array of context variable names.\n */\nexport function detectRequiredContexts(\n bodyNode: Node,\n sourceFile: SourceFile,\n project: Project,\n): string[] {\n const contextNames = new Set<string>();\n\n // Step 1: direct useContext() in component body\n for (const name of extractDirectContextNames(bodyNode)) {\n contextNames.add(name);\n }\n\n // Step 2: find imported hooks used in this component body\n const hookedCalls = new Set<string>();\n collectCallExpressions(bodyNode).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base) && base !== \"useContext\") {\n hookedCalls.add(base);\n }\n });\n\n if (hookedCalls.size === 0) {\n return Array.from(contextNames).sort();\n }\n\n // Step 3: resolve imports for those hooks\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n // Only follow relative imports (local files)\n if (!specifier.startsWith(\".\")) continue;\n\n const namedImports = importDecl.getNamedImports();\n for (const ni of namedImports) {\n const hookName = ni.getName();\n if (!hookedCalls.has(hookName)) continue;\n\n // Resolve this hook's contexts\n const resolved = resolveHookContexts(hookName, sourceFile, specifier, project);\n for (const ctx of resolved) {\n contextNames.add(ctx);\n }\n }\n }\n\n return Array.from(contextNames).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 4. Side-effect detection\n// ---------------------------------------------------------------------------\n\n/** Callee patterns for data fetching. */\nconst FETCH_PATTERNS = [\n /^fetch$/,\n /^axios(\\.[a-zA-Z]+)?$/,\n /^useQuery$/,\n /^useMutation$/,\n /^useSWR$/,\n /^useInfiniteQuery$/,\n /^request$/,\n];\n\n/** Callee patterns for timers. */\nconst TIMER_PATTERNS = [\n /^setTimeout$/,\n /^setInterval$/,\n /^requestAnimationFrame$/,\n /^clearTimeout$/,\n /^clearInterval$/,\n /^cancelAnimationFrame$/,\n];\n\n/** Callee patterns for subscriptions (non-global). */\nconst SUBSCRIPTION_PATTERNS = [\n /\\.subscribe$/,\n /\\.onSnapshot$/,\n /\\.on$/,\n /\\.listen$/,\n /\\.addListener$/,\n];\n\n/** Window/document addEventListener patterns. */\nconst GLOBAL_LISTENER_PATTERNS = [\n /^window\\.addEventListener$/,\n /^document\\.addEventListener$/,\n /^window\\.removeEventListener$/,\n /^document\\.removeEventListener$/,\n];\n\n/** Naked addEventListener — could be element or global, treat conservatively. */\nconst BARE_ADD_EVENT_LISTENER = /^addEventListener$/;\n\nfunction matchesAny(text: string, patterns: RegExp[]): boolean {\n return patterns.some((p) => p.test(text));\n}\n\n/**\n * Detect side effects within a component body.\n *\n * Scans all CallExpression nodes recursively, including those inside\n * useEffect / useCallback / event handlers.\n */\nexport function detectSideEffects(root: Node): SideEffects {\n const fetches = new Set<string>();\n let timers = false;\n const subscriptions = new Set<string>();\n let globalListeners = false;\n\n for (const callExpr of collectCallExpressions(root)) {\n const callee = calleeText(callExpr);\n\n if (matchesAny(callee, FETCH_PATTERNS)) {\n const name = callee.split(\".\")[0] ?? callee;\n fetches.add(name);\n continue;\n }\n\n if (matchesAny(callee, TIMER_PATTERNS)) {\n timers = true;\n continue;\n }\n\n if (matchesAny(callee, GLOBAL_LISTENER_PATTERNS)) {\n globalListeners = true;\n continue;\n }\n\n if (matchesAny(callee, SUBSCRIPTION_PATTERNS)) {\n // Extract the subscription method name (last segment)\n const parts = callee.split(\".\");\n const method = parts[parts.length - 1] ?? callee;\n subscriptions.add(method);\n continue;\n }\n\n // Bare addEventListener that's not clearly on window/document\n // Check if parent is a member access on window/document\n if (BARE_ADD_EVENT_LISTENER.test(callee)) {\n globalListeners = true;\n }\n }\n\n // Also scan for `window.` / `document.` property accesses that indicate event listener patterns\n root.forEachDescendant((n) => {\n if (Node.isPropertyAccessExpression(n)) {\n const text = n.getText();\n if (\n (text.startsWith(\"window.\") || text.startsWith(\"document.\")) &&\n (text.endsWith(\"addEventListener\") || text.endsWith(\"removeEventListener\"))\n ) {\n globalListeners = true;\n }\n }\n });\n\n return {\n fetches: Array.from(fetches).sort(),\n timers,\n subscriptions: Array.from(subscriptions).sort(),\n globalListeners,\n };\n}\n\n// ---------------------------------------------------------------------------\n// 5. Complexity propagation through composition tree\n// ---------------------------------------------------------------------------\n\n/**\n * Propagate `complexityClass` upward through the composition tree.\n *\n * A component is `simple` only if it AND every descendant in its `composes`\n * tree are also `simple`. If any child anywhere in the subtree is `complex`,\n * all ancestors must also be marked `complex`.\n *\n * Algorithm: bottom-up BFS from every component that is already `complex`.\n * For each complex component, follow the `composedBy` chain upward and mark\n * each ancestor as `complex`. A visited set prevents infinite loops on\n * hypothetical cycles.\n *\n * **Must be called after:**\n * 1. All components have received their initial `complexityClass` from `analyzeComplexity`.\n * 2. The `composedBy` inverse relationships have been populated.\n *\n * Mutates `components` in place — no return value needed.\n */\nexport function propagateComplexity(\n components: Record<string, { complexityClass: ComplexityClass; composedBy: string[] }>,\n): void {\n // Seed the queue with all currently-complex components.\n const queue: string[] = [];\n for (const [name, desc] of Object.entries(components)) {\n if (desc.complexityClass === \"complex\") {\n queue.push(name);\n }\n }\n\n // BFS upward — visited tracks names we have already enqueued to avoid\n // re-processing (handles cycles and diamond dependencies).\n const visited = new Set<string>(queue);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const desc = components[current];\n if (!desc) continue;\n\n for (const parentName of desc.composedBy) {\n const parent = components[parentName];\n if (!parent) continue;\n\n // Mark the parent as complex regardless of its prior classification.\n parent.complexityClass = \"complex\";\n\n // Only enqueue if we haven't visited it yet (avoids cycles / re-work).\n if (!visited.has(parentName)) {\n visited.add(parentName);\n queue.push(parentName);\n }\n }\n }\n}\n","import { existsSync } from \"node:fs\";\n/**\n * Core AST parser for @agent-scope/manifest.\n *\n * Uses ts-morph to traverse TypeScript/TSX source files and extract:\n * - React component declarations (function, arrow, class)\n * - Props interfaces / type aliases with full type resolution\n * - Union type expansion to literal values\n * - React.memo / React.forwardRef / HOC wrapper detection\n * - JSX composition tree (which components render which)\n * - Complexity classification (complexityClass)\n * - Required context detection (requiredContexts)\n * - Hook detection (detectedHooks)\n * - Side-effect tracking (sideEffects)\n */\n\nimport { join, relative } from \"node:path\";\nimport {\n type ClassDeclaration,\n type ExportAssignment,\n type FunctionDeclaration,\n type Identifier,\n Node,\n Project,\n type SourceFile,\n type Type,\n type VariableDeclaration,\n} from \"ts-morph\";\nimport {\n analyzeComplexity,\n detectHooks,\n detectRequiredContexts,\n detectSideEffects,\n propagateComplexity,\n} from \"./analysis.js\";\nimport type {\n ComponentDescriptor,\n ExportType,\n Manifest,\n ManifestConfig,\n PropDescriptor,\n PropKind,\n ScopeFileMeta,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isReactNode(typeName: string): boolean {\n return [\n \"ReactNode\",\n \"ReactElement\",\n \"JSX.Element\",\n \"React.ReactNode\",\n \"React.ReactElement\",\n ].includes(typeName);\n}\n\nfunction resolvePropKind(type: Type): PropKind {\n if (type.isString() || type.isStringLiteral()) return \"string\";\n if (type.isNumber() || type.isNumberLiteral()) return \"number\";\n if (type.isBoolean() || type.isBooleanLiteral()) return \"boolean\";\n if (type.isNull()) return \"null\";\n if (type.isUndefined()) return \"undefined\";\n if (type.isNever()) return \"never\";\n if (type.isAny()) return \"any\";\n if (type.isUnknown()) return \"unknown\";\n if (type.isArray()) return \"array\";\n if (type.isTuple()) return \"array\";\n\n const typeText = type.getText();\n if (isReactNode(typeText)) return \"node\";\n if (type.isUnion()) return \"union\";\n if (typeText.includes(\"=>\") || typeText.startsWith(\"(\")) return \"function\";\n if (type.isObject()) return \"object\";\n return \"other\";\n}\n\n/**\n * For a union type, attempt to extract string/number literal member values.\n */\nfunction expandUnionValues(type: Type): string[] | undefined {\n if (!type.isUnion()) return undefined;\n const values: string[] = [];\n for (const member of type.getUnionTypes()) {\n if (member.isStringLiteral()) {\n values.push(member.getLiteralValue() as string);\n } else if (member.isNumberLiteral()) {\n values.push(String(member.getLiteralValue()));\n } else if (member.isBooleanLiteral()) {\n // In ts-morph v25, getLiteralValue() may return undefined for bool literals\n // getText() reliably returns \"true\" or \"false\"\n const boolText = member.getText();\n if (boolText === \"true\" || boolText === \"false\") {\n values.push(boolText);\n }\n }\n // Skip non-literal union members (e.g. string | null | undefined)\n }\n return values.length > 0 ? values : undefined;\n}\n\n/**\n * Build a PropDescriptor from a ts-morph Type + optional default value source.\n */\nfunction buildPropDescriptor(type: Type, required: boolean, defaultValue?: string): PropDescriptor {\n const kind = resolvePropKind(type);\n const desc: PropDescriptor = {\n type: kind,\n required,\n rawType: type.getText().replace(/import\\(\"[^\"]*\"\\)\\./g, \"\"),\n };\n if (kind === \"union\") {\n const expanded = expandUnionValues(type);\n if (expanded) desc.values = expanded;\n }\n if (defaultValue !== undefined) {\n desc.default = defaultValue;\n // A prop with a default is effectively optional at the call site\n desc.required = false;\n }\n return desc;\n}\n\n// ---------------------------------------------------------------------------\n// Props extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract props from a TypeScript interface or type alias node.\n * Returns Record<propName, PropDescriptor>.\n */\nfunction extractPropsFromType(\n typeName: string,\n sourceFile: SourceFile,\n defaultValues: Record<string, string> = {},\n): Record<string, PropDescriptor> {\n const props: Record<string, PropDescriptor> = {};\n\n // Try interface first\n const iface = sourceFile.getInterface(typeName);\n if (iface) {\n for (const prop of iface.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue; // skip index signatures\n const type = prop.getType();\n const required = !prop.hasQuestionToken();\n props[name] = buildPropDescriptor(type, required, defaultValues[name]);\n }\n return props;\n }\n\n // Try type alias\n const typeAlias = sourceFile.getTypeAlias(typeName);\n if (typeAlias) {\n const aliasType = typeAlias.getType();\n if (aliasType.isObject()) {\n for (const prop of aliasType.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue;\n const decls = prop.getDeclarations();\n const required =\n decls.length === 0 ||\n !prop.getDeclarations().some((d) => Node.isPropertySignature(d) && d.hasQuestionToken());\n const valType = prop.getTypeAtLocation(sourceFile);\n props[name] = buildPropDescriptor(valType, required, defaultValues[name]);\n }\n }\n return props;\n }\n\n return props;\n}\n\n/**\n * Try to infer the props type name from a function's parameter destructuring.\n * E.g. `function Foo({ bar }: FooProps)` → \"FooProps\"\n */\nfunction inferPropsTypeName(params: { getTypeNode(): Node | undefined }[]): string | undefined {\n if (params.length === 0) return undefined;\n const firstParam = params[0];\n if (!firstParam) return undefined;\n const typeNode = firstParam.getTypeNode?.();\n if (!typeNode) return undefined;\n return typeNode.getText().trim();\n}\n\n/**\n * Extract default values from destructured parameters.\n * E.g. `function Foo({ variant = 'primary', size = 'md' }: FooProps)` → { variant: 'primary', size: 'md' }\n */\nfunction extractDefaultsFromDestructuring(\n params: ReturnType<FunctionDeclaration[\"getParameters\"]>,\n): Record<string, string> {\n const defaults: Record<string, string> = {};\n if (params.length === 0) return defaults;\n const firstParam = params[0];\n if (!firstParam) return defaults;\n\n const nameNode = firstParam.getNameNode();\n if (!Node.isObjectBindingPattern(nameNode)) return defaults;\n\n for (const element of nameNode.getElements()) {\n const initializer = element.getInitializer();\n if (initializer) {\n const propName = element.getPropertyNameNode()?.getText() ?? element.getName();\n defaults[propName] = initializer.getText();\n }\n }\n return defaults;\n}\n\n// ---------------------------------------------------------------------------\n// JSX composition extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Collect all JSX element tag names used inside a node.\n * Returns only PascalCase names (component references, not host elements).\n */\nfunction collectJsxCompositions(node: Node): string[] {\n const names = new Set<string>();\n\n function visit(n: Node): void {\n if (Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n)) {\n const tagNameNode = n.getTagNameNode();\n const tagName = tagNameNode.getText();\n // Only capture PascalCase = React components (not div, span, etc.)\n if (/^[A-Z]/.test(tagName)) {\n // Strip member access – e.g. React.Fragment → skip; Context.Provider → skip\n const base = tagName.split(\".\")[0] ?? tagName;\n if (base && /^[A-Z]/.test(base) && ![\"React\", \"Fragment\"].includes(base)) {\n names.add(base);\n }\n }\n }\n n.forEachChild(visit);\n }\n\n visit(node);\n return Array.from(names);\n}\n\n// ---------------------------------------------------------------------------\n// HOC / wrapper detection\n// ---------------------------------------------------------------------------\n\ninterface WrapperInfo {\n memoized: boolean;\n forwardedRef: boolean;\n hocWrappers: string[];\n}\n\n/**\n * Detect React.memo, React.forwardRef, and arbitrary HOC wrappers on a call expression.\n */\nfunction detectWrappers(node: Node): WrapperInfo {\n let memoized = false;\n let forwardedRef = false;\n const hocWrappers: string[] = [];\n\n function visitCall(n: Node): void {\n if (!Node.isCallExpression(n)) return;\n const expr = n.getExpression();\n const name = expr.getText();\n\n if (name === \"React.memo\" || name === \"memo\") {\n memoized = true;\n // Recurse into the inner arg (it might also be forwardRef)\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else if (name === \"React.forwardRef\" || name === \"forwardRef\") {\n forwardedRef = true;\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else {\n // Generic HOC: something(Component)\n const args = n.getArguments();\n if (args.length > 0) {\n const firstArg = args[0];\n if (firstArg && (Node.isIdentifier(firstArg) || Node.isCallExpression(firstArg))) {\n // Treat outer call name as an HOC wrapper\n const calleeName = name.split(\".\").pop() ?? name;\n if (/^[a-z]/.test(calleeName)) {\n hocWrappers.push(calleeName);\n }\n if (Node.isCallExpression(firstArg)) {\n visitCall(firstArg);\n }\n }\n }\n }\n }\n\n visitCall(node);\n return { memoized, forwardedRef, hocWrappers };\n}\n\n// ---------------------------------------------------------------------------\n// Component name resolution for wrapped components\n// ---------------------------------------------------------------------------\n\n/**\n * Given a call expression like `React.memo(function Foo() {...})`, extract the inner name.\n */\nfunction extractNameFromWrappedCall(node: Node): string | undefined {\n if (!Node.isCallExpression(node)) return undefined;\n const args = node.getArguments();\n if (args.length === 0) return undefined;\n\n const firstArg = args[0];\n if (!firstArg) return undefined;\n\n // memo(function Foo() {...})\n if (Node.isFunctionExpression(firstArg)) {\n return firstArg.getName() ?? undefined;\n }\n // memo(Foo) where Foo is an identifier\n if (Node.isIdentifier(firstArg)) {\n return firstArg.getText();\n }\n // memo(forwardRef(function Foo() {...}))\n if (Node.isCallExpression(firstArg)) {\n return extractNameFromWrappedCall(firstArg);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Returns-JSX detection\n// ---------------------------------------------------------------------------\n\nfunction nodeReturnsJsx(node: Node): boolean {\n let found = false;\n function visit(n: Node): void {\n if (found) return;\n if (Node.isJsxElement(n) || Node.isJsxFragment(n) || Node.isJsxSelfClosingElement(n)) {\n found = true;\n return;\n }\n n.forEachChild(visit);\n }\n visit(node);\n return found;\n}\n\n// ---------------------------------------------------------------------------\n// Per-file component extraction\n// ---------------------------------------------------------------------------\n\ninterface RawComponent {\n name: string;\n descriptor: ComponentDescriptor;\n}\n\nfunction processSourceFile(\n sourceFile: SourceFile,\n rootDir: string,\n project: Project,\n): RawComponent[] {\n const results: RawComponent[] = [];\n const filePath = relative(rootDir, sourceFile.getFilePath());\n\n // Collect default export assignment target name (e.g. `export default Foo`)\n // Also handle wrapped defaults: `export default React.memo(Foo)` or `export default React.forwardRef(Foo)`\n let defaultExportName: string | undefined;\n const defaultExportWrappers = new Map<string, WrapperInfo>();\n sourceFile.forEachChild((node) => {\n if (Node.isExportAssignment(node)) {\n const expr = (node as ExportAssignment).getExpression();\n if (Node.isIdentifier(expr)) {\n defaultExportName = (expr as Identifier).getText();\n } else if (Node.isCallExpression(expr)) {\n // e.g. `export default React.memo(Sidebar)` or `export default React.forwardRef(Btn)`\n const innerName = extractNameFromWrappedCall(expr);\n if (innerName) {\n defaultExportName = innerName;\n defaultExportWrappers.set(innerName, detectWrappers(expr));\n }\n }\n }\n });\n\n // Named exports map: variable name → export type\n const namedExports = new Set<string>();\n for (const exportDecl of sourceFile.getExportSymbols()) {\n namedExports.add(exportDecl.getName());\n }\n\n // -------------------------------------------------------------------------\n // 1. Function declarations\n // -------------------------------------------------------------------------\n for (const fn of sourceFile.getFunctions()) {\n const name = fn.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n if (!nodeReturnsJsx(fn)) continue;\n\n const params = fn.getParameters();\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(fn);\n const start = fn.getStartLineNumber();\n const end = fn.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (fn.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (fn.isExported() || namedExports.has(name)) exportType = \"named\";\n\n const fnWrappers = defaultExportWrappers.get(name) ?? {\n memoized: false,\n forwardedRef: false,\n hocWrappers: [],\n };\n\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: fnWrappers.forwardedRef,\n hocWrappers: fnWrappers.hocWrappers,\n memoized: fnWrappers.memoized,\n loc: { start, end },\n complexityClass: analyzeComplexity(fn),\n detectedHooks: detectHooks(fn),\n requiredContexts: detectRequiredContexts(fn, sourceFile, project),\n sideEffects: detectSideEffects(fn),\n scopeFile: null,\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // 2. Variable declarations (arrow functions, React.memo, React.forwardRef)\n // -------------------------------------------------------------------------\n for (const varStmt of sourceFile.getVariableStatements()) {\n const isExported = varStmt.isExported();\n for (const varDecl of varStmt.getDeclarations()) {\n const varName = (varDecl as VariableDeclaration).getName();\n if (!/^[A-Z]/.test(varName)) continue;\n\n const initializer = (varDecl as VariableDeclaration).getInitializer();\n if (!initializer) continue;\n\n // Detect wrappers on the whole expression\n const wrappers = detectWrappers(initializer);\n let innerName: string | undefined;\n let bodyNode: Node = initializer;\n\n if (Node.isCallExpression(initializer)) {\n innerName = extractNameFromWrappedCall(initializer);\n // Drill into the innermost function for props / JSX\n const args = initializer.getArguments();\n const firstArg = args[0];\n if (firstArg) {\n if (Node.isArrowFunction(firstArg) || Node.isFunctionExpression(firstArg)) {\n bodyNode = firstArg;\n } else if (Node.isCallExpression(firstArg)) {\n // e.g. memo(forwardRef(fn))\n const innerArgs = firstArg.getArguments();\n const innerFirst = innerArgs[0];\n if (\n innerFirst &&\n (Node.isArrowFunction(innerFirst) || Node.isFunctionExpression(innerFirst))\n ) {\n bodyNode = innerFirst;\n }\n }\n }\n }\n\n // Must return JSX somewhere in the body\n if (!nodeReturnsJsx(bodyNode)) continue;\n\n // For named inner functions we use innerName; fall back to varName\n const componentName = innerName ?? varName;\n\n let params: ReturnType<FunctionDeclaration[\"getParameters\"]> = [];\n if (Node.isArrowFunction(bodyNode) || Node.isFunctionExpression(bodyNode)) {\n params = bodyNode.getParameters();\n }\n\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(bodyNode);\n const startLine = (varDecl as VariableDeclaration).getStartLineNumber();\n const endLine = (varDecl as VariableDeclaration).getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (defaultExportName === varName || defaultExportName === componentName) {\n exportType = \"default\";\n } else if (isExported || namedExports.has(varName)) {\n exportType = \"named\";\n }\n\n results.push({\n name: componentName === varName ? componentName : varName,\n descriptor: {\n filePath,\n exportType,\n displayName: componentName,\n props,\n composes,\n composedBy: [],\n forwardedRef: wrappers.forwardedRef,\n hocWrappers: wrappers.hocWrappers,\n memoized: wrappers.memoized,\n loc: { start: startLine, end: endLine },\n complexityClass: analyzeComplexity(bodyNode),\n detectedHooks: detectHooks(bodyNode),\n requiredContexts: detectRequiredContexts(bodyNode, sourceFile, project),\n sideEffects: detectSideEffects(bodyNode),\n scopeFile: null,\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // 3. Class components\n // -------------------------------------------------------------------------\n for (const cls of sourceFile.getClasses()) {\n const name = cls.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n\n // Must extend React.Component or React.PureComponent\n const baseClass = (cls as ClassDeclaration).getBaseClass()?.getName();\n if (!baseClass && !(cls as ClassDeclaration).getExtends()) continue;\n const extendsText = (cls as ClassDeclaration).getExtends()?.getText() ?? \"\";\n if (!extendsText.includes(\"Component\") && !extendsText.includes(\"PureComponent\")) {\n continue;\n }\n\n // Render method must return JSX\n const renderMethod = cls.getMethod(\"render\");\n if (!renderMethod || !nodeReturnsJsx(renderMethod)) continue;\n\n // Extract first type argument as props type\n const extendsNode = (cls as ClassDeclaration).getExtends();\n let propsTypeName: string | undefined;\n if (extendsNode) {\n const typeArgs = extendsNode.getTypeArguments();\n if (typeArgs[0]) {\n propsTypeName = typeArgs[0].getText().trim();\n }\n }\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile) : {};\n\n const composes = collectJsxCompositions(renderMethod);\n const start = cls.getStartLineNumber();\n const end = cls.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (cls.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (cls.isExported() || namedExports.has(name)) exportType = \"named\";\n\n // Class components: default to \"complex\" (they often use lifecycle methods / state)\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: false,\n hocWrappers: [],\n memoized: false,\n loc: { start, end },\n complexityClass: \"complex\",\n detectedHooks: [],\n requiredContexts: [],\n sideEffects: detectSideEffects(cls),\n scopeFile: null,\n },\n });\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a component manifest by parsing all matching TypeScript/TSX files.\n */\nexport function generateManifest(config: ManifestConfig): Manifest {\n const {\n rootDir,\n include = [\"src/**/*.tsx\", \"src/**/*.ts\"],\n exclude = [\"**/node_modules/**\", \"**/*.test.*\", \"**/*.spec.*\", \"**/dist/**\", \"**/*.d.ts\"],\n tsConfigFilePath = join(rootDir, \"tsconfig.json\"),\n } = config;\n\n const project = new Project({\n tsConfigFilePath,\n skipAddingFilesFromTsConfig: true,\n });\n\n // Add source files via glob\n const includePatterns = include.map((g) => join(rootDir, g));\n project.addSourceFilesFromTsConfig(tsConfigFilePath);\n\n // If tsconfig doesn't cover the files, add them directly\n for (const pattern of includePatterns) {\n project.addSourceFilesAtPaths(pattern);\n }\n\n // Remove excluded files\n for (const sf of project.getSourceFiles()) {\n const fp = sf.getFilePath();\n const shouldExclude = exclude.some((ex) => {\n const pattern = ex.replace(/\\*\\*/g, \".*\").replace(/\\*/g, \"[^/]*\").replace(/\\./g, \"\\\\.\");\n return new RegExp(pattern).test(fp);\n });\n if (shouldExclude) {\n project.removeSourceFile(sf);\n }\n }\n\n // Also filter to only files within rootDir\n for (const sf of project.getSourceFiles()) {\n if (!sf.getFilePath().startsWith(rootDir)) {\n project.removeSourceFile(sf);\n }\n }\n\n // Collect all components\n const allComponents: Record<string, ComponentDescriptor> = {};\n\n for (const sf of project.getSourceFiles()) {\n const rawComponents = processSourceFile(sf, rootDir, project);\n for (const { name, descriptor } of rawComponents) {\n // If duplicate name, prefer the exported one\n if (allComponents[name] && descriptor.exportType === \"none\") continue;\n allComponents[name] = descriptor;\n }\n }\n\n // Build composition inverse: composedBy\n for (const [name, desc] of Object.entries(allComponents)) {\n for (const child of desc.composes) {\n if (allComponents[child]) {\n const childDesc = allComponents[child];\n if (childDesc && !childDesc.composedBy.includes(name)) {\n childDesc.composedBy.push(name);\n }\n }\n }\n }\n\n // Propagate complexityClass upward through the composition tree.\n // A component is only `simple` if it AND every descendant are simple.\n // This must run after composedBy is fully populated.\n propagateComplexity(allComponents);\n\n // Build tree\n const tree: Manifest[\"tree\"] = {};\n for (const [name, desc] of Object.entries(allComponents)) {\n // Only include children that exist in the manifest\n const children = desc.composes.filter((c) => c in allComponents);\n const parents = desc.composedBy.filter((p) => p in allComponents);\n tree[name] = { children, parents };\n }\n\n // Attach scope file metadata to each component (static presence check only)\n for (const desc of Object.values(allComponents)) {\n const scopeMeta = detectScopeFile(desc.filePath, config.rootDir);\n if (scopeMeta !== null) {\n desc.scopeFile = scopeMeta;\n }\n }\n\n return {\n version: \"0.1\",\n generatedAt: new Date().toISOString(),\n components: allComponents,\n tree,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Scope file detection (static — presence check only, no bundling)\n// ---------------------------------------------------------------------------\n\nconst SCOPE_EXTENSIONS = [\".scope.tsx\", \".scope.ts\", \".scope.jsx\", \".scope.js\"];\n\n/**\n * Check whether a scope file exists next to the component file.\n * Returns minimal ScopeFileMeta if found, null otherwise.\n *\n * scenarioNames and hasWrapper are left empty here — they are populated at\n * render time when loadScopeFile() actually bundles and evaluates the file.\n */\nfunction detectScopeFile(componentFilePath: string, rootDir: string): ScopeFileMeta | null {\n const absPath = componentFilePath.startsWith(\"/\")\n ? componentFilePath\n : join(rootDir, componentFilePath);\n\n const stem = absPath.replace(/\\.(tsx?|jsx?)$/, \"\");\n for (const ext of SCOPE_EXTENSIONS) {\n const candidate = `${stem}${ext}`;\n if (existsSync(candidate)) {\n return { filePath: candidate, scenarioNames: [], hasWrapper: false };\n }\n }\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/analysis.ts","../src/parser.ts"],"names":["Node","relative","join","Project","existsSync"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Phase 6 analysis functions for @agent-scope/manifest.\n *\n * This module is responsible for:\n * 1. Complexity classification (`complexityClass`)\n * 2. Required context detection (`requiredContexts`)\n * 3. Hook detection (`detectedHooks`)\n * 4. Side-effect tracking (`sideEffects`)\n *\n * All functions accept ts-morph `Node` / `SourceFile` / `Project` values and\n * return plain data — no mutations to the AST.\n */\n\nimport { Node, type Project, type SourceFile } from \"ts-morph\";\nimport type { ComplexityClass, SideEffects } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Collect all CallExpression nodes beneath a node (inclusive). */\nfunction collectCallExpressions(root: Node): Node[] {\n const results: Node[] = [];\n root.forEachDescendant((n) => {\n if (Node.isCallExpression(n)) {\n results.push(n);\n }\n });\n return results;\n}\n\n/** Return the callee string for a CallExpression node (e.g. \"window.addEventListener\"). */\nfunction calleeText(callExpr: Node): string {\n if (!Node.isCallExpression(callExpr)) return \"\";\n return callExpr.getExpression().getText().trim();\n}\n\n// ---------------------------------------------------------------------------\n// 1. Complexity classification\n// ---------------------------------------------------------------------------\n\n/**\n * CSS property names / values that force `complex` classification.\n * Any inline-style key matching this set triggers complexity.\n */\nconst COMPLEX_STYLE_KEYS = new Set([\n \"position\",\n \"gridTemplate\",\n \"gridTemplateColumns\",\n \"gridTemplateRows\",\n \"gridArea\",\n \"gridColumn\",\n \"gridRow\",\n \"grid\",\n \"animation\",\n \"animationName\",\n \"animationDuration\",\n \"transition\",\n \"transform\",\n \"transformOrigin\",\n \"clip\",\n \"clipPath\",\n \"willChange\",\n \"contain\",\n]);\n\n/**\n * Inline-style *value* fragments that imply complex layout even when the key\n * is safe (e.g. `position: \"absolute\"`).\n */\nconst COMPLEX_POSITION_VALUES = new Set([\"absolute\", \"fixed\", \"sticky\"]);\n\n/**\n * CSS properties that begin with these prefixes are complex\n * (e.g. \"gridTemplateAreas\").\n */\nconst COMPLEX_KEY_PREFIXES = [\"grid\", \"animation\", \"transition\"];\n\nfunction isComplexStyleKey(key: string): boolean {\n if (COMPLEX_STYLE_KEYS.has(key)) return true;\n return COMPLEX_KEY_PREFIXES.some((p) => key.startsWith(p));\n}\n\n/**\n * Scan JSX attribute `style={{ ... }}` inline-object expressions for complex\n * CSS properties. Returns true if any complex property is detected.\n */\nfunction hasCssComplexity(root: Node): boolean {\n let complex = false;\n\n root.forEachDescendant((n) => {\n if (complex) return;\n\n // --- Inline style object: style={{ position: \"absolute\", ... }} ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"style\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // style={{ ... }} → JsxExpression wrapping an ObjectLiteralExpression\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n if (!inner || !Node.isObjectLiteralExpression(inner)) return;\n\n for (const prop of inner.getProperties()) {\n if (complex) break;\n if (!Node.isPropertyAssignment(prop) && !Node.isShorthandPropertyAssignment(prop)) {\n continue;\n }\n\n const keyText = prop.getNameNode().getText();\n\n if (isComplexStyleKey(keyText)) {\n complex = true;\n break;\n }\n\n // Check value for position: \"absolute\" | \"fixed\" | \"sticky\"\n if (keyText === \"position\" && Node.isPropertyAssignment(prop)) {\n const val = prop.getInitializer();\n if (val) {\n const raw = val.getText().replace(/['\"]/g, \"\").trim().toLowerCase();\n if (COMPLEX_POSITION_VALUES.has(raw)) {\n complex = true;\n break;\n }\n }\n }\n }\n }\n return;\n }\n\n // --- Styled-components / css template literals ---\n // These are too opaque to analyze reliably; treat as complex\n if (Node.isTaggedTemplateExpression(n)) {\n const tag = n.getTag().getText();\n // styled.div`...`, styled(Component)`...`, css`...`\n if (tag.startsWith(\"styled\") || tag === \"css\" || tag === \"keyframes\") {\n complex = true;\n }\n return;\n }\n\n // --- className with a non-trivial expression → can't analyze, default complex ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"className\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // className=\"literal\" is fine; className={expr} is opaque\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n // Allow simple string concatenation / template literals - skip\n // Identifiers / call expressions pointing to CSS modules → complex\n if (\n inner &&\n (Node.isIdentifier(inner) ||\n Node.isCallExpression(inner) ||\n Node.isPropertyAccessExpression(inner))\n ) {\n complex = true;\n }\n }\n }\n });\n\n return complex;\n}\n\n/**\n * Classify a component body as `\"simple\"` or `\"complex\"`.\n *\n * Rule: any use of complex CSS properties (grid, absolute/fixed/sticky\n * positioning, animations, transforms, transitions) OR styled-components\n * OR opaque className references → `\"complex\"`.\n *\n * Default is `\"simple\"` when nothing complex is detected.\n * Callers should pass `\"complex\"` as the safe fallback for class components\n * or other patterns where analysis is not possible.\n */\nexport function analyzeComplexity(bodyNode: Node): ComplexityClass {\n return hasCssComplexity(bodyNode) ? \"complex\" : \"simple\";\n}\n\n// ---------------------------------------------------------------------------\n// 2. Hook detection\n// ---------------------------------------------------------------------------\n\nconst HOOK_REGEX = /^use[A-Z]/;\n\n/**\n * Collect all hook calls within a node.\n * A \"hook\" is any call expression whose callee matches /^use[A-Z]/.\n *\n * Returns a de-duplicated, sorted array of hook names.\n */\nexport function detectHooks(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n // Only the base name — drop member access (e.g. React.useState → useState)\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base)) {\n names.add(base);\n }\n });\n\n return Array.from(names).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 3. Required context detection\n// ---------------------------------------------------------------------------\n\n/**\n * Map from callee text → context variable name patterns.\n * We look for `useContext(SomeCtx)` patterns.\n */\nfunction extractDirectContextNames(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (base !== \"useContext\") return;\n\n const args = (Node.isCallExpression(callExpr) ? callExpr : null)?.getArguments() ?? [];\n const firstArg = args[0];\n if (!firstArg) return;\n\n // useContext(ThemeCtx) → \"ThemeCtx\"\n const argText = firstArg.getText().trim();\n if (argText) {\n names.add(argText);\n }\n });\n\n return Array.from(names);\n}\n\n/**\n * Given a custom hook name imported from a specifier, resolve its source file\n * and extract any `useContext(...)` calls it makes.\n *\n * Returns context variable names, e.g. [\"ThemeCtx\", \"AuthCtx\"].\n */\nfunction resolveHookContexts(\n hookName: string,\n importingFile: SourceFile,\n importSpecifier: string,\n project: Project,\n): string[] {\n // Attempt to resolve via ts-morph project\n const allFiles = project.getSourceFiles();\n const importingDir = importingFile.getDirectoryPath();\n\n // Build candidate paths for the specifier\n const specParts = importSpecifier.replace(/^\\.\\.?\\//, \"\");\n const candidates = allFiles.filter((sf) => {\n const fp = sf.getFilePath();\n // Must be relative to the same directory tree\n if (!fp.startsWith(importingDir.split(\"/src/\")[0] ?? importingDir)) return false;\n const basename = fp.split(\"/\").pop() ?? \"\";\n const specBase = specParts.split(\"/\").pop() ?? specParts;\n return (\n basename === `${specBase}.ts` ||\n basename === `${specBase}.tsx` ||\n basename === `${specBase}.js` ||\n basename === `${specBase}.jsx` ||\n fp.endsWith(`${specParts}.ts`) ||\n fp.endsWith(`${specParts}.tsx`) ||\n fp.endsWith(`${importSpecifier}.ts`) ||\n fp.endsWith(`${importSpecifier}.tsx`)\n );\n });\n\n for (const candidate of candidates) {\n // Find the hook function in this file\n const hookFunctions = [\n ...candidate.getFunctions().filter((f) => f.getName() === hookName),\n ...candidate.getVariableDeclarations().filter((v) => v.getName() === hookName),\n ];\n\n for (const fn of hookFunctions) {\n const ctxNames = extractDirectContextNames(fn);\n if (ctxNames.length > 0) return ctxNames;\n }\n\n // Also try arrow functions assigned to const hookName = () => ...\n // (already covered by getVariableDeclarations above)\n }\n\n return [];\n}\n\n/**\n * Detect all React context identifiers required by a component.\n *\n * Algorithm:\n * 1. Scan the component body for direct `useContext(X)` calls.\n * 2. Find all `import { useXxx } from './...'` statements.\n * 3. For each imported custom hook (matching /^use[A-Z]/), resolve its\n * source file and scan it for `useContext()` calls.\n * 4. Merge and de-duplicate.\n *\n * Returns a sorted array of context variable names.\n */\nexport function detectRequiredContexts(\n bodyNode: Node,\n sourceFile: SourceFile,\n project: Project,\n): string[] {\n const contextNames = new Set<string>();\n\n // Step 1: direct useContext() in component body\n for (const name of extractDirectContextNames(bodyNode)) {\n contextNames.add(name);\n }\n\n // Step 2: find imported hooks used in this component body\n const hookedCalls = new Set<string>();\n collectCallExpressions(bodyNode).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base) && base !== \"useContext\") {\n hookedCalls.add(base);\n }\n });\n\n if (hookedCalls.size === 0) {\n return Array.from(contextNames).sort();\n }\n\n // Step 3: resolve imports for those hooks\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n // Only follow relative imports (local files)\n if (!specifier.startsWith(\".\")) continue;\n\n const namedImports = importDecl.getNamedImports();\n for (const ni of namedImports) {\n const hookName = ni.getName();\n if (!hookedCalls.has(hookName)) continue;\n\n // Resolve this hook's contexts\n const resolved = resolveHookContexts(hookName, sourceFile, specifier, project);\n for (const ctx of resolved) {\n contextNames.add(ctx);\n }\n }\n }\n\n return Array.from(contextNames).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 4. Side-effect detection\n// ---------------------------------------------------------------------------\n\n/** Callee patterns for data fetching. */\nconst FETCH_PATTERNS = [\n /^fetch$/,\n /^axios(\\.[a-zA-Z]+)?$/,\n /^useQuery$/,\n /^useMutation$/,\n /^useSWR$/,\n /^useInfiniteQuery$/,\n /^request$/,\n];\n\n/** Callee patterns for timers. */\nconst TIMER_PATTERNS = [\n /^setTimeout$/,\n /^setInterval$/,\n /^requestAnimationFrame$/,\n /^clearTimeout$/,\n /^clearInterval$/,\n /^cancelAnimationFrame$/,\n];\n\n/** Callee patterns for subscriptions (non-global). */\nconst SUBSCRIPTION_PATTERNS = [\n /\\.subscribe$/,\n /\\.onSnapshot$/,\n /\\.on$/,\n /\\.listen$/,\n /\\.addListener$/,\n];\n\n/** Window/document addEventListener patterns. */\nconst GLOBAL_LISTENER_PATTERNS = [\n /^window\\.addEventListener$/,\n /^document\\.addEventListener$/,\n /^window\\.removeEventListener$/,\n /^document\\.removeEventListener$/,\n];\n\n/** Naked addEventListener — could be element or global, treat conservatively. */\nconst BARE_ADD_EVENT_LISTENER = /^addEventListener$/;\n\nfunction matchesAny(text: string, patterns: RegExp[]): boolean {\n return patterns.some((p) => p.test(text));\n}\n\n/**\n * Detect side effects within a component body.\n *\n * Scans all CallExpression nodes recursively, including those inside\n * useEffect / useCallback / event handlers.\n */\nexport function detectSideEffects(root: Node): SideEffects {\n const fetches = new Set<string>();\n let timers = false;\n const subscriptions = new Set<string>();\n let globalListeners = false;\n\n for (const callExpr of collectCallExpressions(root)) {\n const callee = calleeText(callExpr);\n\n if (matchesAny(callee, FETCH_PATTERNS)) {\n const name = callee.split(\".\")[0] ?? callee;\n fetches.add(name);\n continue;\n }\n\n if (matchesAny(callee, TIMER_PATTERNS)) {\n timers = true;\n continue;\n }\n\n if (matchesAny(callee, GLOBAL_LISTENER_PATTERNS)) {\n globalListeners = true;\n continue;\n }\n\n if (matchesAny(callee, SUBSCRIPTION_PATTERNS)) {\n // Extract the subscription method name (last segment)\n const parts = callee.split(\".\");\n const method = parts[parts.length - 1] ?? callee;\n subscriptions.add(method);\n continue;\n }\n\n // Bare addEventListener that's not clearly on window/document\n // Check if parent is a member access on window/document\n if (BARE_ADD_EVENT_LISTENER.test(callee)) {\n globalListeners = true;\n }\n }\n\n // Also scan for `window.` / `document.` property accesses that indicate event listener patterns\n root.forEachDescendant((n) => {\n if (Node.isPropertyAccessExpression(n)) {\n const text = n.getText();\n if (\n (text.startsWith(\"window.\") || text.startsWith(\"document.\")) &&\n (text.endsWith(\"addEventListener\") || text.endsWith(\"removeEventListener\"))\n ) {\n globalListeners = true;\n }\n }\n });\n\n return {\n fetches: Array.from(fetches).sort(),\n timers,\n subscriptions: Array.from(subscriptions).sort(),\n globalListeners,\n };\n}\n\n// ---------------------------------------------------------------------------\n// 5. Complexity propagation through composition tree\n// ---------------------------------------------------------------------------\n\n/**\n * Propagate `complexityClass` upward through the composition tree.\n *\n * A component is `simple` only if it AND every descendant in its `composes`\n * tree are also `simple`. If any child anywhere in the subtree is `complex`,\n * all ancestors must also be marked `complex`.\n *\n * Algorithm: bottom-up BFS from every component that is already `complex`.\n * For each complex component, follow the `composedBy` chain upward and mark\n * each ancestor as `complex`. A visited set prevents infinite loops on\n * hypothetical cycles.\n *\n * **Must be called after:**\n * 1. All components have received their initial `complexityClass` from `analyzeComplexity`.\n * 2. The `composedBy` inverse relationships have been populated.\n *\n * Mutates `components` in place — no return value needed.\n */\nexport function propagateComplexity(\n components: Record<string, { complexityClass: ComplexityClass; composedBy: string[] }>,\n): void {\n // Seed the queue with all currently-complex components.\n const queue: string[] = [];\n for (const [name, desc] of Object.entries(components)) {\n if (desc.complexityClass === \"complex\") {\n queue.push(name);\n }\n }\n\n // BFS upward — visited tracks names we have already enqueued to avoid\n // re-processing (handles cycles and diamond dependencies).\n const visited = new Set<string>(queue);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const desc = components[current];\n if (!desc) continue;\n\n for (const parentName of desc.composedBy) {\n const parent = components[parentName];\n if (!parent) continue;\n\n // Mark the parent as complex regardless of its prior classification.\n parent.complexityClass = \"complex\";\n\n // Only enqueue if we haven't visited it yet (avoids cycles / re-work).\n if (!visited.has(parentName)) {\n visited.add(parentName);\n queue.push(parentName);\n }\n }\n }\n}\n","import { existsSync } from \"node:fs\";\n/**\n * Core AST parser for @agent-scope/manifest.\n *\n * Uses ts-morph to traverse TypeScript/TSX source files and extract:\n * - React component declarations (function, arrow, class)\n * - Props interfaces / type aliases with full type resolution\n * - Union type expansion to literal values\n * - React.memo / React.forwardRef / HOC wrapper detection\n * - JSX composition tree (which components render which)\n * - Complexity classification (complexityClass)\n * - Required context detection (requiredContexts)\n * - Hook detection (detectedHooks)\n * - Side-effect tracking (sideEffects)\n * - Collection and internal classification (via TSDoc, .scope.ts, config patterns)\n */\n\nimport { join, relative } from \"node:path\";\nimport {\n type ClassDeclaration,\n type ExportAssignment,\n type FunctionDeclaration,\n type Identifier,\n Node,\n Project,\n type SourceFile,\n type Type,\n type VariableDeclaration,\n} from \"ts-morph\";\nimport {\n analyzeComplexity,\n detectHooks,\n detectRequiredContexts,\n detectSideEffects,\n propagateComplexity,\n} from \"./analysis.js\";\nimport type {\n CollectionConfig,\n ComponentDescriptor,\n ExportType,\n Manifest,\n ManifestConfig,\n PropDescriptor,\n PropKind,\n ScopeFileMeta,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isReactNode(typeName: string): boolean {\n return [\n \"ReactNode\",\n \"ReactElement\",\n \"JSX.Element\",\n \"React.ReactNode\",\n \"React.ReactElement\",\n ].includes(typeName);\n}\n\nfunction resolvePropKind(type: Type): PropKind {\n if (type.isString() || type.isStringLiteral()) return \"string\";\n if (type.isNumber() || type.isNumberLiteral()) return \"number\";\n if (type.isBoolean() || type.isBooleanLiteral()) return \"boolean\";\n if (type.isNull()) return \"null\";\n if (type.isUndefined()) return \"undefined\";\n if (type.isNever()) return \"never\";\n if (type.isAny()) return \"any\";\n if (type.isUnknown()) return \"unknown\";\n if (type.isArray()) return \"array\";\n if (type.isTuple()) return \"array\";\n\n const typeText = type.getText();\n if (isReactNode(typeText)) return \"node\";\n if (type.isUnion()) return \"union\";\n if (typeText.includes(\"=>\") || typeText.startsWith(\"(\")) return \"function\";\n if (type.isObject()) return \"object\";\n return \"other\";\n}\n\n/**\n * For a union type, attempt to extract string/number literal member values.\n */\nfunction expandUnionValues(type: Type): string[] | undefined {\n if (!type.isUnion()) return undefined;\n const values: string[] = [];\n for (const member of type.getUnionTypes()) {\n if (member.isStringLiteral()) {\n values.push(member.getLiteralValue() as string);\n } else if (member.isNumberLiteral()) {\n values.push(String(member.getLiteralValue()));\n } else if (member.isBooleanLiteral()) {\n // In ts-morph v25, getLiteralValue() may return undefined for bool literals\n // getText() reliably returns \"true\" or \"false\"\n const boolText = member.getText();\n if (boolText === \"true\" || boolText === \"false\") {\n values.push(boolText);\n }\n }\n // Skip non-literal union members (e.g. string | null | undefined)\n }\n return values.length > 0 ? values : undefined;\n}\n\n/**\n * Build a PropDescriptor from a ts-morph Type + optional default value source.\n */\nfunction buildPropDescriptor(type: Type, required: boolean, defaultValue?: string): PropDescriptor {\n const kind = resolvePropKind(type);\n const desc: PropDescriptor = {\n type: kind,\n required,\n rawType: type.getText().replace(/import\\(\"[^\"]*\"\\)\\./g, \"\"),\n };\n if (kind === \"union\") {\n const expanded = expandUnionValues(type);\n if (expanded) desc.values = expanded;\n }\n if (defaultValue !== undefined) {\n desc.default = defaultValue;\n // A prop with a default is effectively optional at the call site\n desc.required = false;\n }\n return desc;\n}\n\n// ---------------------------------------------------------------------------\n// Props extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract props from a TypeScript interface or type alias node.\n * Returns Record<propName, PropDescriptor>.\n */\nfunction extractPropsFromType(\n typeName: string,\n sourceFile: SourceFile,\n defaultValues: Record<string, string> = {},\n): Record<string, PropDescriptor> {\n const props: Record<string, PropDescriptor> = {};\n\n // Try interface first\n const iface = sourceFile.getInterface(typeName);\n if (iface) {\n for (const prop of iface.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue; // skip index signatures\n const type = prop.getType();\n const required = !prop.hasQuestionToken();\n props[name] = buildPropDescriptor(type, required, defaultValues[name]);\n }\n return props;\n }\n\n // Try type alias\n const typeAlias = sourceFile.getTypeAlias(typeName);\n if (typeAlias) {\n const aliasType = typeAlias.getType();\n if (aliasType.isObject()) {\n for (const prop of aliasType.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue;\n const decls = prop.getDeclarations();\n const required =\n decls.length === 0 ||\n !prop.getDeclarations().some((d) => Node.isPropertySignature(d) && d.hasQuestionToken());\n const valType = prop.getTypeAtLocation(sourceFile);\n props[name] = buildPropDescriptor(valType, required, defaultValues[name]);\n }\n }\n return props;\n }\n\n return props;\n}\n\n/**\n * Try to infer the props type name from a function's parameter destructuring.\n * E.g. `function Foo({ bar }: FooProps)` → \"FooProps\"\n */\nfunction inferPropsTypeName(params: { getTypeNode(): Node | undefined }[]): string | undefined {\n if (params.length === 0) return undefined;\n const firstParam = params[0];\n if (!firstParam) return undefined;\n const typeNode = firstParam.getTypeNode?.();\n if (!typeNode) return undefined;\n return typeNode.getText().trim();\n}\n\n/**\n * Extract default values from destructured parameters.\n * E.g. `function Foo({ variant = 'primary', size = 'md' }: FooProps)` → { variant: 'primary', size: 'md' }\n */\nfunction extractDefaultsFromDestructuring(\n params: ReturnType<FunctionDeclaration[\"getParameters\"]>,\n): Record<string, string> {\n const defaults: Record<string, string> = {};\n if (params.length === 0) return defaults;\n const firstParam = params[0];\n if (!firstParam) return defaults;\n\n const nameNode = firstParam.getNameNode();\n if (!Node.isObjectBindingPattern(nameNode)) return defaults;\n\n for (const element of nameNode.getElements()) {\n const initializer = element.getInitializer();\n if (initializer) {\n const propName = element.getPropertyNameNode()?.getText() ?? element.getName();\n defaults[propName] = initializer.getText();\n }\n }\n return defaults;\n}\n\n// ---------------------------------------------------------------------------\n// JSX composition extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Collect all JSX element tag names used inside a node.\n * Returns only PascalCase names (component references, not host elements).\n */\nfunction collectJsxCompositions(node: Node): string[] {\n const names = new Set<string>();\n\n function visit(n: Node): void {\n if (Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n)) {\n const tagNameNode = n.getTagNameNode();\n const tagName = tagNameNode.getText();\n // Only capture PascalCase = React components (not div, span, etc.)\n if (/^[A-Z]/.test(tagName)) {\n // Strip member access – e.g. React.Fragment → skip; Context.Provider → skip\n const base = tagName.split(\".\")[0] ?? tagName;\n if (base && /^[A-Z]/.test(base) && ![\"React\", \"Fragment\"].includes(base)) {\n names.add(base);\n }\n }\n }\n n.forEachChild(visit);\n }\n\n visit(node);\n return Array.from(names);\n}\n\n// ---------------------------------------------------------------------------\n// HOC / wrapper detection\n// ---------------------------------------------------------------------------\n\ninterface WrapperInfo {\n memoized: boolean;\n forwardedRef: boolean;\n hocWrappers: string[];\n}\n\n/**\n * Detect React.memo, React.forwardRef, and arbitrary HOC wrappers on a call expression.\n */\nfunction detectWrappers(node: Node): WrapperInfo {\n let memoized = false;\n let forwardedRef = false;\n const hocWrappers: string[] = [];\n\n function visitCall(n: Node): void {\n if (!Node.isCallExpression(n)) return;\n const expr = n.getExpression();\n const name = expr.getText();\n\n if (name === \"React.memo\" || name === \"memo\") {\n memoized = true;\n // Recurse into the inner arg (it might also be forwardRef)\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else if (name === \"React.forwardRef\" || name === \"forwardRef\") {\n forwardedRef = true;\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else {\n // Generic HOC: something(Component)\n const args = n.getArguments();\n if (args.length > 0) {\n const firstArg = args[0];\n if (firstArg && (Node.isIdentifier(firstArg) || Node.isCallExpression(firstArg))) {\n // Treat outer call name as an HOC wrapper\n const calleeName = name.split(\".\").pop() ?? name;\n if (/^[a-z]/.test(calleeName)) {\n hocWrappers.push(calleeName);\n }\n if (Node.isCallExpression(firstArg)) {\n visitCall(firstArg);\n }\n }\n }\n }\n }\n\n visitCall(node);\n return { memoized, forwardedRef, hocWrappers };\n}\n\n// ---------------------------------------------------------------------------\n// Component name resolution for wrapped components\n// ---------------------------------------------------------------------------\n\n/**\n * Given a call expression like `React.memo(function Foo() {...})`, extract the inner name.\n */\nfunction extractNameFromWrappedCall(node: Node): string | undefined {\n if (!Node.isCallExpression(node)) return undefined;\n const args = node.getArguments();\n if (args.length === 0) return undefined;\n\n const firstArg = args[0];\n if (!firstArg) return undefined;\n\n // memo(function Foo() {...})\n if (Node.isFunctionExpression(firstArg)) {\n return firstArg.getName() ?? undefined;\n }\n // memo(Foo) where Foo is an identifier\n if (Node.isIdentifier(firstArg)) {\n return firstArg.getText();\n }\n // memo(forwardRef(function Foo() {...}))\n if (Node.isCallExpression(firstArg)) {\n return extractNameFromWrappedCall(firstArg);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Returns-JSX detection\n// ---------------------------------------------------------------------------\n\nfunction nodeReturnsJsx(node: Node): boolean {\n let found = false;\n function visit(n: Node): void {\n if (found) return;\n if (Node.isJsxElement(n) || Node.isJsxFragment(n) || Node.isJsxSelfClosingElement(n)) {\n found = true;\n return;\n }\n n.forEachChild(visit);\n }\n visit(node);\n return found;\n}\n\n// ---------------------------------------------------------------------------\n// Glob matching\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal glob matcher supporting `*` (any chars except `/`) and `**` (any chars).\n * Used for collection pattern and internalPatterns matching.\n */\nfunction matchGlob(pattern: string, value: string): boolean {\n // Escape regex special chars except *\n const escaped = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regexStr = escaped\n .replace(/\\*\\*/g, \"§GLOBSTAR§\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/§GLOBSTAR§/g, \".*\");\n const regex = new RegExp(`^${regexStr}$`, \"i\");\n return regex.test(value);\n}\n\n// ---------------------------------------------------------------------------\n// TSDoc tag extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract @collection and @internal tags from JSDoc on a declaration node.\n * Returns { collection?: string; internal: boolean }.\n *\n * ts-morph exposes getJsDocs() on concrete declaration types (FunctionDeclaration,\n * VariableStatement, ClassDeclaration, etc.) but not on the base Node class.\n * We use an unknown cast to access it safely.\n */\nfunction extractTsDocTags(declNode: Node): { collection?: string; internal: boolean } {\n let collection: string | undefined;\n let internal = false;\n\n // Safely access getJsDocs via duck-typing — available on most named declaration nodes\n const nodeWithDocs = declNode as unknown as {\n getJsDocs?: () => Array<{\n getTags: () => Array<{\n getTagName: () => string;\n getComment: () => string | undefined;\n }>;\n }>;\n };\n\n if (typeof nodeWithDocs.getJsDocs !== \"function\") {\n return { collection, internal };\n }\n\n const jsDocs = nodeWithDocs.getJsDocs();\n\n for (const jsDoc of jsDocs) {\n for (const tag of jsDoc.getTags()) {\n const tagName = tag.getTagName();\n if (tagName === \"collection\") {\n const comment = tag.getComment();\n if (comment && typeof comment === \"string\") {\n collection = comment.trim();\n }\n } else if (tagName === \"internal\") {\n internal = true;\n }\n }\n }\n\n return { collection, internal };\n}\n\n// ---------------------------------------------------------------------------\n// Scope file collection extraction (static AST — no bundling)\n// ---------------------------------------------------------------------------\n\n/**\n * Attempt to read `export const collection = \"...\"` from a scope file using ts-morph.\n * Returns the collection name string, or undefined if not found.\n */\nfunction readCollectionFromScopeFile(scopeFilePath: string, project: Project): string | undefined {\n // Add the scope file to the project temporarily if not already present\n let sf = project.getSourceFile(scopeFilePath);\n if (!sf) {\n sf = project.addSourceFileAtPath(scopeFilePath);\n }\n\n for (const varStmt of sf.getVariableStatements()) {\n if (!varStmt.isExported()) continue;\n for (const varDecl of varStmt.getDeclarations()) {\n if (varDecl.getName() !== \"collection\") continue;\n const initializer = varDecl.getInitializer();\n if (!initializer) continue;\n if (Node.isStringLiteral(initializer)) {\n return initializer.getLiteralValue();\n }\n }\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Per-file component extraction\n// ---------------------------------------------------------------------------\n\ninterface RawComponent {\n name: string;\n descriptor: ComponentDescriptor;\n}\n\nfunction processSourceFile(\n sourceFile: SourceFile,\n rootDir: string,\n project: Project,\n): RawComponent[] {\n const results: RawComponent[] = [];\n const filePath = relative(rootDir, sourceFile.getFilePath());\n\n // Collect default export assignment target name (e.g. `export default Foo`)\n // Also handle wrapped defaults: `export default React.memo(Foo)` or `export default React.forwardRef(Foo)`\n let defaultExportName: string | undefined;\n const defaultExportWrappers = new Map<string, WrapperInfo>();\n sourceFile.forEachChild((node) => {\n if (Node.isExportAssignment(node)) {\n const expr = (node as ExportAssignment).getExpression();\n if (Node.isIdentifier(expr)) {\n defaultExportName = (expr as Identifier).getText();\n } else if (Node.isCallExpression(expr)) {\n // e.g. `export default React.memo(Sidebar)` or `export default React.forwardRef(Btn)`\n const innerName = extractNameFromWrappedCall(expr);\n if (innerName) {\n defaultExportName = innerName;\n defaultExportWrappers.set(innerName, detectWrappers(expr));\n }\n }\n }\n });\n\n // Named exports map: variable name → export type\n const namedExports = new Set<string>();\n for (const exportDecl of sourceFile.getExportSymbols()) {\n namedExports.add(exportDecl.getName());\n }\n\n // -------------------------------------------------------------------------\n // 1. Function declarations\n // -------------------------------------------------------------------------\n for (const fn of sourceFile.getFunctions()) {\n const name = fn.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n if (!nodeReturnsJsx(fn)) continue;\n\n const params = fn.getParameters();\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(fn);\n const start = fn.getStartLineNumber();\n const end = fn.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (fn.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (fn.isExported() || namedExports.has(name)) exportType = \"named\";\n\n const fnWrappers = defaultExportWrappers.get(name) ?? {\n memoized: false,\n forwardedRef: false,\n hocWrappers: [],\n };\n\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: fnWrappers.forwardedRef,\n hocWrappers: fnWrappers.hocWrappers,\n memoized: fnWrappers.memoized,\n loc: { start, end },\n complexityClass: analyzeComplexity(fn),\n detectedHooks: detectHooks(fn),\n requiredContexts: detectRequiredContexts(fn, sourceFile, project),\n sideEffects: detectSideEffects(fn),\n scopeFile: null,\n // collection and internal will be filled in after all components are collected\n internal: false,\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // 2. Variable declarations (arrow functions, React.memo, React.forwardRef)\n // -------------------------------------------------------------------------\n for (const varStmt of sourceFile.getVariableStatements()) {\n const isExported = varStmt.isExported();\n for (const varDecl of varStmt.getDeclarations()) {\n const varName = (varDecl as VariableDeclaration).getName();\n if (!/^[A-Z]/.test(varName)) continue;\n\n const initializer = (varDecl as VariableDeclaration).getInitializer();\n if (!initializer) continue;\n\n // Detect wrappers on the whole expression\n const wrappers = detectWrappers(initializer);\n let innerName: string | undefined;\n let bodyNode: Node = initializer;\n\n if (Node.isCallExpression(initializer)) {\n innerName = extractNameFromWrappedCall(initializer);\n // Drill into the innermost function for props / JSX\n const args = initializer.getArguments();\n const firstArg = args[0];\n if (firstArg) {\n if (Node.isArrowFunction(firstArg) || Node.isFunctionExpression(firstArg)) {\n bodyNode = firstArg;\n } else if (Node.isCallExpression(firstArg)) {\n // e.g. memo(forwardRef(fn))\n const innerArgs = firstArg.getArguments();\n const innerFirst = innerArgs[0];\n if (\n innerFirst &&\n (Node.isArrowFunction(innerFirst) || Node.isFunctionExpression(innerFirst))\n ) {\n bodyNode = innerFirst;\n }\n }\n }\n }\n\n // Must return JSX somewhere in the body\n if (!nodeReturnsJsx(bodyNode)) continue;\n\n // For named inner functions we use innerName; fall back to varName\n const componentName = innerName ?? varName;\n\n let params: ReturnType<FunctionDeclaration[\"getParameters\"]> = [];\n if (Node.isArrowFunction(bodyNode) || Node.isFunctionExpression(bodyNode)) {\n params = bodyNode.getParameters();\n }\n\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(bodyNode);\n const startLine = (varDecl as VariableDeclaration).getStartLineNumber();\n const endLine = (varDecl as VariableDeclaration).getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (defaultExportName === varName || defaultExportName === componentName) {\n exportType = \"default\";\n } else if (isExported || namedExports.has(varName)) {\n exportType = \"named\";\n }\n\n results.push({\n name: componentName === varName ? componentName : varName,\n descriptor: {\n filePath,\n exportType,\n displayName: componentName,\n props,\n composes,\n composedBy: [],\n forwardedRef: wrappers.forwardedRef,\n hocWrappers: wrappers.hocWrappers,\n memoized: wrappers.memoized,\n loc: { start: startLine, end: endLine },\n complexityClass: analyzeComplexity(bodyNode),\n detectedHooks: detectHooks(bodyNode),\n requiredContexts: detectRequiredContexts(bodyNode, sourceFile, project),\n sideEffects: detectSideEffects(bodyNode),\n scopeFile: null,\n internal: false,\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // 3. Class components\n // -------------------------------------------------------------------------\n for (const cls of sourceFile.getClasses()) {\n const name = cls.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n\n // Must extend React.Component or React.PureComponent\n const baseClass = (cls as ClassDeclaration).getBaseClass()?.getName();\n if (!baseClass && !(cls as ClassDeclaration).getExtends()) continue;\n const extendsText = (cls as ClassDeclaration).getExtends()?.getText() ?? \"\";\n if (!extendsText.includes(\"Component\") && !extendsText.includes(\"PureComponent\")) {\n continue;\n }\n\n // Render method must return JSX\n const renderMethod = cls.getMethod(\"render\");\n if (!renderMethod || !nodeReturnsJsx(renderMethod)) continue;\n\n // Extract first type argument as props type\n const extendsNode = (cls as ClassDeclaration).getExtends();\n let propsTypeName: string | undefined;\n if (extendsNode) {\n const typeArgs = extendsNode.getTypeArguments();\n if (typeArgs[0]) {\n propsTypeName = typeArgs[0].getText().trim();\n }\n }\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile) : {};\n\n const composes = collectJsxCompositions(renderMethod);\n const start = cls.getStartLineNumber();\n const end = cls.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (cls.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (cls.isExported() || namedExports.has(name)) exportType = \"named\";\n\n // Class components: default to \"complex\" (they often use lifecycle methods / state)\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: false,\n hocWrappers: [],\n memoized: false,\n loc: { start, end },\n complexityClass: \"complex\",\n detectedHooks: [],\n requiredContexts: [],\n sideEffects: detectSideEffects(cls),\n scopeFile: null,\n internal: false,\n },\n });\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a component manifest by parsing all matching TypeScript/TSX files.\n */\nexport function generateManifest(config: ManifestConfig): Manifest {\n const {\n rootDir,\n include = [\"src/**/*.tsx\", \"src/**/*.ts\"],\n exclude = [\"**/node_modules/**\", \"**/*.test.*\", \"**/*.spec.*\", \"**/dist/**\", \"**/*.d.ts\"],\n tsConfigFilePath = join(rootDir, \"tsconfig.json\"),\n } = config;\n\n const project = new Project({\n tsConfigFilePath,\n skipAddingFilesFromTsConfig: true,\n });\n\n // Add source files via glob\n const includePatterns = include.map((g) => join(rootDir, g));\n project.addSourceFilesFromTsConfig(tsConfigFilePath);\n\n // If tsconfig doesn't cover the files, add them directly\n for (const pattern of includePatterns) {\n project.addSourceFilesAtPaths(pattern);\n }\n\n // Remove excluded files\n for (const sf of project.getSourceFiles()) {\n const fp = sf.getFilePath();\n const shouldExclude = exclude.some((ex) => {\n const pattern = ex.replace(/\\*\\*/g, \".*\").replace(/\\*/g, \"[^/]*\").replace(/\\./g, \"\\\\.\");\n return new RegExp(pattern).test(fp);\n });\n if (shouldExclude) {\n project.removeSourceFile(sf);\n }\n }\n\n // Also filter to only files within rootDir\n for (const sf of project.getSourceFiles()) {\n if (!sf.getFilePath().startsWith(rootDir)) {\n project.removeSourceFile(sf);\n }\n }\n\n // Collect all components\n const allComponents: Record<string, ComponentDescriptor> = {};\n\n for (const sf of project.getSourceFiles()) {\n const rawComponents = processSourceFile(sf, rootDir, project);\n for (const { name, descriptor } of rawComponents) {\n // If duplicate name, prefer the exported one\n if (allComponents[name] && descriptor.exportType === \"none\") continue;\n allComponents[name] = descriptor;\n }\n }\n\n // Build composition inverse: composedBy\n for (const [name, desc] of Object.entries(allComponents)) {\n for (const child of desc.composes) {\n if (allComponents[child]) {\n const childDesc = allComponents[child];\n if (childDesc && !childDesc.composedBy.includes(name)) {\n childDesc.composedBy.push(name);\n }\n }\n }\n }\n\n // Propagate complexityClass upward through the composition tree.\n // A component is only `simple` if it AND every descendant are simple.\n // This must run after composedBy is fully populated.\n propagateComplexity(allComponents);\n\n // Build tree\n const tree: Manifest[\"tree\"] = {};\n for (const [name, desc] of Object.entries(allComponents)) {\n // Only include children that exist in the manifest\n const children = desc.composes.filter((c) => c in allComponents);\n const parents = desc.composedBy.filter((p) => p in allComponents);\n tree[name] = { children, parents };\n }\n\n // Attach scope file metadata to each component (static presence check only)\n for (const desc of Object.values(allComponents)) {\n const scopeMeta = detectScopeFile(desc.filePath, config.rootDir);\n if (scopeMeta !== null) {\n desc.scopeFile = scopeMeta;\n }\n }\n\n // -------------------------------------------------------------------------\n // Resolve collection and internal for each component\n // After composedBy + scope file is populated.\n //\n // Precedence:\n // collection: TSDoc @collection > .scope.ts export > config patterns\n // internal: TSDoc @internal > config internalPatterns\n // -------------------------------------------------------------------------\n const configCollections: CollectionConfig[] = config.collections ?? [];\n const internalPatterns: string[] = config.internalPatterns ?? [];\n\n for (const [compName, desc] of Object.entries(allComponents)) {\n // --- 1. TSDoc-based collection & internal ---\n // We need to find the source file to look up the declaration\n const absFilePath = desc.filePath.startsWith(\"/\")\n ? desc.filePath\n : join(rootDir, desc.filePath);\n const sf = project.getSourceFile(absFilePath);\n\n let tsdocCollection: string | undefined;\n let tsdocInternal = false;\n\n if (sf) {\n // Try function declarations first\n const fn = sf.getFunction(compName);\n if (fn) {\n const tags = extractTsDocTags(fn);\n tsdocCollection = tags.collection;\n tsdocInternal = tags.internal;\n }\n\n // Try variable declarations (arrow functions, React.memo, etc.)\n if (tsdocCollection === undefined && !tsdocInternal) {\n const varDecl = sf.getVariableDeclaration(compName);\n if (varDecl) {\n // JSDocs are on the VariableStatement, not the VariableDeclaration\n const varStmt = varDecl.getVariableStatement();\n if (varStmt) {\n const tags = extractTsDocTags(varStmt);\n tsdocCollection = tags.collection;\n tsdocInternal = tags.internal;\n }\n }\n }\n\n // Try class declarations\n if (tsdocCollection === undefined && !tsdocInternal) {\n const cls = sf.getClass(compName);\n if (cls) {\n const tags = extractTsDocTags(cls);\n tsdocCollection = tags.collection;\n tsdocInternal = tags.internal;\n }\n }\n }\n\n // --- 2. .scope.ts collection ---\n let scopeFileCollection: string | undefined;\n if (desc.scopeFile) {\n scopeFileCollection = readCollectionFromScopeFile(desc.scopeFile.filePath, project);\n }\n\n // --- 3. Config pattern matching ---\n let configCollection: string | undefined;\n for (const colConfig of configCollections) {\n if (colConfig.patterns.some((p) => matchGlob(p, desc.filePath))) {\n configCollection = colConfig.name;\n break;\n }\n }\n\n let configInternal = false;\n if (internalPatterns.length > 0) {\n configInternal = internalPatterns.some(\n (p) => matchGlob(p, desc.filePath) || matchGlob(p, desc.displayName),\n );\n }\n\n // --- Apply precedence ---\n // collection: TSDoc > .scope.ts > config\n const resolvedCollection = tsdocCollection ?? scopeFileCollection ?? configCollection;\n if (resolvedCollection !== undefined) {\n desc.collection = resolvedCollection;\n }\n\n // internal: TSDoc > config patterns\n desc.internal = tsdocInternal || configInternal;\n }\n\n return {\n version: \"0.1\",\n generatedAt: new Date().toISOString(),\n components: allComponents,\n tree,\n collections: configCollections,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Scope file detection (static — presence check only, no bundling)\n// ---------------------------------------------------------------------------\n\nconst SCOPE_EXTENSIONS = [\".scope.tsx\", \".scope.ts\", \".scope.jsx\", \".scope.js\"];\n\n/**\n * Check whether a scope file exists next to the component file.\n * Returns minimal ScopeFileMeta if found, null otherwise.\n *\n * scenarioNames and hasWrapper are left empty here — they are populated at\n * render time when loadScopeFile() actually bundles and evaluates the file.\n */\nfunction detectScopeFile(componentFilePath: string, rootDir: string): ScopeFileMeta | null {\n const absPath = componentFilePath.startsWith(\"/\")\n ? componentFilePath\n : join(rootDir, componentFilePath);\n\n const stem = absPath.replace(/\\.(tsx?|jsx?)$/, \"\");\n for (const ext of SCOPE_EXTENSIONS) {\n const candidate = `${stem}${ext}`;\n if (existsSync(candidate)) {\n return { filePath: candidate, scenarioNames: [], hasWrapper: false };\n }\n }\n return null;\n}\n"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -132,6 +132,26 @@ interface ComponentDescriptor {
|
|
|
132
132
|
* `null` when no scope file is found next to the component source file.
|
|
133
133
|
*/
|
|
134
134
|
scopeFile: ScopeFileMeta | null;
|
|
135
|
+
/**
|
|
136
|
+
* The collection this component belongs to (e.g. "Forms", "Navigation").
|
|
137
|
+
* `undefined` means ungrouped.
|
|
138
|
+
*
|
|
139
|
+
* Resolution precedence (highest → lowest):
|
|
140
|
+
* 1. `@collection <name>` TSDoc tag on the component declaration
|
|
141
|
+
* 2. `export const collection = "name"` in a co-located `.scope.ts` file
|
|
142
|
+
* 3. First matching pattern in `config.collections[].patterns`
|
|
143
|
+
*/
|
|
144
|
+
collection?: string;
|
|
145
|
+
/**
|
|
146
|
+
* Whether this component is internal (not intended for external consumers).
|
|
147
|
+
* Defaults to `false`.
|
|
148
|
+
*
|
|
149
|
+
* Set to `true` when:
|
|
150
|
+
* - `@internal` TSDoc tag is present on the component declaration, OR
|
|
151
|
+
* - The component's `filePath` or `displayName` matches any pattern in
|
|
152
|
+
* `config.internalPatterns`.
|
|
153
|
+
*/
|
|
154
|
+
internal: boolean;
|
|
135
155
|
}
|
|
136
156
|
/**
|
|
137
157
|
* Metadata extracted from a `.scope.ts(x)` / `.scope.js(x)` file that lives
|
|
@@ -151,6 +171,17 @@ interface ScopeFileMeta {
|
|
|
151
171
|
*/
|
|
152
172
|
hasWrapper: boolean;
|
|
153
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Configuration for a named component collection.
|
|
176
|
+
*/
|
|
177
|
+
interface CollectionConfig {
|
|
178
|
+
/** Human-readable collection name (e.g. "Forms", "Navigation"). */
|
|
179
|
+
name: string;
|
|
180
|
+
/** Optional description of the collection. */
|
|
181
|
+
description?: string;
|
|
182
|
+
/** Glob patterns matching component file paths that belong to this collection. */
|
|
183
|
+
patterns: string[];
|
|
184
|
+
}
|
|
154
185
|
/**
|
|
155
186
|
* A node in the composition tree.
|
|
156
187
|
*/
|
|
@@ -172,6 +203,11 @@ interface Manifest {
|
|
|
172
203
|
components: Record<string, ComponentDescriptor>;
|
|
173
204
|
/** Composition tree (child/parent relationships). */
|
|
174
205
|
tree: Record<string, TreeNode>;
|
|
206
|
+
/**
|
|
207
|
+
* All defined collections, echoing `config.collections`.
|
|
208
|
+
* Empty array when no collections are configured.
|
|
209
|
+
*/
|
|
210
|
+
collections: CollectionConfig[];
|
|
175
211
|
}
|
|
176
212
|
/**
|
|
177
213
|
* Configuration for `generateManifest`.
|
|
@@ -199,6 +235,18 @@ interface ManifestConfig {
|
|
|
199
235
|
* Defaults to `<rootDir>/tsconfig.json`.
|
|
200
236
|
*/
|
|
201
237
|
tsConfigFilePath?: string;
|
|
238
|
+
/**
|
|
239
|
+
* Named component collections. Each entry maps a set of glob patterns to a
|
|
240
|
+
* collection name. Components whose `filePath` matches a pattern are assigned
|
|
241
|
+
* to that collection (config-level precedence — lower than TSDoc / .scope.ts).
|
|
242
|
+
*/
|
|
243
|
+
collections?: CollectionConfig[];
|
|
244
|
+
/**
|
|
245
|
+
* Glob patterns for components that should be flagged as internal.
|
|
246
|
+
* Matched against both `filePath` and `displayName`.
|
|
247
|
+
* Config-level precedence — lower than an explicit `@internal` TSDoc tag.
|
|
248
|
+
*/
|
|
249
|
+
internalPatterns?: string[];
|
|
202
250
|
}
|
|
203
251
|
|
|
204
252
|
/**
|
|
@@ -206,4 +254,4 @@ interface ManifestConfig {
|
|
|
206
254
|
*/
|
|
207
255
|
declare function generateManifest(config: ManifestConfig): Manifest;
|
|
208
256
|
|
|
209
|
-
export { type ComplexityClass, type ComponentDescriptor, type ExportType, type Manifest, type ManifestConfig, type PropDescriptor, type PropKind, type ScopeFileMeta, type SideEffects, type TreeNode, generateManifest };
|
|
257
|
+
export { type CollectionConfig, type ComplexityClass, type ComponentDescriptor, type ExportType, type Manifest, type ManifestConfig, type PropDescriptor, type PropKind, type ScopeFileMeta, type SideEffects, type TreeNode, generateManifest };
|
package/dist/index.d.ts
CHANGED
|
@@ -132,6 +132,26 @@ interface ComponentDescriptor {
|
|
|
132
132
|
* `null` when no scope file is found next to the component source file.
|
|
133
133
|
*/
|
|
134
134
|
scopeFile: ScopeFileMeta | null;
|
|
135
|
+
/**
|
|
136
|
+
* The collection this component belongs to (e.g. "Forms", "Navigation").
|
|
137
|
+
* `undefined` means ungrouped.
|
|
138
|
+
*
|
|
139
|
+
* Resolution precedence (highest → lowest):
|
|
140
|
+
* 1. `@collection <name>` TSDoc tag on the component declaration
|
|
141
|
+
* 2. `export const collection = "name"` in a co-located `.scope.ts` file
|
|
142
|
+
* 3. First matching pattern in `config.collections[].patterns`
|
|
143
|
+
*/
|
|
144
|
+
collection?: string;
|
|
145
|
+
/**
|
|
146
|
+
* Whether this component is internal (not intended for external consumers).
|
|
147
|
+
* Defaults to `false`.
|
|
148
|
+
*
|
|
149
|
+
* Set to `true` when:
|
|
150
|
+
* - `@internal` TSDoc tag is present on the component declaration, OR
|
|
151
|
+
* - The component's `filePath` or `displayName` matches any pattern in
|
|
152
|
+
* `config.internalPatterns`.
|
|
153
|
+
*/
|
|
154
|
+
internal: boolean;
|
|
135
155
|
}
|
|
136
156
|
/**
|
|
137
157
|
* Metadata extracted from a `.scope.ts(x)` / `.scope.js(x)` file that lives
|
|
@@ -151,6 +171,17 @@ interface ScopeFileMeta {
|
|
|
151
171
|
*/
|
|
152
172
|
hasWrapper: boolean;
|
|
153
173
|
}
|
|
174
|
+
/**
|
|
175
|
+
* Configuration for a named component collection.
|
|
176
|
+
*/
|
|
177
|
+
interface CollectionConfig {
|
|
178
|
+
/** Human-readable collection name (e.g. "Forms", "Navigation"). */
|
|
179
|
+
name: string;
|
|
180
|
+
/** Optional description of the collection. */
|
|
181
|
+
description?: string;
|
|
182
|
+
/** Glob patterns matching component file paths that belong to this collection. */
|
|
183
|
+
patterns: string[];
|
|
184
|
+
}
|
|
154
185
|
/**
|
|
155
186
|
* A node in the composition tree.
|
|
156
187
|
*/
|
|
@@ -172,6 +203,11 @@ interface Manifest {
|
|
|
172
203
|
components: Record<string, ComponentDescriptor>;
|
|
173
204
|
/** Composition tree (child/parent relationships). */
|
|
174
205
|
tree: Record<string, TreeNode>;
|
|
206
|
+
/**
|
|
207
|
+
* All defined collections, echoing `config.collections`.
|
|
208
|
+
* Empty array when no collections are configured.
|
|
209
|
+
*/
|
|
210
|
+
collections: CollectionConfig[];
|
|
175
211
|
}
|
|
176
212
|
/**
|
|
177
213
|
* Configuration for `generateManifest`.
|
|
@@ -199,6 +235,18 @@ interface ManifestConfig {
|
|
|
199
235
|
* Defaults to `<rootDir>/tsconfig.json`.
|
|
200
236
|
*/
|
|
201
237
|
tsConfigFilePath?: string;
|
|
238
|
+
/**
|
|
239
|
+
* Named component collections. Each entry maps a set of glob patterns to a
|
|
240
|
+
* collection name. Components whose `filePath` matches a pattern are assigned
|
|
241
|
+
* to that collection (config-level precedence — lower than TSDoc / .scope.ts).
|
|
242
|
+
*/
|
|
243
|
+
collections?: CollectionConfig[];
|
|
244
|
+
/**
|
|
245
|
+
* Glob patterns for components that should be flagged as internal.
|
|
246
|
+
* Matched against both `filePath` and `displayName`.
|
|
247
|
+
* Config-level precedence — lower than an explicit `@internal` TSDoc tag.
|
|
248
|
+
*/
|
|
249
|
+
internalPatterns?: string[];
|
|
202
250
|
}
|
|
203
251
|
|
|
204
252
|
/**
|
|
@@ -206,4 +254,4 @@ interface ManifestConfig {
|
|
|
206
254
|
*/
|
|
207
255
|
declare function generateManifest(config: ManifestConfig): Manifest;
|
|
208
256
|
|
|
209
|
-
export { type ComplexityClass, type ComponentDescriptor, type ExportType, type Manifest, type ManifestConfig, type PropDescriptor, type PropKind, type ScopeFileMeta, type SideEffects, type TreeNode, generateManifest };
|
|
257
|
+
export { type CollectionConfig, type ComplexityClass, type ComponentDescriptor, type ExportType, type Manifest, type ManifestConfig, type PropDescriptor, type PropKind, type ScopeFileMeta, type SideEffects, type TreeNode, generateManifest };
|
package/dist/index.js
CHANGED
|
@@ -487,6 +487,53 @@ function nodeReturnsJsx(node) {
|
|
|
487
487
|
visit(node);
|
|
488
488
|
return found;
|
|
489
489
|
}
|
|
490
|
+
function matchGlob(pattern, value) {
|
|
491
|
+
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&");
|
|
492
|
+
const regexStr = escaped.replace(/\*\*/g, "\xA7GLOBSTAR\xA7").replace(/\*/g, "[^/]*").replace(/§GLOBSTAR§/g, ".*");
|
|
493
|
+
const regex = new RegExp(`^${regexStr}$`, "i");
|
|
494
|
+
return regex.test(value);
|
|
495
|
+
}
|
|
496
|
+
function extractTsDocTags(declNode) {
|
|
497
|
+
let collection;
|
|
498
|
+
let internal = false;
|
|
499
|
+
const nodeWithDocs = declNode;
|
|
500
|
+
if (typeof nodeWithDocs.getJsDocs !== "function") {
|
|
501
|
+
return { collection, internal };
|
|
502
|
+
}
|
|
503
|
+
const jsDocs = nodeWithDocs.getJsDocs();
|
|
504
|
+
for (const jsDoc of jsDocs) {
|
|
505
|
+
for (const tag of jsDoc.getTags()) {
|
|
506
|
+
const tagName = tag.getTagName();
|
|
507
|
+
if (tagName === "collection") {
|
|
508
|
+
const comment = tag.getComment();
|
|
509
|
+
if (comment && typeof comment === "string") {
|
|
510
|
+
collection = comment.trim();
|
|
511
|
+
}
|
|
512
|
+
} else if (tagName === "internal") {
|
|
513
|
+
internal = true;
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
return { collection, internal };
|
|
518
|
+
}
|
|
519
|
+
function readCollectionFromScopeFile(scopeFilePath, project) {
|
|
520
|
+
let sf = project.getSourceFile(scopeFilePath);
|
|
521
|
+
if (!sf) {
|
|
522
|
+
sf = project.addSourceFileAtPath(scopeFilePath);
|
|
523
|
+
}
|
|
524
|
+
for (const varStmt of sf.getVariableStatements()) {
|
|
525
|
+
if (!varStmt.isExported()) continue;
|
|
526
|
+
for (const varDecl of varStmt.getDeclarations()) {
|
|
527
|
+
if (varDecl.getName() !== "collection") continue;
|
|
528
|
+
const initializer = varDecl.getInitializer();
|
|
529
|
+
if (!initializer) continue;
|
|
530
|
+
if (Node.isStringLiteral(initializer)) {
|
|
531
|
+
return initializer.getLiteralValue();
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
return void 0;
|
|
536
|
+
}
|
|
490
537
|
function processSourceFile(sourceFile, rootDir, project) {
|
|
491
538
|
const results = [];
|
|
492
539
|
const filePath = relative(rootDir, sourceFile.getFilePath());
|
|
@@ -547,7 +594,9 @@ function processSourceFile(sourceFile, rootDir, project) {
|
|
|
547
594
|
detectedHooks: detectHooks(fn),
|
|
548
595
|
requiredContexts: detectRequiredContexts(fn, sourceFile, project),
|
|
549
596
|
sideEffects: detectSideEffects(fn),
|
|
550
|
-
scopeFile: null
|
|
597
|
+
scopeFile: null,
|
|
598
|
+
// collection and internal will be filled in after all components are collected
|
|
599
|
+
internal: false
|
|
551
600
|
}
|
|
552
601
|
});
|
|
553
602
|
}
|
|
@@ -612,7 +661,8 @@ function processSourceFile(sourceFile, rootDir, project) {
|
|
|
612
661
|
detectedHooks: detectHooks(bodyNode),
|
|
613
662
|
requiredContexts: detectRequiredContexts(bodyNode, sourceFile, project),
|
|
614
663
|
sideEffects: detectSideEffects(bodyNode),
|
|
615
|
-
scopeFile: null
|
|
664
|
+
scopeFile: null,
|
|
665
|
+
internal: false
|
|
616
666
|
}
|
|
617
667
|
});
|
|
618
668
|
}
|
|
@@ -661,7 +711,8 @@ function processSourceFile(sourceFile, rootDir, project) {
|
|
|
661
711
|
detectedHooks: [],
|
|
662
712
|
requiredContexts: [],
|
|
663
713
|
sideEffects: detectSideEffects(cls),
|
|
664
|
-
scopeFile: null
|
|
714
|
+
scopeFile: null,
|
|
715
|
+
internal: false
|
|
665
716
|
}
|
|
666
717
|
});
|
|
667
718
|
}
|
|
@@ -729,11 +780,69 @@ function generateManifest(config) {
|
|
|
729
780
|
desc.scopeFile = scopeMeta;
|
|
730
781
|
}
|
|
731
782
|
}
|
|
783
|
+
const configCollections = config.collections ?? [];
|
|
784
|
+
const internalPatterns = config.internalPatterns ?? [];
|
|
785
|
+
for (const [compName, desc] of Object.entries(allComponents)) {
|
|
786
|
+
const absFilePath = desc.filePath.startsWith("/") ? desc.filePath : join(rootDir, desc.filePath);
|
|
787
|
+
const sf = project.getSourceFile(absFilePath);
|
|
788
|
+
let tsdocCollection;
|
|
789
|
+
let tsdocInternal = false;
|
|
790
|
+
if (sf) {
|
|
791
|
+
const fn = sf.getFunction(compName);
|
|
792
|
+
if (fn) {
|
|
793
|
+
const tags = extractTsDocTags(fn);
|
|
794
|
+
tsdocCollection = tags.collection;
|
|
795
|
+
tsdocInternal = tags.internal;
|
|
796
|
+
}
|
|
797
|
+
if (tsdocCollection === void 0 && !tsdocInternal) {
|
|
798
|
+
const varDecl = sf.getVariableDeclaration(compName);
|
|
799
|
+
if (varDecl) {
|
|
800
|
+
const varStmt = varDecl.getVariableStatement();
|
|
801
|
+
if (varStmt) {
|
|
802
|
+
const tags = extractTsDocTags(varStmt);
|
|
803
|
+
tsdocCollection = tags.collection;
|
|
804
|
+
tsdocInternal = tags.internal;
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
if (tsdocCollection === void 0 && !tsdocInternal) {
|
|
809
|
+
const cls = sf.getClass(compName);
|
|
810
|
+
if (cls) {
|
|
811
|
+
const tags = extractTsDocTags(cls);
|
|
812
|
+
tsdocCollection = tags.collection;
|
|
813
|
+
tsdocInternal = tags.internal;
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
let scopeFileCollection;
|
|
818
|
+
if (desc.scopeFile) {
|
|
819
|
+
scopeFileCollection = readCollectionFromScopeFile(desc.scopeFile.filePath, project);
|
|
820
|
+
}
|
|
821
|
+
let configCollection;
|
|
822
|
+
for (const colConfig of configCollections) {
|
|
823
|
+
if (colConfig.patterns.some((p) => matchGlob(p, desc.filePath))) {
|
|
824
|
+
configCollection = colConfig.name;
|
|
825
|
+
break;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
let configInternal = false;
|
|
829
|
+
if (internalPatterns.length > 0) {
|
|
830
|
+
configInternal = internalPatterns.some(
|
|
831
|
+
(p) => matchGlob(p, desc.filePath) || matchGlob(p, desc.displayName)
|
|
832
|
+
);
|
|
833
|
+
}
|
|
834
|
+
const resolvedCollection = tsdocCollection ?? scopeFileCollection ?? configCollection;
|
|
835
|
+
if (resolvedCollection !== void 0) {
|
|
836
|
+
desc.collection = resolvedCollection;
|
|
837
|
+
}
|
|
838
|
+
desc.internal = tsdocInternal || configInternal;
|
|
839
|
+
}
|
|
732
840
|
return {
|
|
733
841
|
version: "0.1",
|
|
734
842
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
735
843
|
components: allComponents,
|
|
736
|
-
tree
|
|
844
|
+
tree,
|
|
845
|
+
collections: configCollections
|
|
737
846
|
};
|
|
738
847
|
}
|
|
739
848
|
var SCOPE_EXTENSIONS = [".scope.tsx", ".scope.ts", ".scope.jsx", ".scope.js"];
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/analysis.ts","../src/parser.ts"],"names":["Node"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Phase 6 analysis functions for @agent-scope/manifest.\n *\n * This module is responsible for:\n * 1. Complexity classification (`complexityClass`)\n * 2. Required context detection (`requiredContexts`)\n * 3. Hook detection (`detectedHooks`)\n * 4. Side-effect tracking (`sideEffects`)\n *\n * All functions accept ts-morph `Node` / `SourceFile` / `Project` values and\n * return plain data — no mutations to the AST.\n */\n\nimport { Node, type Project, type SourceFile } from \"ts-morph\";\nimport type { ComplexityClass, SideEffects } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Collect all CallExpression nodes beneath a node (inclusive). */\nfunction collectCallExpressions(root: Node): Node[] {\n const results: Node[] = [];\n root.forEachDescendant((n) => {\n if (Node.isCallExpression(n)) {\n results.push(n);\n }\n });\n return results;\n}\n\n/** Return the callee string for a CallExpression node (e.g. \"window.addEventListener\"). */\nfunction calleeText(callExpr: Node): string {\n if (!Node.isCallExpression(callExpr)) return \"\";\n return callExpr.getExpression().getText().trim();\n}\n\n// ---------------------------------------------------------------------------\n// 1. Complexity classification\n// ---------------------------------------------------------------------------\n\n/**\n * CSS property names / values that force `complex` classification.\n * Any inline-style key matching this set triggers complexity.\n */\nconst COMPLEX_STYLE_KEYS = new Set([\n \"position\",\n \"gridTemplate\",\n \"gridTemplateColumns\",\n \"gridTemplateRows\",\n \"gridArea\",\n \"gridColumn\",\n \"gridRow\",\n \"grid\",\n \"animation\",\n \"animationName\",\n \"animationDuration\",\n \"transition\",\n \"transform\",\n \"transformOrigin\",\n \"clip\",\n \"clipPath\",\n \"willChange\",\n \"contain\",\n]);\n\n/**\n * Inline-style *value* fragments that imply complex layout even when the key\n * is safe (e.g. `position: \"absolute\"`).\n */\nconst COMPLEX_POSITION_VALUES = new Set([\"absolute\", \"fixed\", \"sticky\"]);\n\n/**\n * CSS properties that begin with these prefixes are complex\n * (e.g. \"gridTemplateAreas\").\n */\nconst COMPLEX_KEY_PREFIXES = [\"grid\", \"animation\", \"transition\"];\n\nfunction isComplexStyleKey(key: string): boolean {\n if (COMPLEX_STYLE_KEYS.has(key)) return true;\n return COMPLEX_KEY_PREFIXES.some((p) => key.startsWith(p));\n}\n\n/**\n * Scan JSX attribute `style={{ ... }}` inline-object expressions for complex\n * CSS properties. Returns true if any complex property is detected.\n */\nfunction hasCssComplexity(root: Node): boolean {\n let complex = false;\n\n root.forEachDescendant((n) => {\n if (complex) return;\n\n // --- Inline style object: style={{ position: \"absolute\", ... }} ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"style\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // style={{ ... }} → JsxExpression wrapping an ObjectLiteralExpression\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n if (!inner || !Node.isObjectLiteralExpression(inner)) return;\n\n for (const prop of inner.getProperties()) {\n if (complex) break;\n if (!Node.isPropertyAssignment(prop) && !Node.isShorthandPropertyAssignment(prop)) {\n continue;\n }\n\n const keyText = prop.getNameNode().getText();\n\n if (isComplexStyleKey(keyText)) {\n complex = true;\n break;\n }\n\n // Check value for position: \"absolute\" | \"fixed\" | \"sticky\"\n if (keyText === \"position\" && Node.isPropertyAssignment(prop)) {\n const val = prop.getInitializer();\n if (val) {\n const raw = val.getText().replace(/['\"]/g, \"\").trim().toLowerCase();\n if (COMPLEX_POSITION_VALUES.has(raw)) {\n complex = true;\n break;\n }\n }\n }\n }\n }\n return;\n }\n\n // --- Styled-components / css template literals ---\n // These are too opaque to analyze reliably; treat as complex\n if (Node.isTaggedTemplateExpression(n)) {\n const tag = n.getTag().getText();\n // styled.div`...`, styled(Component)`...`, css`...`\n if (tag.startsWith(\"styled\") || tag === \"css\" || tag === \"keyframes\") {\n complex = true;\n }\n return;\n }\n\n // --- className with a non-trivial expression → can't analyze, default complex ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"className\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // className=\"literal\" is fine; className={expr} is opaque\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n // Allow simple string concatenation / template literals - skip\n // Identifiers / call expressions pointing to CSS modules → complex\n if (\n inner &&\n (Node.isIdentifier(inner) ||\n Node.isCallExpression(inner) ||\n Node.isPropertyAccessExpression(inner))\n ) {\n complex = true;\n }\n }\n }\n });\n\n return complex;\n}\n\n/**\n * Classify a component body as `\"simple\"` or `\"complex\"`.\n *\n * Rule: any use of complex CSS properties (grid, absolute/fixed/sticky\n * positioning, animations, transforms, transitions) OR styled-components\n * OR opaque className references → `\"complex\"`.\n *\n * Default is `\"simple\"` when nothing complex is detected.\n * Callers should pass `\"complex\"` as the safe fallback for class components\n * or other patterns where analysis is not possible.\n */\nexport function analyzeComplexity(bodyNode: Node): ComplexityClass {\n return hasCssComplexity(bodyNode) ? \"complex\" : \"simple\";\n}\n\n// ---------------------------------------------------------------------------\n// 2. Hook detection\n// ---------------------------------------------------------------------------\n\nconst HOOK_REGEX = /^use[A-Z]/;\n\n/**\n * Collect all hook calls within a node.\n * A \"hook\" is any call expression whose callee matches /^use[A-Z]/.\n *\n * Returns a de-duplicated, sorted array of hook names.\n */\nexport function detectHooks(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n // Only the base name — drop member access (e.g. React.useState → useState)\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base)) {\n names.add(base);\n }\n });\n\n return Array.from(names).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 3. Required context detection\n// ---------------------------------------------------------------------------\n\n/**\n * Map from callee text → context variable name patterns.\n * We look for `useContext(SomeCtx)` patterns.\n */\nfunction extractDirectContextNames(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (base !== \"useContext\") return;\n\n const args = (Node.isCallExpression(callExpr) ? callExpr : null)?.getArguments() ?? [];\n const firstArg = args[0];\n if (!firstArg) return;\n\n // useContext(ThemeCtx) → \"ThemeCtx\"\n const argText = firstArg.getText().trim();\n if (argText) {\n names.add(argText);\n }\n });\n\n return Array.from(names);\n}\n\n/**\n * Given a custom hook name imported from a specifier, resolve its source file\n * and extract any `useContext(...)` calls it makes.\n *\n * Returns context variable names, e.g. [\"ThemeCtx\", \"AuthCtx\"].\n */\nfunction resolveHookContexts(\n hookName: string,\n importingFile: SourceFile,\n importSpecifier: string,\n project: Project,\n): string[] {\n // Attempt to resolve via ts-morph project\n const allFiles = project.getSourceFiles();\n const importingDir = importingFile.getDirectoryPath();\n\n // Build candidate paths for the specifier\n const specParts = importSpecifier.replace(/^\\.\\.?\\//, \"\");\n const candidates = allFiles.filter((sf) => {\n const fp = sf.getFilePath();\n // Must be relative to the same directory tree\n if (!fp.startsWith(importingDir.split(\"/src/\")[0] ?? importingDir)) return false;\n const basename = fp.split(\"/\").pop() ?? \"\";\n const specBase = specParts.split(\"/\").pop() ?? specParts;\n return (\n basename === `${specBase}.ts` ||\n basename === `${specBase}.tsx` ||\n basename === `${specBase}.js` ||\n basename === `${specBase}.jsx` ||\n fp.endsWith(`${specParts}.ts`) ||\n fp.endsWith(`${specParts}.tsx`) ||\n fp.endsWith(`${importSpecifier}.ts`) ||\n fp.endsWith(`${importSpecifier}.tsx`)\n );\n });\n\n for (const candidate of candidates) {\n // Find the hook function in this file\n const hookFunctions = [\n ...candidate.getFunctions().filter((f) => f.getName() === hookName),\n ...candidate.getVariableDeclarations().filter((v) => v.getName() === hookName),\n ];\n\n for (const fn of hookFunctions) {\n const ctxNames = extractDirectContextNames(fn);\n if (ctxNames.length > 0) return ctxNames;\n }\n\n // Also try arrow functions assigned to const hookName = () => ...\n // (already covered by getVariableDeclarations above)\n }\n\n return [];\n}\n\n/**\n * Detect all React context identifiers required by a component.\n *\n * Algorithm:\n * 1. Scan the component body for direct `useContext(X)` calls.\n * 2. Find all `import { useXxx } from './...'` statements.\n * 3. For each imported custom hook (matching /^use[A-Z]/), resolve its\n * source file and scan it for `useContext()` calls.\n * 4. Merge and de-duplicate.\n *\n * Returns a sorted array of context variable names.\n */\nexport function detectRequiredContexts(\n bodyNode: Node,\n sourceFile: SourceFile,\n project: Project,\n): string[] {\n const contextNames = new Set<string>();\n\n // Step 1: direct useContext() in component body\n for (const name of extractDirectContextNames(bodyNode)) {\n contextNames.add(name);\n }\n\n // Step 2: find imported hooks used in this component body\n const hookedCalls = new Set<string>();\n collectCallExpressions(bodyNode).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base) && base !== \"useContext\") {\n hookedCalls.add(base);\n }\n });\n\n if (hookedCalls.size === 0) {\n return Array.from(contextNames).sort();\n }\n\n // Step 3: resolve imports for those hooks\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n // Only follow relative imports (local files)\n if (!specifier.startsWith(\".\")) continue;\n\n const namedImports = importDecl.getNamedImports();\n for (const ni of namedImports) {\n const hookName = ni.getName();\n if (!hookedCalls.has(hookName)) continue;\n\n // Resolve this hook's contexts\n const resolved = resolveHookContexts(hookName, sourceFile, specifier, project);\n for (const ctx of resolved) {\n contextNames.add(ctx);\n }\n }\n }\n\n return Array.from(contextNames).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 4. Side-effect detection\n// ---------------------------------------------------------------------------\n\n/** Callee patterns for data fetching. */\nconst FETCH_PATTERNS = [\n /^fetch$/,\n /^axios(\\.[a-zA-Z]+)?$/,\n /^useQuery$/,\n /^useMutation$/,\n /^useSWR$/,\n /^useInfiniteQuery$/,\n /^request$/,\n];\n\n/** Callee patterns for timers. */\nconst TIMER_PATTERNS = [\n /^setTimeout$/,\n /^setInterval$/,\n /^requestAnimationFrame$/,\n /^clearTimeout$/,\n /^clearInterval$/,\n /^cancelAnimationFrame$/,\n];\n\n/** Callee patterns for subscriptions (non-global). */\nconst SUBSCRIPTION_PATTERNS = [\n /\\.subscribe$/,\n /\\.onSnapshot$/,\n /\\.on$/,\n /\\.listen$/,\n /\\.addListener$/,\n];\n\n/** Window/document addEventListener patterns. */\nconst GLOBAL_LISTENER_PATTERNS = [\n /^window\\.addEventListener$/,\n /^document\\.addEventListener$/,\n /^window\\.removeEventListener$/,\n /^document\\.removeEventListener$/,\n];\n\n/** Naked addEventListener — could be element or global, treat conservatively. */\nconst BARE_ADD_EVENT_LISTENER = /^addEventListener$/;\n\nfunction matchesAny(text: string, patterns: RegExp[]): boolean {\n return patterns.some((p) => p.test(text));\n}\n\n/**\n * Detect side effects within a component body.\n *\n * Scans all CallExpression nodes recursively, including those inside\n * useEffect / useCallback / event handlers.\n */\nexport function detectSideEffects(root: Node): SideEffects {\n const fetches = new Set<string>();\n let timers = false;\n const subscriptions = new Set<string>();\n let globalListeners = false;\n\n for (const callExpr of collectCallExpressions(root)) {\n const callee = calleeText(callExpr);\n\n if (matchesAny(callee, FETCH_PATTERNS)) {\n const name = callee.split(\".\")[0] ?? callee;\n fetches.add(name);\n continue;\n }\n\n if (matchesAny(callee, TIMER_PATTERNS)) {\n timers = true;\n continue;\n }\n\n if (matchesAny(callee, GLOBAL_LISTENER_PATTERNS)) {\n globalListeners = true;\n continue;\n }\n\n if (matchesAny(callee, SUBSCRIPTION_PATTERNS)) {\n // Extract the subscription method name (last segment)\n const parts = callee.split(\".\");\n const method = parts[parts.length - 1] ?? callee;\n subscriptions.add(method);\n continue;\n }\n\n // Bare addEventListener that's not clearly on window/document\n // Check if parent is a member access on window/document\n if (BARE_ADD_EVENT_LISTENER.test(callee)) {\n globalListeners = true;\n }\n }\n\n // Also scan for `window.` / `document.` property accesses that indicate event listener patterns\n root.forEachDescendant((n) => {\n if (Node.isPropertyAccessExpression(n)) {\n const text = n.getText();\n if (\n (text.startsWith(\"window.\") || text.startsWith(\"document.\")) &&\n (text.endsWith(\"addEventListener\") || text.endsWith(\"removeEventListener\"))\n ) {\n globalListeners = true;\n }\n }\n });\n\n return {\n fetches: Array.from(fetches).sort(),\n timers,\n subscriptions: Array.from(subscriptions).sort(),\n globalListeners,\n };\n}\n\n// ---------------------------------------------------------------------------\n// 5. Complexity propagation through composition tree\n// ---------------------------------------------------------------------------\n\n/**\n * Propagate `complexityClass` upward through the composition tree.\n *\n * A component is `simple` only if it AND every descendant in its `composes`\n * tree are also `simple`. If any child anywhere in the subtree is `complex`,\n * all ancestors must also be marked `complex`.\n *\n * Algorithm: bottom-up BFS from every component that is already `complex`.\n * For each complex component, follow the `composedBy` chain upward and mark\n * each ancestor as `complex`. A visited set prevents infinite loops on\n * hypothetical cycles.\n *\n * **Must be called after:**\n * 1. All components have received their initial `complexityClass` from `analyzeComplexity`.\n * 2. The `composedBy` inverse relationships have been populated.\n *\n * Mutates `components` in place — no return value needed.\n */\nexport function propagateComplexity(\n components: Record<string, { complexityClass: ComplexityClass; composedBy: string[] }>,\n): void {\n // Seed the queue with all currently-complex components.\n const queue: string[] = [];\n for (const [name, desc] of Object.entries(components)) {\n if (desc.complexityClass === \"complex\") {\n queue.push(name);\n }\n }\n\n // BFS upward — visited tracks names we have already enqueued to avoid\n // re-processing (handles cycles and diamond dependencies).\n const visited = new Set<string>(queue);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const desc = components[current];\n if (!desc) continue;\n\n for (const parentName of desc.composedBy) {\n const parent = components[parentName];\n if (!parent) continue;\n\n // Mark the parent as complex regardless of its prior classification.\n parent.complexityClass = \"complex\";\n\n // Only enqueue if we haven't visited it yet (avoids cycles / re-work).\n if (!visited.has(parentName)) {\n visited.add(parentName);\n queue.push(parentName);\n }\n }\n }\n}\n","import { existsSync } from \"node:fs\";\n/**\n * Core AST parser for @agent-scope/manifest.\n *\n * Uses ts-morph to traverse TypeScript/TSX source files and extract:\n * - React component declarations (function, arrow, class)\n * - Props interfaces / type aliases with full type resolution\n * - Union type expansion to literal values\n * - React.memo / React.forwardRef / HOC wrapper detection\n * - JSX composition tree (which components render which)\n * - Complexity classification (complexityClass)\n * - Required context detection (requiredContexts)\n * - Hook detection (detectedHooks)\n * - Side-effect tracking (sideEffects)\n */\n\nimport { join, relative } from \"node:path\";\nimport {\n type ClassDeclaration,\n type ExportAssignment,\n type FunctionDeclaration,\n type Identifier,\n Node,\n Project,\n type SourceFile,\n type Type,\n type VariableDeclaration,\n} from \"ts-morph\";\nimport {\n analyzeComplexity,\n detectHooks,\n detectRequiredContexts,\n detectSideEffects,\n propagateComplexity,\n} from \"./analysis.js\";\nimport type {\n ComponentDescriptor,\n ExportType,\n Manifest,\n ManifestConfig,\n PropDescriptor,\n PropKind,\n ScopeFileMeta,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isReactNode(typeName: string): boolean {\n return [\n \"ReactNode\",\n \"ReactElement\",\n \"JSX.Element\",\n \"React.ReactNode\",\n \"React.ReactElement\",\n ].includes(typeName);\n}\n\nfunction resolvePropKind(type: Type): PropKind {\n if (type.isString() || type.isStringLiteral()) return \"string\";\n if (type.isNumber() || type.isNumberLiteral()) return \"number\";\n if (type.isBoolean() || type.isBooleanLiteral()) return \"boolean\";\n if (type.isNull()) return \"null\";\n if (type.isUndefined()) return \"undefined\";\n if (type.isNever()) return \"never\";\n if (type.isAny()) return \"any\";\n if (type.isUnknown()) return \"unknown\";\n if (type.isArray()) return \"array\";\n if (type.isTuple()) return \"array\";\n\n const typeText = type.getText();\n if (isReactNode(typeText)) return \"node\";\n if (type.isUnion()) return \"union\";\n if (typeText.includes(\"=>\") || typeText.startsWith(\"(\")) return \"function\";\n if (type.isObject()) return \"object\";\n return \"other\";\n}\n\n/**\n * For a union type, attempt to extract string/number literal member values.\n */\nfunction expandUnionValues(type: Type): string[] | undefined {\n if (!type.isUnion()) return undefined;\n const values: string[] = [];\n for (const member of type.getUnionTypes()) {\n if (member.isStringLiteral()) {\n values.push(member.getLiteralValue() as string);\n } else if (member.isNumberLiteral()) {\n values.push(String(member.getLiteralValue()));\n } else if (member.isBooleanLiteral()) {\n // In ts-morph v25, getLiteralValue() may return undefined for bool literals\n // getText() reliably returns \"true\" or \"false\"\n const boolText = member.getText();\n if (boolText === \"true\" || boolText === \"false\") {\n values.push(boolText);\n }\n }\n // Skip non-literal union members (e.g. string | null | undefined)\n }\n return values.length > 0 ? values : undefined;\n}\n\n/**\n * Build a PropDescriptor from a ts-morph Type + optional default value source.\n */\nfunction buildPropDescriptor(type: Type, required: boolean, defaultValue?: string): PropDescriptor {\n const kind = resolvePropKind(type);\n const desc: PropDescriptor = {\n type: kind,\n required,\n rawType: type.getText().replace(/import\\(\"[^\"]*\"\\)\\./g, \"\"),\n };\n if (kind === \"union\") {\n const expanded = expandUnionValues(type);\n if (expanded) desc.values = expanded;\n }\n if (defaultValue !== undefined) {\n desc.default = defaultValue;\n // A prop with a default is effectively optional at the call site\n desc.required = false;\n }\n return desc;\n}\n\n// ---------------------------------------------------------------------------\n// Props extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract props from a TypeScript interface or type alias node.\n * Returns Record<propName, PropDescriptor>.\n */\nfunction extractPropsFromType(\n typeName: string,\n sourceFile: SourceFile,\n defaultValues: Record<string, string> = {},\n): Record<string, PropDescriptor> {\n const props: Record<string, PropDescriptor> = {};\n\n // Try interface first\n const iface = sourceFile.getInterface(typeName);\n if (iface) {\n for (const prop of iface.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue; // skip index signatures\n const type = prop.getType();\n const required = !prop.hasQuestionToken();\n props[name] = buildPropDescriptor(type, required, defaultValues[name]);\n }\n return props;\n }\n\n // Try type alias\n const typeAlias = sourceFile.getTypeAlias(typeName);\n if (typeAlias) {\n const aliasType = typeAlias.getType();\n if (aliasType.isObject()) {\n for (const prop of aliasType.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue;\n const decls = prop.getDeclarations();\n const required =\n decls.length === 0 ||\n !prop.getDeclarations().some((d) => Node.isPropertySignature(d) && d.hasQuestionToken());\n const valType = prop.getTypeAtLocation(sourceFile);\n props[name] = buildPropDescriptor(valType, required, defaultValues[name]);\n }\n }\n return props;\n }\n\n return props;\n}\n\n/**\n * Try to infer the props type name from a function's parameter destructuring.\n * E.g. `function Foo({ bar }: FooProps)` → \"FooProps\"\n */\nfunction inferPropsTypeName(params: { getTypeNode(): Node | undefined }[]): string | undefined {\n if (params.length === 0) return undefined;\n const firstParam = params[0];\n if (!firstParam) return undefined;\n const typeNode = firstParam.getTypeNode?.();\n if (!typeNode) return undefined;\n return typeNode.getText().trim();\n}\n\n/**\n * Extract default values from destructured parameters.\n * E.g. `function Foo({ variant = 'primary', size = 'md' }: FooProps)` → { variant: 'primary', size: 'md' }\n */\nfunction extractDefaultsFromDestructuring(\n params: ReturnType<FunctionDeclaration[\"getParameters\"]>,\n): Record<string, string> {\n const defaults: Record<string, string> = {};\n if (params.length === 0) return defaults;\n const firstParam = params[0];\n if (!firstParam) return defaults;\n\n const nameNode = firstParam.getNameNode();\n if (!Node.isObjectBindingPattern(nameNode)) return defaults;\n\n for (const element of nameNode.getElements()) {\n const initializer = element.getInitializer();\n if (initializer) {\n const propName = element.getPropertyNameNode()?.getText() ?? element.getName();\n defaults[propName] = initializer.getText();\n }\n }\n return defaults;\n}\n\n// ---------------------------------------------------------------------------\n// JSX composition extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Collect all JSX element tag names used inside a node.\n * Returns only PascalCase names (component references, not host elements).\n */\nfunction collectJsxCompositions(node: Node): string[] {\n const names = new Set<string>();\n\n function visit(n: Node): void {\n if (Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n)) {\n const tagNameNode = n.getTagNameNode();\n const tagName = tagNameNode.getText();\n // Only capture PascalCase = React components (not div, span, etc.)\n if (/^[A-Z]/.test(tagName)) {\n // Strip member access – e.g. React.Fragment → skip; Context.Provider → skip\n const base = tagName.split(\".\")[0] ?? tagName;\n if (base && /^[A-Z]/.test(base) && ![\"React\", \"Fragment\"].includes(base)) {\n names.add(base);\n }\n }\n }\n n.forEachChild(visit);\n }\n\n visit(node);\n return Array.from(names);\n}\n\n// ---------------------------------------------------------------------------\n// HOC / wrapper detection\n// ---------------------------------------------------------------------------\n\ninterface WrapperInfo {\n memoized: boolean;\n forwardedRef: boolean;\n hocWrappers: string[];\n}\n\n/**\n * Detect React.memo, React.forwardRef, and arbitrary HOC wrappers on a call expression.\n */\nfunction detectWrappers(node: Node): WrapperInfo {\n let memoized = false;\n let forwardedRef = false;\n const hocWrappers: string[] = [];\n\n function visitCall(n: Node): void {\n if (!Node.isCallExpression(n)) return;\n const expr = n.getExpression();\n const name = expr.getText();\n\n if (name === \"React.memo\" || name === \"memo\") {\n memoized = true;\n // Recurse into the inner arg (it might also be forwardRef)\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else if (name === \"React.forwardRef\" || name === \"forwardRef\") {\n forwardedRef = true;\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else {\n // Generic HOC: something(Component)\n const args = n.getArguments();\n if (args.length > 0) {\n const firstArg = args[0];\n if (firstArg && (Node.isIdentifier(firstArg) || Node.isCallExpression(firstArg))) {\n // Treat outer call name as an HOC wrapper\n const calleeName = name.split(\".\").pop() ?? name;\n if (/^[a-z]/.test(calleeName)) {\n hocWrappers.push(calleeName);\n }\n if (Node.isCallExpression(firstArg)) {\n visitCall(firstArg);\n }\n }\n }\n }\n }\n\n visitCall(node);\n return { memoized, forwardedRef, hocWrappers };\n}\n\n// ---------------------------------------------------------------------------\n// Component name resolution for wrapped components\n// ---------------------------------------------------------------------------\n\n/**\n * Given a call expression like `React.memo(function Foo() {...})`, extract the inner name.\n */\nfunction extractNameFromWrappedCall(node: Node): string | undefined {\n if (!Node.isCallExpression(node)) return undefined;\n const args = node.getArguments();\n if (args.length === 0) return undefined;\n\n const firstArg = args[0];\n if (!firstArg) return undefined;\n\n // memo(function Foo() {...})\n if (Node.isFunctionExpression(firstArg)) {\n return firstArg.getName() ?? undefined;\n }\n // memo(Foo) where Foo is an identifier\n if (Node.isIdentifier(firstArg)) {\n return firstArg.getText();\n }\n // memo(forwardRef(function Foo() {...}))\n if (Node.isCallExpression(firstArg)) {\n return extractNameFromWrappedCall(firstArg);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Returns-JSX detection\n// ---------------------------------------------------------------------------\n\nfunction nodeReturnsJsx(node: Node): boolean {\n let found = false;\n function visit(n: Node): void {\n if (found) return;\n if (Node.isJsxElement(n) || Node.isJsxFragment(n) || Node.isJsxSelfClosingElement(n)) {\n found = true;\n return;\n }\n n.forEachChild(visit);\n }\n visit(node);\n return found;\n}\n\n// ---------------------------------------------------------------------------\n// Per-file component extraction\n// ---------------------------------------------------------------------------\n\ninterface RawComponent {\n name: string;\n descriptor: ComponentDescriptor;\n}\n\nfunction processSourceFile(\n sourceFile: SourceFile,\n rootDir: string,\n project: Project,\n): RawComponent[] {\n const results: RawComponent[] = [];\n const filePath = relative(rootDir, sourceFile.getFilePath());\n\n // Collect default export assignment target name (e.g. `export default Foo`)\n // Also handle wrapped defaults: `export default React.memo(Foo)` or `export default React.forwardRef(Foo)`\n let defaultExportName: string | undefined;\n const defaultExportWrappers = new Map<string, WrapperInfo>();\n sourceFile.forEachChild((node) => {\n if (Node.isExportAssignment(node)) {\n const expr = (node as ExportAssignment).getExpression();\n if (Node.isIdentifier(expr)) {\n defaultExportName = (expr as Identifier).getText();\n } else if (Node.isCallExpression(expr)) {\n // e.g. `export default React.memo(Sidebar)` or `export default React.forwardRef(Btn)`\n const innerName = extractNameFromWrappedCall(expr);\n if (innerName) {\n defaultExportName = innerName;\n defaultExportWrappers.set(innerName, detectWrappers(expr));\n }\n }\n }\n });\n\n // Named exports map: variable name → export type\n const namedExports = new Set<string>();\n for (const exportDecl of sourceFile.getExportSymbols()) {\n namedExports.add(exportDecl.getName());\n }\n\n // -------------------------------------------------------------------------\n // 1. Function declarations\n // -------------------------------------------------------------------------\n for (const fn of sourceFile.getFunctions()) {\n const name = fn.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n if (!nodeReturnsJsx(fn)) continue;\n\n const params = fn.getParameters();\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(fn);\n const start = fn.getStartLineNumber();\n const end = fn.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (fn.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (fn.isExported() || namedExports.has(name)) exportType = \"named\";\n\n const fnWrappers = defaultExportWrappers.get(name) ?? {\n memoized: false,\n forwardedRef: false,\n hocWrappers: [],\n };\n\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: fnWrappers.forwardedRef,\n hocWrappers: fnWrappers.hocWrappers,\n memoized: fnWrappers.memoized,\n loc: { start, end },\n complexityClass: analyzeComplexity(fn),\n detectedHooks: detectHooks(fn),\n requiredContexts: detectRequiredContexts(fn, sourceFile, project),\n sideEffects: detectSideEffects(fn),\n scopeFile: null,\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // 2. Variable declarations (arrow functions, React.memo, React.forwardRef)\n // -------------------------------------------------------------------------\n for (const varStmt of sourceFile.getVariableStatements()) {\n const isExported = varStmt.isExported();\n for (const varDecl of varStmt.getDeclarations()) {\n const varName = (varDecl as VariableDeclaration).getName();\n if (!/^[A-Z]/.test(varName)) continue;\n\n const initializer = (varDecl as VariableDeclaration).getInitializer();\n if (!initializer) continue;\n\n // Detect wrappers on the whole expression\n const wrappers = detectWrappers(initializer);\n let innerName: string | undefined;\n let bodyNode: Node = initializer;\n\n if (Node.isCallExpression(initializer)) {\n innerName = extractNameFromWrappedCall(initializer);\n // Drill into the innermost function for props / JSX\n const args = initializer.getArguments();\n const firstArg = args[0];\n if (firstArg) {\n if (Node.isArrowFunction(firstArg) || Node.isFunctionExpression(firstArg)) {\n bodyNode = firstArg;\n } else if (Node.isCallExpression(firstArg)) {\n // e.g. memo(forwardRef(fn))\n const innerArgs = firstArg.getArguments();\n const innerFirst = innerArgs[0];\n if (\n innerFirst &&\n (Node.isArrowFunction(innerFirst) || Node.isFunctionExpression(innerFirst))\n ) {\n bodyNode = innerFirst;\n }\n }\n }\n }\n\n // Must return JSX somewhere in the body\n if (!nodeReturnsJsx(bodyNode)) continue;\n\n // For named inner functions we use innerName; fall back to varName\n const componentName = innerName ?? varName;\n\n let params: ReturnType<FunctionDeclaration[\"getParameters\"]> = [];\n if (Node.isArrowFunction(bodyNode) || Node.isFunctionExpression(bodyNode)) {\n params = bodyNode.getParameters();\n }\n\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(bodyNode);\n const startLine = (varDecl as VariableDeclaration).getStartLineNumber();\n const endLine = (varDecl as VariableDeclaration).getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (defaultExportName === varName || defaultExportName === componentName) {\n exportType = \"default\";\n } else if (isExported || namedExports.has(varName)) {\n exportType = \"named\";\n }\n\n results.push({\n name: componentName === varName ? componentName : varName,\n descriptor: {\n filePath,\n exportType,\n displayName: componentName,\n props,\n composes,\n composedBy: [],\n forwardedRef: wrappers.forwardedRef,\n hocWrappers: wrappers.hocWrappers,\n memoized: wrappers.memoized,\n loc: { start: startLine, end: endLine },\n complexityClass: analyzeComplexity(bodyNode),\n detectedHooks: detectHooks(bodyNode),\n requiredContexts: detectRequiredContexts(bodyNode, sourceFile, project),\n sideEffects: detectSideEffects(bodyNode),\n scopeFile: null,\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // 3. Class components\n // -------------------------------------------------------------------------\n for (const cls of sourceFile.getClasses()) {\n const name = cls.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n\n // Must extend React.Component or React.PureComponent\n const baseClass = (cls as ClassDeclaration).getBaseClass()?.getName();\n if (!baseClass && !(cls as ClassDeclaration).getExtends()) continue;\n const extendsText = (cls as ClassDeclaration).getExtends()?.getText() ?? \"\";\n if (!extendsText.includes(\"Component\") && !extendsText.includes(\"PureComponent\")) {\n continue;\n }\n\n // Render method must return JSX\n const renderMethod = cls.getMethod(\"render\");\n if (!renderMethod || !nodeReturnsJsx(renderMethod)) continue;\n\n // Extract first type argument as props type\n const extendsNode = (cls as ClassDeclaration).getExtends();\n let propsTypeName: string | undefined;\n if (extendsNode) {\n const typeArgs = extendsNode.getTypeArguments();\n if (typeArgs[0]) {\n propsTypeName = typeArgs[0].getText().trim();\n }\n }\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile) : {};\n\n const composes = collectJsxCompositions(renderMethod);\n const start = cls.getStartLineNumber();\n const end = cls.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (cls.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (cls.isExported() || namedExports.has(name)) exportType = \"named\";\n\n // Class components: default to \"complex\" (they often use lifecycle methods / state)\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: false,\n hocWrappers: [],\n memoized: false,\n loc: { start, end },\n complexityClass: \"complex\",\n detectedHooks: [],\n requiredContexts: [],\n sideEffects: detectSideEffects(cls),\n scopeFile: null,\n },\n });\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a component manifest by parsing all matching TypeScript/TSX files.\n */\nexport function generateManifest(config: ManifestConfig): Manifest {\n const {\n rootDir,\n include = [\"src/**/*.tsx\", \"src/**/*.ts\"],\n exclude = [\"**/node_modules/**\", \"**/*.test.*\", \"**/*.spec.*\", \"**/dist/**\", \"**/*.d.ts\"],\n tsConfigFilePath = join(rootDir, \"tsconfig.json\"),\n } = config;\n\n const project = new Project({\n tsConfigFilePath,\n skipAddingFilesFromTsConfig: true,\n });\n\n // Add source files via glob\n const includePatterns = include.map((g) => join(rootDir, g));\n project.addSourceFilesFromTsConfig(tsConfigFilePath);\n\n // If tsconfig doesn't cover the files, add them directly\n for (const pattern of includePatterns) {\n project.addSourceFilesAtPaths(pattern);\n }\n\n // Remove excluded files\n for (const sf of project.getSourceFiles()) {\n const fp = sf.getFilePath();\n const shouldExclude = exclude.some((ex) => {\n const pattern = ex.replace(/\\*\\*/g, \".*\").replace(/\\*/g, \"[^/]*\").replace(/\\./g, \"\\\\.\");\n return new RegExp(pattern).test(fp);\n });\n if (shouldExclude) {\n project.removeSourceFile(sf);\n }\n }\n\n // Also filter to only files within rootDir\n for (const sf of project.getSourceFiles()) {\n if (!sf.getFilePath().startsWith(rootDir)) {\n project.removeSourceFile(sf);\n }\n }\n\n // Collect all components\n const allComponents: Record<string, ComponentDescriptor> = {};\n\n for (const sf of project.getSourceFiles()) {\n const rawComponents = processSourceFile(sf, rootDir, project);\n for (const { name, descriptor } of rawComponents) {\n // If duplicate name, prefer the exported one\n if (allComponents[name] && descriptor.exportType === \"none\") continue;\n allComponents[name] = descriptor;\n }\n }\n\n // Build composition inverse: composedBy\n for (const [name, desc] of Object.entries(allComponents)) {\n for (const child of desc.composes) {\n if (allComponents[child]) {\n const childDesc = allComponents[child];\n if (childDesc && !childDesc.composedBy.includes(name)) {\n childDesc.composedBy.push(name);\n }\n }\n }\n }\n\n // Propagate complexityClass upward through the composition tree.\n // A component is only `simple` if it AND every descendant are simple.\n // This must run after composedBy is fully populated.\n propagateComplexity(allComponents);\n\n // Build tree\n const tree: Manifest[\"tree\"] = {};\n for (const [name, desc] of Object.entries(allComponents)) {\n // Only include children that exist in the manifest\n const children = desc.composes.filter((c) => c in allComponents);\n const parents = desc.composedBy.filter((p) => p in allComponents);\n tree[name] = { children, parents };\n }\n\n // Attach scope file metadata to each component (static presence check only)\n for (const desc of Object.values(allComponents)) {\n const scopeMeta = detectScopeFile(desc.filePath, config.rootDir);\n if (scopeMeta !== null) {\n desc.scopeFile = scopeMeta;\n }\n }\n\n return {\n version: \"0.1\",\n generatedAt: new Date().toISOString(),\n components: allComponents,\n tree,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Scope file detection (static — presence check only, no bundling)\n// ---------------------------------------------------------------------------\n\nconst SCOPE_EXTENSIONS = [\".scope.tsx\", \".scope.ts\", \".scope.jsx\", \".scope.js\"];\n\n/**\n * Check whether a scope file exists next to the component file.\n * Returns minimal ScopeFileMeta if found, null otherwise.\n *\n * scenarioNames and hasWrapper are left empty here — they are populated at\n * render time when loadScopeFile() actually bundles and evaluates the file.\n */\nfunction detectScopeFile(componentFilePath: string, rootDir: string): ScopeFileMeta | null {\n const absPath = componentFilePath.startsWith(\"/\")\n ? componentFilePath\n : join(rootDir, componentFilePath);\n\n const stem = absPath.replace(/\\.(tsx?|jsx?)$/, \"\");\n for (const ext of SCOPE_EXTENSIONS) {\n const candidate = `${stem}${ext}`;\n if (existsSync(candidate)) {\n return { filePath: candidate, scenarioNames: [], hasWrapper: false };\n }\n }\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/analysis.ts","../src/parser.ts"],"names":["Node"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Phase 6 analysis functions for @agent-scope/manifest.\n *\n * This module is responsible for:\n * 1. Complexity classification (`complexityClass`)\n * 2. Required context detection (`requiredContexts`)\n * 3. Hook detection (`detectedHooks`)\n * 4. Side-effect tracking (`sideEffects`)\n *\n * All functions accept ts-morph `Node` / `SourceFile` / `Project` values and\n * return plain data — no mutations to the AST.\n */\n\nimport { Node, type Project, type SourceFile } from \"ts-morph\";\nimport type { ComplexityClass, SideEffects } from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\n/** Collect all CallExpression nodes beneath a node (inclusive). */\nfunction collectCallExpressions(root: Node): Node[] {\n const results: Node[] = [];\n root.forEachDescendant((n) => {\n if (Node.isCallExpression(n)) {\n results.push(n);\n }\n });\n return results;\n}\n\n/** Return the callee string for a CallExpression node (e.g. \"window.addEventListener\"). */\nfunction calleeText(callExpr: Node): string {\n if (!Node.isCallExpression(callExpr)) return \"\";\n return callExpr.getExpression().getText().trim();\n}\n\n// ---------------------------------------------------------------------------\n// 1. Complexity classification\n// ---------------------------------------------------------------------------\n\n/**\n * CSS property names / values that force `complex` classification.\n * Any inline-style key matching this set triggers complexity.\n */\nconst COMPLEX_STYLE_KEYS = new Set([\n \"position\",\n \"gridTemplate\",\n \"gridTemplateColumns\",\n \"gridTemplateRows\",\n \"gridArea\",\n \"gridColumn\",\n \"gridRow\",\n \"grid\",\n \"animation\",\n \"animationName\",\n \"animationDuration\",\n \"transition\",\n \"transform\",\n \"transformOrigin\",\n \"clip\",\n \"clipPath\",\n \"willChange\",\n \"contain\",\n]);\n\n/**\n * Inline-style *value* fragments that imply complex layout even when the key\n * is safe (e.g. `position: \"absolute\"`).\n */\nconst COMPLEX_POSITION_VALUES = new Set([\"absolute\", \"fixed\", \"sticky\"]);\n\n/**\n * CSS properties that begin with these prefixes are complex\n * (e.g. \"gridTemplateAreas\").\n */\nconst COMPLEX_KEY_PREFIXES = [\"grid\", \"animation\", \"transition\"];\n\nfunction isComplexStyleKey(key: string): boolean {\n if (COMPLEX_STYLE_KEYS.has(key)) return true;\n return COMPLEX_KEY_PREFIXES.some((p) => key.startsWith(p));\n}\n\n/**\n * Scan JSX attribute `style={{ ... }}` inline-object expressions for complex\n * CSS properties. Returns true if any complex property is detected.\n */\nfunction hasCssComplexity(root: Node): boolean {\n let complex = false;\n\n root.forEachDescendant((n) => {\n if (complex) return;\n\n // --- Inline style object: style={{ position: \"absolute\", ... }} ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"style\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // style={{ ... }} → JsxExpression wrapping an ObjectLiteralExpression\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n if (!inner || !Node.isObjectLiteralExpression(inner)) return;\n\n for (const prop of inner.getProperties()) {\n if (complex) break;\n if (!Node.isPropertyAssignment(prop) && !Node.isShorthandPropertyAssignment(prop)) {\n continue;\n }\n\n const keyText = prop.getNameNode().getText();\n\n if (isComplexStyleKey(keyText)) {\n complex = true;\n break;\n }\n\n // Check value for position: \"absolute\" | \"fixed\" | \"sticky\"\n if (keyText === \"position\" && Node.isPropertyAssignment(prop)) {\n const val = prop.getInitializer();\n if (val) {\n const raw = val.getText().replace(/['\"]/g, \"\").trim().toLowerCase();\n if (COMPLEX_POSITION_VALUES.has(raw)) {\n complex = true;\n break;\n }\n }\n }\n }\n }\n return;\n }\n\n // --- Styled-components / css template literals ---\n // These are too opaque to analyze reliably; treat as complex\n if (Node.isTaggedTemplateExpression(n)) {\n const tag = n.getTag().getText();\n // styled.div`...`, styled(Component)`...`, css`...`\n if (tag.startsWith(\"styled\") || tag === \"css\" || tag === \"keyframes\") {\n complex = true;\n }\n return;\n }\n\n // --- className with a non-trivial expression → can't analyze, default complex ---\n if (Node.isJsxAttribute(n)) {\n const nameNode = n.getNameNode();\n if (nameNode.getText() !== \"className\") return;\n\n const initializer = n.getInitializer();\n if (!initializer) return;\n\n // className=\"literal\" is fine; className={expr} is opaque\n if (Node.isJsxExpression(initializer)) {\n const inner = initializer.getExpression();\n // Allow simple string concatenation / template literals - skip\n // Identifiers / call expressions pointing to CSS modules → complex\n if (\n inner &&\n (Node.isIdentifier(inner) ||\n Node.isCallExpression(inner) ||\n Node.isPropertyAccessExpression(inner))\n ) {\n complex = true;\n }\n }\n }\n });\n\n return complex;\n}\n\n/**\n * Classify a component body as `\"simple\"` or `\"complex\"`.\n *\n * Rule: any use of complex CSS properties (grid, absolute/fixed/sticky\n * positioning, animations, transforms, transitions) OR styled-components\n * OR opaque className references → `\"complex\"`.\n *\n * Default is `\"simple\"` when nothing complex is detected.\n * Callers should pass `\"complex\"` as the safe fallback for class components\n * or other patterns where analysis is not possible.\n */\nexport function analyzeComplexity(bodyNode: Node): ComplexityClass {\n return hasCssComplexity(bodyNode) ? \"complex\" : \"simple\";\n}\n\n// ---------------------------------------------------------------------------\n// 2. Hook detection\n// ---------------------------------------------------------------------------\n\nconst HOOK_REGEX = /^use[A-Z]/;\n\n/**\n * Collect all hook calls within a node.\n * A \"hook\" is any call expression whose callee matches /^use[A-Z]/.\n *\n * Returns a de-duplicated, sorted array of hook names.\n */\nexport function detectHooks(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n // Only the base name — drop member access (e.g. React.useState → useState)\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base)) {\n names.add(base);\n }\n });\n\n return Array.from(names).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 3. Required context detection\n// ---------------------------------------------------------------------------\n\n/**\n * Map from callee text → context variable name patterns.\n * We look for `useContext(SomeCtx)` patterns.\n */\nfunction extractDirectContextNames(root: Node): string[] {\n const names = new Set<string>();\n\n collectCallExpressions(root).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (base !== \"useContext\") return;\n\n const args = (Node.isCallExpression(callExpr) ? callExpr : null)?.getArguments() ?? [];\n const firstArg = args[0];\n if (!firstArg) return;\n\n // useContext(ThemeCtx) → \"ThemeCtx\"\n const argText = firstArg.getText().trim();\n if (argText) {\n names.add(argText);\n }\n });\n\n return Array.from(names);\n}\n\n/**\n * Given a custom hook name imported from a specifier, resolve its source file\n * and extract any `useContext(...)` calls it makes.\n *\n * Returns context variable names, e.g. [\"ThemeCtx\", \"AuthCtx\"].\n */\nfunction resolveHookContexts(\n hookName: string,\n importingFile: SourceFile,\n importSpecifier: string,\n project: Project,\n): string[] {\n // Attempt to resolve via ts-morph project\n const allFiles = project.getSourceFiles();\n const importingDir = importingFile.getDirectoryPath();\n\n // Build candidate paths for the specifier\n const specParts = importSpecifier.replace(/^\\.\\.?\\//, \"\");\n const candidates = allFiles.filter((sf) => {\n const fp = sf.getFilePath();\n // Must be relative to the same directory tree\n if (!fp.startsWith(importingDir.split(\"/src/\")[0] ?? importingDir)) return false;\n const basename = fp.split(\"/\").pop() ?? \"\";\n const specBase = specParts.split(\"/\").pop() ?? specParts;\n return (\n basename === `${specBase}.ts` ||\n basename === `${specBase}.tsx` ||\n basename === `${specBase}.js` ||\n basename === `${specBase}.jsx` ||\n fp.endsWith(`${specParts}.ts`) ||\n fp.endsWith(`${specParts}.tsx`) ||\n fp.endsWith(`${importSpecifier}.ts`) ||\n fp.endsWith(`${importSpecifier}.tsx`)\n );\n });\n\n for (const candidate of candidates) {\n // Find the hook function in this file\n const hookFunctions = [\n ...candidate.getFunctions().filter((f) => f.getName() === hookName),\n ...candidate.getVariableDeclarations().filter((v) => v.getName() === hookName),\n ];\n\n for (const fn of hookFunctions) {\n const ctxNames = extractDirectContextNames(fn);\n if (ctxNames.length > 0) return ctxNames;\n }\n\n // Also try arrow functions assigned to const hookName = () => ...\n // (already covered by getVariableDeclarations above)\n }\n\n return [];\n}\n\n/**\n * Detect all React context identifiers required by a component.\n *\n * Algorithm:\n * 1. Scan the component body for direct `useContext(X)` calls.\n * 2. Find all `import { useXxx } from './...'` statements.\n * 3. For each imported custom hook (matching /^use[A-Z]/), resolve its\n * source file and scan it for `useContext()` calls.\n * 4. Merge and de-duplicate.\n *\n * Returns a sorted array of context variable names.\n */\nexport function detectRequiredContexts(\n bodyNode: Node,\n sourceFile: SourceFile,\n project: Project,\n): string[] {\n const contextNames = new Set<string>();\n\n // Step 1: direct useContext() in component body\n for (const name of extractDirectContextNames(bodyNode)) {\n contextNames.add(name);\n }\n\n // Step 2: find imported hooks used in this component body\n const hookedCalls = new Set<string>();\n collectCallExpressions(bodyNode).forEach((callExpr) => {\n const callee = calleeText(callExpr);\n const base = callee.split(\".\").pop() ?? callee;\n if (HOOK_REGEX.test(base) && base !== \"useContext\") {\n hookedCalls.add(base);\n }\n });\n\n if (hookedCalls.size === 0) {\n return Array.from(contextNames).sort();\n }\n\n // Step 3: resolve imports for those hooks\n for (const importDecl of sourceFile.getImportDeclarations()) {\n const specifier = importDecl.getModuleSpecifierValue();\n // Only follow relative imports (local files)\n if (!specifier.startsWith(\".\")) continue;\n\n const namedImports = importDecl.getNamedImports();\n for (const ni of namedImports) {\n const hookName = ni.getName();\n if (!hookedCalls.has(hookName)) continue;\n\n // Resolve this hook's contexts\n const resolved = resolveHookContexts(hookName, sourceFile, specifier, project);\n for (const ctx of resolved) {\n contextNames.add(ctx);\n }\n }\n }\n\n return Array.from(contextNames).sort();\n}\n\n// ---------------------------------------------------------------------------\n// 4. Side-effect detection\n// ---------------------------------------------------------------------------\n\n/** Callee patterns for data fetching. */\nconst FETCH_PATTERNS = [\n /^fetch$/,\n /^axios(\\.[a-zA-Z]+)?$/,\n /^useQuery$/,\n /^useMutation$/,\n /^useSWR$/,\n /^useInfiniteQuery$/,\n /^request$/,\n];\n\n/** Callee patterns for timers. */\nconst TIMER_PATTERNS = [\n /^setTimeout$/,\n /^setInterval$/,\n /^requestAnimationFrame$/,\n /^clearTimeout$/,\n /^clearInterval$/,\n /^cancelAnimationFrame$/,\n];\n\n/** Callee patterns for subscriptions (non-global). */\nconst SUBSCRIPTION_PATTERNS = [\n /\\.subscribe$/,\n /\\.onSnapshot$/,\n /\\.on$/,\n /\\.listen$/,\n /\\.addListener$/,\n];\n\n/** Window/document addEventListener patterns. */\nconst GLOBAL_LISTENER_PATTERNS = [\n /^window\\.addEventListener$/,\n /^document\\.addEventListener$/,\n /^window\\.removeEventListener$/,\n /^document\\.removeEventListener$/,\n];\n\n/** Naked addEventListener — could be element or global, treat conservatively. */\nconst BARE_ADD_EVENT_LISTENER = /^addEventListener$/;\n\nfunction matchesAny(text: string, patterns: RegExp[]): boolean {\n return patterns.some((p) => p.test(text));\n}\n\n/**\n * Detect side effects within a component body.\n *\n * Scans all CallExpression nodes recursively, including those inside\n * useEffect / useCallback / event handlers.\n */\nexport function detectSideEffects(root: Node): SideEffects {\n const fetches = new Set<string>();\n let timers = false;\n const subscriptions = new Set<string>();\n let globalListeners = false;\n\n for (const callExpr of collectCallExpressions(root)) {\n const callee = calleeText(callExpr);\n\n if (matchesAny(callee, FETCH_PATTERNS)) {\n const name = callee.split(\".\")[0] ?? callee;\n fetches.add(name);\n continue;\n }\n\n if (matchesAny(callee, TIMER_PATTERNS)) {\n timers = true;\n continue;\n }\n\n if (matchesAny(callee, GLOBAL_LISTENER_PATTERNS)) {\n globalListeners = true;\n continue;\n }\n\n if (matchesAny(callee, SUBSCRIPTION_PATTERNS)) {\n // Extract the subscription method name (last segment)\n const parts = callee.split(\".\");\n const method = parts[parts.length - 1] ?? callee;\n subscriptions.add(method);\n continue;\n }\n\n // Bare addEventListener that's not clearly on window/document\n // Check if parent is a member access on window/document\n if (BARE_ADD_EVENT_LISTENER.test(callee)) {\n globalListeners = true;\n }\n }\n\n // Also scan for `window.` / `document.` property accesses that indicate event listener patterns\n root.forEachDescendant((n) => {\n if (Node.isPropertyAccessExpression(n)) {\n const text = n.getText();\n if (\n (text.startsWith(\"window.\") || text.startsWith(\"document.\")) &&\n (text.endsWith(\"addEventListener\") || text.endsWith(\"removeEventListener\"))\n ) {\n globalListeners = true;\n }\n }\n });\n\n return {\n fetches: Array.from(fetches).sort(),\n timers,\n subscriptions: Array.from(subscriptions).sort(),\n globalListeners,\n };\n}\n\n// ---------------------------------------------------------------------------\n// 5. Complexity propagation through composition tree\n// ---------------------------------------------------------------------------\n\n/**\n * Propagate `complexityClass` upward through the composition tree.\n *\n * A component is `simple` only if it AND every descendant in its `composes`\n * tree are also `simple`. If any child anywhere in the subtree is `complex`,\n * all ancestors must also be marked `complex`.\n *\n * Algorithm: bottom-up BFS from every component that is already `complex`.\n * For each complex component, follow the `composedBy` chain upward and mark\n * each ancestor as `complex`. A visited set prevents infinite loops on\n * hypothetical cycles.\n *\n * **Must be called after:**\n * 1. All components have received their initial `complexityClass` from `analyzeComplexity`.\n * 2. The `composedBy` inverse relationships have been populated.\n *\n * Mutates `components` in place — no return value needed.\n */\nexport function propagateComplexity(\n components: Record<string, { complexityClass: ComplexityClass; composedBy: string[] }>,\n): void {\n // Seed the queue with all currently-complex components.\n const queue: string[] = [];\n for (const [name, desc] of Object.entries(components)) {\n if (desc.complexityClass === \"complex\") {\n queue.push(name);\n }\n }\n\n // BFS upward — visited tracks names we have already enqueued to avoid\n // re-processing (handles cycles and diamond dependencies).\n const visited = new Set<string>(queue);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const desc = components[current];\n if (!desc) continue;\n\n for (const parentName of desc.composedBy) {\n const parent = components[parentName];\n if (!parent) continue;\n\n // Mark the parent as complex regardless of its prior classification.\n parent.complexityClass = \"complex\";\n\n // Only enqueue if we haven't visited it yet (avoids cycles / re-work).\n if (!visited.has(parentName)) {\n visited.add(parentName);\n queue.push(parentName);\n }\n }\n }\n}\n","import { existsSync } from \"node:fs\";\n/**\n * Core AST parser for @agent-scope/manifest.\n *\n * Uses ts-morph to traverse TypeScript/TSX source files and extract:\n * - React component declarations (function, arrow, class)\n * - Props interfaces / type aliases with full type resolution\n * - Union type expansion to literal values\n * - React.memo / React.forwardRef / HOC wrapper detection\n * - JSX composition tree (which components render which)\n * - Complexity classification (complexityClass)\n * - Required context detection (requiredContexts)\n * - Hook detection (detectedHooks)\n * - Side-effect tracking (sideEffects)\n * - Collection and internal classification (via TSDoc, .scope.ts, config patterns)\n */\n\nimport { join, relative } from \"node:path\";\nimport {\n type ClassDeclaration,\n type ExportAssignment,\n type FunctionDeclaration,\n type Identifier,\n Node,\n Project,\n type SourceFile,\n type Type,\n type VariableDeclaration,\n} from \"ts-morph\";\nimport {\n analyzeComplexity,\n detectHooks,\n detectRequiredContexts,\n detectSideEffects,\n propagateComplexity,\n} from \"./analysis.js\";\nimport type {\n CollectionConfig,\n ComponentDescriptor,\n ExportType,\n Manifest,\n ManifestConfig,\n PropDescriptor,\n PropKind,\n ScopeFileMeta,\n} from \"./types.js\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isReactNode(typeName: string): boolean {\n return [\n \"ReactNode\",\n \"ReactElement\",\n \"JSX.Element\",\n \"React.ReactNode\",\n \"React.ReactElement\",\n ].includes(typeName);\n}\n\nfunction resolvePropKind(type: Type): PropKind {\n if (type.isString() || type.isStringLiteral()) return \"string\";\n if (type.isNumber() || type.isNumberLiteral()) return \"number\";\n if (type.isBoolean() || type.isBooleanLiteral()) return \"boolean\";\n if (type.isNull()) return \"null\";\n if (type.isUndefined()) return \"undefined\";\n if (type.isNever()) return \"never\";\n if (type.isAny()) return \"any\";\n if (type.isUnknown()) return \"unknown\";\n if (type.isArray()) return \"array\";\n if (type.isTuple()) return \"array\";\n\n const typeText = type.getText();\n if (isReactNode(typeText)) return \"node\";\n if (type.isUnion()) return \"union\";\n if (typeText.includes(\"=>\") || typeText.startsWith(\"(\")) return \"function\";\n if (type.isObject()) return \"object\";\n return \"other\";\n}\n\n/**\n * For a union type, attempt to extract string/number literal member values.\n */\nfunction expandUnionValues(type: Type): string[] | undefined {\n if (!type.isUnion()) return undefined;\n const values: string[] = [];\n for (const member of type.getUnionTypes()) {\n if (member.isStringLiteral()) {\n values.push(member.getLiteralValue() as string);\n } else if (member.isNumberLiteral()) {\n values.push(String(member.getLiteralValue()));\n } else if (member.isBooleanLiteral()) {\n // In ts-morph v25, getLiteralValue() may return undefined for bool literals\n // getText() reliably returns \"true\" or \"false\"\n const boolText = member.getText();\n if (boolText === \"true\" || boolText === \"false\") {\n values.push(boolText);\n }\n }\n // Skip non-literal union members (e.g. string | null | undefined)\n }\n return values.length > 0 ? values : undefined;\n}\n\n/**\n * Build a PropDescriptor from a ts-morph Type + optional default value source.\n */\nfunction buildPropDescriptor(type: Type, required: boolean, defaultValue?: string): PropDescriptor {\n const kind = resolvePropKind(type);\n const desc: PropDescriptor = {\n type: kind,\n required,\n rawType: type.getText().replace(/import\\(\"[^\"]*\"\\)\\./g, \"\"),\n };\n if (kind === \"union\") {\n const expanded = expandUnionValues(type);\n if (expanded) desc.values = expanded;\n }\n if (defaultValue !== undefined) {\n desc.default = defaultValue;\n // A prop with a default is effectively optional at the call site\n desc.required = false;\n }\n return desc;\n}\n\n// ---------------------------------------------------------------------------\n// Props extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract props from a TypeScript interface or type alias node.\n * Returns Record<propName, PropDescriptor>.\n */\nfunction extractPropsFromType(\n typeName: string,\n sourceFile: SourceFile,\n defaultValues: Record<string, string> = {},\n): Record<string, PropDescriptor> {\n const props: Record<string, PropDescriptor> = {};\n\n // Try interface first\n const iface = sourceFile.getInterface(typeName);\n if (iface) {\n for (const prop of iface.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue; // skip index signatures\n const type = prop.getType();\n const required = !prop.hasQuestionToken();\n props[name] = buildPropDescriptor(type, required, defaultValues[name]);\n }\n return props;\n }\n\n // Try type alias\n const typeAlias = sourceFile.getTypeAlias(typeName);\n if (typeAlias) {\n const aliasType = typeAlias.getType();\n if (aliasType.isObject()) {\n for (const prop of aliasType.getProperties()) {\n const name = prop.getName();\n if (name.startsWith(\"[\")) continue;\n const decls = prop.getDeclarations();\n const required =\n decls.length === 0 ||\n !prop.getDeclarations().some((d) => Node.isPropertySignature(d) && d.hasQuestionToken());\n const valType = prop.getTypeAtLocation(sourceFile);\n props[name] = buildPropDescriptor(valType, required, defaultValues[name]);\n }\n }\n return props;\n }\n\n return props;\n}\n\n/**\n * Try to infer the props type name from a function's parameter destructuring.\n * E.g. `function Foo({ bar }: FooProps)` → \"FooProps\"\n */\nfunction inferPropsTypeName(params: { getTypeNode(): Node | undefined }[]): string | undefined {\n if (params.length === 0) return undefined;\n const firstParam = params[0];\n if (!firstParam) return undefined;\n const typeNode = firstParam.getTypeNode?.();\n if (!typeNode) return undefined;\n return typeNode.getText().trim();\n}\n\n/**\n * Extract default values from destructured parameters.\n * E.g. `function Foo({ variant = 'primary', size = 'md' }: FooProps)` → { variant: 'primary', size: 'md' }\n */\nfunction extractDefaultsFromDestructuring(\n params: ReturnType<FunctionDeclaration[\"getParameters\"]>,\n): Record<string, string> {\n const defaults: Record<string, string> = {};\n if (params.length === 0) return defaults;\n const firstParam = params[0];\n if (!firstParam) return defaults;\n\n const nameNode = firstParam.getNameNode();\n if (!Node.isObjectBindingPattern(nameNode)) return defaults;\n\n for (const element of nameNode.getElements()) {\n const initializer = element.getInitializer();\n if (initializer) {\n const propName = element.getPropertyNameNode()?.getText() ?? element.getName();\n defaults[propName] = initializer.getText();\n }\n }\n return defaults;\n}\n\n// ---------------------------------------------------------------------------\n// JSX composition extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Collect all JSX element tag names used inside a node.\n * Returns only PascalCase names (component references, not host elements).\n */\nfunction collectJsxCompositions(node: Node): string[] {\n const names = new Set<string>();\n\n function visit(n: Node): void {\n if (Node.isJsxOpeningElement(n) || Node.isJsxSelfClosingElement(n)) {\n const tagNameNode = n.getTagNameNode();\n const tagName = tagNameNode.getText();\n // Only capture PascalCase = React components (not div, span, etc.)\n if (/^[A-Z]/.test(tagName)) {\n // Strip member access – e.g. React.Fragment → skip; Context.Provider → skip\n const base = tagName.split(\".\")[0] ?? tagName;\n if (base && /^[A-Z]/.test(base) && ![\"React\", \"Fragment\"].includes(base)) {\n names.add(base);\n }\n }\n }\n n.forEachChild(visit);\n }\n\n visit(node);\n return Array.from(names);\n}\n\n// ---------------------------------------------------------------------------\n// HOC / wrapper detection\n// ---------------------------------------------------------------------------\n\ninterface WrapperInfo {\n memoized: boolean;\n forwardedRef: boolean;\n hocWrappers: string[];\n}\n\n/**\n * Detect React.memo, React.forwardRef, and arbitrary HOC wrappers on a call expression.\n */\nfunction detectWrappers(node: Node): WrapperInfo {\n let memoized = false;\n let forwardedRef = false;\n const hocWrappers: string[] = [];\n\n function visitCall(n: Node): void {\n if (!Node.isCallExpression(n)) return;\n const expr = n.getExpression();\n const name = expr.getText();\n\n if (name === \"React.memo\" || name === \"memo\") {\n memoized = true;\n // Recurse into the inner arg (it might also be forwardRef)\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else if (name === \"React.forwardRef\" || name === \"forwardRef\") {\n forwardedRef = true;\n const args = n.getArguments();\n if (args[0]) visitCall(args[0]);\n } else {\n // Generic HOC: something(Component)\n const args = n.getArguments();\n if (args.length > 0) {\n const firstArg = args[0];\n if (firstArg && (Node.isIdentifier(firstArg) || Node.isCallExpression(firstArg))) {\n // Treat outer call name as an HOC wrapper\n const calleeName = name.split(\".\").pop() ?? name;\n if (/^[a-z]/.test(calleeName)) {\n hocWrappers.push(calleeName);\n }\n if (Node.isCallExpression(firstArg)) {\n visitCall(firstArg);\n }\n }\n }\n }\n }\n\n visitCall(node);\n return { memoized, forwardedRef, hocWrappers };\n}\n\n// ---------------------------------------------------------------------------\n// Component name resolution for wrapped components\n// ---------------------------------------------------------------------------\n\n/**\n * Given a call expression like `React.memo(function Foo() {...})`, extract the inner name.\n */\nfunction extractNameFromWrappedCall(node: Node): string | undefined {\n if (!Node.isCallExpression(node)) return undefined;\n const args = node.getArguments();\n if (args.length === 0) return undefined;\n\n const firstArg = args[0];\n if (!firstArg) return undefined;\n\n // memo(function Foo() {...})\n if (Node.isFunctionExpression(firstArg)) {\n return firstArg.getName() ?? undefined;\n }\n // memo(Foo) where Foo is an identifier\n if (Node.isIdentifier(firstArg)) {\n return firstArg.getText();\n }\n // memo(forwardRef(function Foo() {...}))\n if (Node.isCallExpression(firstArg)) {\n return extractNameFromWrappedCall(firstArg);\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Returns-JSX detection\n// ---------------------------------------------------------------------------\n\nfunction nodeReturnsJsx(node: Node): boolean {\n let found = false;\n function visit(n: Node): void {\n if (found) return;\n if (Node.isJsxElement(n) || Node.isJsxFragment(n) || Node.isJsxSelfClosingElement(n)) {\n found = true;\n return;\n }\n n.forEachChild(visit);\n }\n visit(node);\n return found;\n}\n\n// ---------------------------------------------------------------------------\n// Glob matching\n// ---------------------------------------------------------------------------\n\n/**\n * Minimal glob matcher supporting `*` (any chars except `/`) and `**` (any chars).\n * Used for collection pattern and internalPatterns matching.\n */\nfunction matchGlob(pattern: string, value: string): boolean {\n // Escape regex special chars except *\n const escaped = pattern.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regexStr = escaped\n .replace(/\\*\\*/g, \"§GLOBSTAR§\")\n .replace(/\\*/g, \"[^/]*\")\n .replace(/§GLOBSTAR§/g, \".*\");\n const regex = new RegExp(`^${regexStr}$`, \"i\");\n return regex.test(value);\n}\n\n// ---------------------------------------------------------------------------\n// TSDoc tag extraction\n// ---------------------------------------------------------------------------\n\n/**\n * Extract @collection and @internal tags from JSDoc on a declaration node.\n * Returns { collection?: string; internal: boolean }.\n *\n * ts-morph exposes getJsDocs() on concrete declaration types (FunctionDeclaration,\n * VariableStatement, ClassDeclaration, etc.) but not on the base Node class.\n * We use an unknown cast to access it safely.\n */\nfunction extractTsDocTags(declNode: Node): { collection?: string; internal: boolean } {\n let collection: string | undefined;\n let internal = false;\n\n // Safely access getJsDocs via duck-typing — available on most named declaration nodes\n const nodeWithDocs = declNode as unknown as {\n getJsDocs?: () => Array<{\n getTags: () => Array<{\n getTagName: () => string;\n getComment: () => string | undefined;\n }>;\n }>;\n };\n\n if (typeof nodeWithDocs.getJsDocs !== \"function\") {\n return { collection, internal };\n }\n\n const jsDocs = nodeWithDocs.getJsDocs();\n\n for (const jsDoc of jsDocs) {\n for (const tag of jsDoc.getTags()) {\n const tagName = tag.getTagName();\n if (tagName === \"collection\") {\n const comment = tag.getComment();\n if (comment && typeof comment === \"string\") {\n collection = comment.trim();\n }\n } else if (tagName === \"internal\") {\n internal = true;\n }\n }\n }\n\n return { collection, internal };\n}\n\n// ---------------------------------------------------------------------------\n// Scope file collection extraction (static AST — no bundling)\n// ---------------------------------------------------------------------------\n\n/**\n * Attempt to read `export const collection = \"...\"` from a scope file using ts-morph.\n * Returns the collection name string, or undefined if not found.\n */\nfunction readCollectionFromScopeFile(scopeFilePath: string, project: Project): string | undefined {\n // Add the scope file to the project temporarily if not already present\n let sf = project.getSourceFile(scopeFilePath);\n if (!sf) {\n sf = project.addSourceFileAtPath(scopeFilePath);\n }\n\n for (const varStmt of sf.getVariableStatements()) {\n if (!varStmt.isExported()) continue;\n for (const varDecl of varStmt.getDeclarations()) {\n if (varDecl.getName() !== \"collection\") continue;\n const initializer = varDecl.getInitializer();\n if (!initializer) continue;\n if (Node.isStringLiteral(initializer)) {\n return initializer.getLiteralValue();\n }\n }\n }\n return undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Per-file component extraction\n// ---------------------------------------------------------------------------\n\ninterface RawComponent {\n name: string;\n descriptor: ComponentDescriptor;\n}\n\nfunction processSourceFile(\n sourceFile: SourceFile,\n rootDir: string,\n project: Project,\n): RawComponent[] {\n const results: RawComponent[] = [];\n const filePath = relative(rootDir, sourceFile.getFilePath());\n\n // Collect default export assignment target name (e.g. `export default Foo`)\n // Also handle wrapped defaults: `export default React.memo(Foo)` or `export default React.forwardRef(Foo)`\n let defaultExportName: string | undefined;\n const defaultExportWrappers = new Map<string, WrapperInfo>();\n sourceFile.forEachChild((node) => {\n if (Node.isExportAssignment(node)) {\n const expr = (node as ExportAssignment).getExpression();\n if (Node.isIdentifier(expr)) {\n defaultExportName = (expr as Identifier).getText();\n } else if (Node.isCallExpression(expr)) {\n // e.g. `export default React.memo(Sidebar)` or `export default React.forwardRef(Btn)`\n const innerName = extractNameFromWrappedCall(expr);\n if (innerName) {\n defaultExportName = innerName;\n defaultExportWrappers.set(innerName, detectWrappers(expr));\n }\n }\n }\n });\n\n // Named exports map: variable name → export type\n const namedExports = new Set<string>();\n for (const exportDecl of sourceFile.getExportSymbols()) {\n namedExports.add(exportDecl.getName());\n }\n\n // -------------------------------------------------------------------------\n // 1. Function declarations\n // -------------------------------------------------------------------------\n for (const fn of sourceFile.getFunctions()) {\n const name = fn.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n if (!nodeReturnsJsx(fn)) continue;\n\n const params = fn.getParameters();\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(fn);\n const start = fn.getStartLineNumber();\n const end = fn.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (fn.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (fn.isExported() || namedExports.has(name)) exportType = \"named\";\n\n const fnWrappers = defaultExportWrappers.get(name) ?? {\n memoized: false,\n forwardedRef: false,\n hocWrappers: [],\n };\n\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: fnWrappers.forwardedRef,\n hocWrappers: fnWrappers.hocWrappers,\n memoized: fnWrappers.memoized,\n loc: { start, end },\n complexityClass: analyzeComplexity(fn),\n detectedHooks: detectHooks(fn),\n requiredContexts: detectRequiredContexts(fn, sourceFile, project),\n sideEffects: detectSideEffects(fn),\n scopeFile: null,\n // collection and internal will be filled in after all components are collected\n internal: false,\n },\n });\n }\n\n // -------------------------------------------------------------------------\n // 2. Variable declarations (arrow functions, React.memo, React.forwardRef)\n // -------------------------------------------------------------------------\n for (const varStmt of sourceFile.getVariableStatements()) {\n const isExported = varStmt.isExported();\n for (const varDecl of varStmt.getDeclarations()) {\n const varName = (varDecl as VariableDeclaration).getName();\n if (!/^[A-Z]/.test(varName)) continue;\n\n const initializer = (varDecl as VariableDeclaration).getInitializer();\n if (!initializer) continue;\n\n // Detect wrappers on the whole expression\n const wrappers = detectWrappers(initializer);\n let innerName: string | undefined;\n let bodyNode: Node = initializer;\n\n if (Node.isCallExpression(initializer)) {\n innerName = extractNameFromWrappedCall(initializer);\n // Drill into the innermost function for props / JSX\n const args = initializer.getArguments();\n const firstArg = args[0];\n if (firstArg) {\n if (Node.isArrowFunction(firstArg) || Node.isFunctionExpression(firstArg)) {\n bodyNode = firstArg;\n } else if (Node.isCallExpression(firstArg)) {\n // e.g. memo(forwardRef(fn))\n const innerArgs = firstArg.getArguments();\n const innerFirst = innerArgs[0];\n if (\n innerFirst &&\n (Node.isArrowFunction(innerFirst) || Node.isFunctionExpression(innerFirst))\n ) {\n bodyNode = innerFirst;\n }\n }\n }\n }\n\n // Must return JSX somewhere in the body\n if (!nodeReturnsJsx(bodyNode)) continue;\n\n // For named inner functions we use innerName; fall back to varName\n const componentName = innerName ?? varName;\n\n let params: ReturnType<FunctionDeclaration[\"getParameters\"]> = [];\n if (Node.isArrowFunction(bodyNode) || Node.isFunctionExpression(bodyNode)) {\n params = bodyNode.getParameters();\n }\n\n const propsTypeName = inferPropsTypeName(params);\n const defaults = extractDefaultsFromDestructuring(params);\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile, defaults) : {};\n\n const composes = collectJsxCompositions(bodyNode);\n const startLine = (varDecl as VariableDeclaration).getStartLineNumber();\n const endLine = (varDecl as VariableDeclaration).getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (defaultExportName === varName || defaultExportName === componentName) {\n exportType = \"default\";\n } else if (isExported || namedExports.has(varName)) {\n exportType = \"named\";\n }\n\n results.push({\n name: componentName === varName ? componentName : varName,\n descriptor: {\n filePath,\n exportType,\n displayName: componentName,\n props,\n composes,\n composedBy: [],\n forwardedRef: wrappers.forwardedRef,\n hocWrappers: wrappers.hocWrappers,\n memoized: wrappers.memoized,\n loc: { start: startLine, end: endLine },\n complexityClass: analyzeComplexity(bodyNode),\n detectedHooks: detectHooks(bodyNode),\n requiredContexts: detectRequiredContexts(bodyNode, sourceFile, project),\n sideEffects: detectSideEffects(bodyNode),\n scopeFile: null,\n internal: false,\n },\n });\n }\n }\n\n // -------------------------------------------------------------------------\n // 3. Class components\n // -------------------------------------------------------------------------\n for (const cls of sourceFile.getClasses()) {\n const name = cls.getName();\n if (!name) continue;\n if (!/^[A-Z]/.test(name)) continue;\n\n // Must extend React.Component or React.PureComponent\n const baseClass = (cls as ClassDeclaration).getBaseClass()?.getName();\n if (!baseClass && !(cls as ClassDeclaration).getExtends()) continue;\n const extendsText = (cls as ClassDeclaration).getExtends()?.getText() ?? \"\";\n if (!extendsText.includes(\"Component\") && !extendsText.includes(\"PureComponent\")) {\n continue;\n }\n\n // Render method must return JSX\n const renderMethod = cls.getMethod(\"render\");\n if (!renderMethod || !nodeReturnsJsx(renderMethod)) continue;\n\n // Extract first type argument as props type\n const extendsNode = (cls as ClassDeclaration).getExtends();\n let propsTypeName: string | undefined;\n if (extendsNode) {\n const typeArgs = extendsNode.getTypeArguments();\n if (typeArgs[0]) {\n propsTypeName = typeArgs[0].getText().trim();\n }\n }\n const props = propsTypeName ? extractPropsFromType(propsTypeName, sourceFile) : {};\n\n const composes = collectJsxCompositions(renderMethod);\n const start = cls.getStartLineNumber();\n const end = cls.getEndLineNumber();\n\n let exportType: ExportType = \"none\";\n if (cls.isDefaultExport() || defaultExportName === name) exportType = \"default\";\n else if (cls.isExported() || namedExports.has(name)) exportType = \"named\";\n\n // Class components: default to \"complex\" (they often use lifecycle methods / state)\n results.push({\n name,\n descriptor: {\n filePath,\n exportType,\n displayName: name,\n props,\n composes,\n composedBy: [],\n forwardedRef: false,\n hocWrappers: [],\n memoized: false,\n loc: { start, end },\n complexityClass: \"complex\",\n detectedHooks: [],\n requiredContexts: [],\n sideEffects: detectSideEffects(cls),\n scopeFile: null,\n internal: false,\n },\n });\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Public API\n// ---------------------------------------------------------------------------\n\n/**\n * Generate a component manifest by parsing all matching TypeScript/TSX files.\n */\nexport function generateManifest(config: ManifestConfig): Manifest {\n const {\n rootDir,\n include = [\"src/**/*.tsx\", \"src/**/*.ts\"],\n exclude = [\"**/node_modules/**\", \"**/*.test.*\", \"**/*.spec.*\", \"**/dist/**\", \"**/*.d.ts\"],\n tsConfigFilePath = join(rootDir, \"tsconfig.json\"),\n } = config;\n\n const project = new Project({\n tsConfigFilePath,\n skipAddingFilesFromTsConfig: true,\n });\n\n // Add source files via glob\n const includePatterns = include.map((g) => join(rootDir, g));\n project.addSourceFilesFromTsConfig(tsConfigFilePath);\n\n // If tsconfig doesn't cover the files, add them directly\n for (const pattern of includePatterns) {\n project.addSourceFilesAtPaths(pattern);\n }\n\n // Remove excluded files\n for (const sf of project.getSourceFiles()) {\n const fp = sf.getFilePath();\n const shouldExclude = exclude.some((ex) => {\n const pattern = ex.replace(/\\*\\*/g, \".*\").replace(/\\*/g, \"[^/]*\").replace(/\\./g, \"\\\\.\");\n return new RegExp(pattern).test(fp);\n });\n if (shouldExclude) {\n project.removeSourceFile(sf);\n }\n }\n\n // Also filter to only files within rootDir\n for (const sf of project.getSourceFiles()) {\n if (!sf.getFilePath().startsWith(rootDir)) {\n project.removeSourceFile(sf);\n }\n }\n\n // Collect all components\n const allComponents: Record<string, ComponentDescriptor> = {};\n\n for (const sf of project.getSourceFiles()) {\n const rawComponents = processSourceFile(sf, rootDir, project);\n for (const { name, descriptor } of rawComponents) {\n // If duplicate name, prefer the exported one\n if (allComponents[name] && descriptor.exportType === \"none\") continue;\n allComponents[name] = descriptor;\n }\n }\n\n // Build composition inverse: composedBy\n for (const [name, desc] of Object.entries(allComponents)) {\n for (const child of desc.composes) {\n if (allComponents[child]) {\n const childDesc = allComponents[child];\n if (childDesc && !childDesc.composedBy.includes(name)) {\n childDesc.composedBy.push(name);\n }\n }\n }\n }\n\n // Propagate complexityClass upward through the composition tree.\n // A component is only `simple` if it AND every descendant are simple.\n // This must run after composedBy is fully populated.\n propagateComplexity(allComponents);\n\n // Build tree\n const tree: Manifest[\"tree\"] = {};\n for (const [name, desc] of Object.entries(allComponents)) {\n // Only include children that exist in the manifest\n const children = desc.composes.filter((c) => c in allComponents);\n const parents = desc.composedBy.filter((p) => p in allComponents);\n tree[name] = { children, parents };\n }\n\n // Attach scope file metadata to each component (static presence check only)\n for (const desc of Object.values(allComponents)) {\n const scopeMeta = detectScopeFile(desc.filePath, config.rootDir);\n if (scopeMeta !== null) {\n desc.scopeFile = scopeMeta;\n }\n }\n\n // -------------------------------------------------------------------------\n // Resolve collection and internal for each component\n // After composedBy + scope file is populated.\n //\n // Precedence:\n // collection: TSDoc @collection > .scope.ts export > config patterns\n // internal: TSDoc @internal > config internalPatterns\n // -------------------------------------------------------------------------\n const configCollections: CollectionConfig[] = config.collections ?? [];\n const internalPatterns: string[] = config.internalPatterns ?? [];\n\n for (const [compName, desc] of Object.entries(allComponents)) {\n // --- 1. TSDoc-based collection & internal ---\n // We need to find the source file to look up the declaration\n const absFilePath = desc.filePath.startsWith(\"/\")\n ? desc.filePath\n : join(rootDir, desc.filePath);\n const sf = project.getSourceFile(absFilePath);\n\n let tsdocCollection: string | undefined;\n let tsdocInternal = false;\n\n if (sf) {\n // Try function declarations first\n const fn = sf.getFunction(compName);\n if (fn) {\n const tags = extractTsDocTags(fn);\n tsdocCollection = tags.collection;\n tsdocInternal = tags.internal;\n }\n\n // Try variable declarations (arrow functions, React.memo, etc.)\n if (tsdocCollection === undefined && !tsdocInternal) {\n const varDecl = sf.getVariableDeclaration(compName);\n if (varDecl) {\n // JSDocs are on the VariableStatement, not the VariableDeclaration\n const varStmt = varDecl.getVariableStatement();\n if (varStmt) {\n const tags = extractTsDocTags(varStmt);\n tsdocCollection = tags.collection;\n tsdocInternal = tags.internal;\n }\n }\n }\n\n // Try class declarations\n if (tsdocCollection === undefined && !tsdocInternal) {\n const cls = sf.getClass(compName);\n if (cls) {\n const tags = extractTsDocTags(cls);\n tsdocCollection = tags.collection;\n tsdocInternal = tags.internal;\n }\n }\n }\n\n // --- 2. .scope.ts collection ---\n let scopeFileCollection: string | undefined;\n if (desc.scopeFile) {\n scopeFileCollection = readCollectionFromScopeFile(desc.scopeFile.filePath, project);\n }\n\n // --- 3. Config pattern matching ---\n let configCollection: string | undefined;\n for (const colConfig of configCollections) {\n if (colConfig.patterns.some((p) => matchGlob(p, desc.filePath))) {\n configCollection = colConfig.name;\n break;\n }\n }\n\n let configInternal = false;\n if (internalPatterns.length > 0) {\n configInternal = internalPatterns.some(\n (p) => matchGlob(p, desc.filePath) || matchGlob(p, desc.displayName),\n );\n }\n\n // --- Apply precedence ---\n // collection: TSDoc > .scope.ts > config\n const resolvedCollection = tsdocCollection ?? scopeFileCollection ?? configCollection;\n if (resolvedCollection !== undefined) {\n desc.collection = resolvedCollection;\n }\n\n // internal: TSDoc > config patterns\n desc.internal = tsdocInternal || configInternal;\n }\n\n return {\n version: \"0.1\",\n generatedAt: new Date().toISOString(),\n components: allComponents,\n tree,\n collections: configCollections,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Scope file detection (static — presence check only, no bundling)\n// ---------------------------------------------------------------------------\n\nconst SCOPE_EXTENSIONS = [\".scope.tsx\", \".scope.ts\", \".scope.jsx\", \".scope.js\"];\n\n/**\n * Check whether a scope file exists next to the component file.\n * Returns minimal ScopeFileMeta if found, null otherwise.\n *\n * scenarioNames and hasWrapper are left empty here — they are populated at\n * render time when loadScopeFile() actually bundles and evaluates the file.\n */\nfunction detectScopeFile(componentFilePath: string, rootDir: string): ScopeFileMeta | null {\n const absPath = componentFilePath.startsWith(\"/\")\n ? componentFilePath\n : join(rootDir, componentFilePath);\n\n const stem = absPath.replace(/\\.(tsx?|jsx?)$/, \"\");\n for (const ext of SCOPE_EXTENSIONS) {\n const candidate = `${stem}${ext}`;\n if (existsSync(candidate)) {\n return { filePath: candidate, scenarioNames: [], hasWrapper: false };\n }\n }\n return null;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-scope/manifest",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.20.0",
|
|
4
4
|
"description": "TypeScript AST parser that generates a machine-readable React component registry for Scope",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"clean": "rm -rf dist"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@agent-scope/core": "1.
|
|
33
|
+
"@agent-scope/core": "1.20.0",
|
|
34
34
|
"ts-morph": "^25.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|