@codesentinel/codesentinel 0.1.0 → 0.1.1
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.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -459,7 +459,7 @@ var runAnalyzeCommand = (inputPath) => {
|
|
|
459
459
|
|
|
460
460
|
// src/index.ts
|
|
461
461
|
var program = new Command();
|
|
462
|
-
program.name("codesentinel").description("Structural and evolutionary risk analysis for TypeScript/JavaScript codebases").version("0.1.
|
|
462
|
+
program.name("codesentinel").description("Structural and evolutionary risk analysis for TypeScript/JavaScript codebases").version("0.1.1");
|
|
463
463
|
program.command("analyze").argument("[path]", "path to the project to analyze").action((path) => {
|
|
464
464
|
const output = runAnalyzeCommand(path);
|
|
465
465
|
process.stdout.write(`${output}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../../code-graph/src/domain/graph-model.ts","../../code-graph/src/domain/tarjan.ts","../../code-graph/src/domain/graph-metrics.ts","../../code-graph/src/infrastructure/typescript-project.ts","../../code-graph/src/application/build-project-graph-summary.ts","../../core/src/index.ts","../src/application/run-analyze-command.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { runAnalyzeCommand } from \"./application/run-analyze-command.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"codesentinel\")\n .description(\"Structural and evolutionary risk analysis for TypeScript/JavaScript codebases\")\n .version(\"0.1.0\");\n\nprogram\n .command(\"analyze\")\n .argument(\"[path]\", \"path to the project to analyze\")\n .action((path?: string) => {\n const output = runAnalyzeCommand(path);\n process.stdout.write(`${output}\\n`);\n });\n\nif (process.argv.length <= 2) {\n program.outputHelp();\n process.exit(0);\n}\n\nprogram.parse(process.argv);\n","export type NodeRecord = {\n id: string;\n absolutePath: string;\n relativePath: string;\n};\n\nexport type EdgeRecord = {\n from: string;\n to: string;\n};\n\nexport type GraphData = {\n nodes: readonly NodeRecord[];\n edges: readonly EdgeRecord[];\n adjacencyById: ReadonlyMap<string, readonly string[]>;\n};\n\nconst edgeKey = (from: string, to: string): string => `${from}\\u0000${to}`;\n\nexport const createGraphData = (\n nodes: readonly NodeRecord[],\n rawEdges: readonly EdgeRecord[],\n): GraphData => {\n const sortedNodes = [...nodes].sort((a, b) => a.id.localeCompare(b.id));\n const knownNodeIds = new Set(sortedNodes.map((node) => node.id));\n\n const uniqueEdgeMap = new Map<string, EdgeRecord>();\n for (const edge of rawEdges) {\n if (edge.from === edge.to) {\n continue;\n }\n\n if (!knownNodeIds.has(edge.from) || !knownNodeIds.has(edge.to)) {\n continue;\n }\n\n uniqueEdgeMap.set(edgeKey(edge.from, edge.to), edge);\n }\n\n const sortedEdges = [...uniqueEdgeMap.values()].sort((a, b) => {\n const fromCompare = a.from.localeCompare(b.from);\n if (fromCompare !== 0) {\n return fromCompare;\n }\n\n return a.to.localeCompare(b.to);\n });\n\n const adjacency = new Map<string, string[]>();\n for (const node of sortedNodes) {\n adjacency.set(node.id, []);\n }\n\n for (const edge of sortedEdges) {\n adjacency.get(edge.from)?.push(edge.to);\n }\n\n const adjacencyById = new Map<string, readonly string[]>();\n for (const [nodeId, targets] of adjacency.entries()) {\n adjacencyById.set(nodeId, [...targets]);\n }\n\n return {\n nodes: sortedNodes,\n edges: sortedEdges,\n adjacencyById,\n };\n};\n","type TarjanResult = {\n components: readonly (readonly string[])[];\n};\n\nexport const runTarjanScc = (adjacencyById: ReadonlyMap<string, readonly string[]>): TarjanResult => {\n let index = 0;\n const indices = new Map<string, number>();\n const lowLink = new Map<string, number>();\n const stack: string[] = [];\n const onStack = new Set<string>();\n const components: string[][] = [];\n\n const strongConnect = (nodeId: string): void => {\n indices.set(nodeId, index);\n lowLink.set(nodeId, index);\n index += 1;\n\n stack.push(nodeId);\n onStack.add(nodeId);\n\n const neighbors = adjacencyById.get(nodeId) ?? [];\n for (const nextId of neighbors) {\n if (!indices.has(nextId)) {\n strongConnect(nextId);\n const nodeLowLink = lowLink.get(nodeId);\n const nextLowLink = lowLink.get(nextId);\n if (nodeLowLink !== undefined && nextLowLink !== undefined && nextLowLink < nodeLowLink) {\n lowLink.set(nodeId, nextLowLink);\n }\n continue;\n }\n\n if (onStack.has(nextId)) {\n const nodeLowLink = lowLink.get(nodeId);\n const nextIndex = indices.get(nextId);\n if (nodeLowLink !== undefined && nextIndex !== undefined && nextIndex < nodeLowLink) {\n lowLink.set(nodeId, nextIndex);\n }\n }\n }\n\n const nodeLowLink = lowLink.get(nodeId);\n const nodeIndex = indices.get(nodeId);\n if (nodeLowLink === undefined || nodeIndex === undefined || nodeLowLink !== nodeIndex) {\n return;\n }\n\n const component: string[] = [];\n for (;;) {\n const popped = stack.pop();\n if (popped === undefined) {\n break;\n }\n\n onStack.delete(popped);\n component.push(popped);\n if (popped === nodeId) {\n break;\n }\n }\n\n component.sort((a, b) => a.localeCompare(b));\n components.push(component);\n };\n\n const nodeIds = [...adjacencyById.keys()].sort((a, b) => a.localeCompare(b));\n for (const nodeId of nodeIds) {\n if (!indices.has(nodeId)) {\n strongConnect(nodeId);\n }\n }\n\n components.sort((a, b) => {\n const firstA = a[0] ?? \"\";\n const firstB = b[0] ?? \"\";\n return firstA.localeCompare(firstB);\n });\n\n return { components };\n};\n","import type { FileDependency, GraphAnalysisSummary, GraphCycle, GraphMetrics } from \"@codesentinel/core\";\nimport type { GraphData } from \"./graph-model.js\";\nimport { runTarjanScc } from \"./tarjan.js\";\n\ntype DepthComputation = {\n depthByNodeId: ReadonlyMap<string, number>;\n graphDepth: number;\n cycles: readonly GraphCycle[];\n};\n\nconst hasSelfLoop = (nodeId: string, adjacencyById: ReadonlyMap<string, readonly string[]>): boolean => {\n const targets = adjacencyById.get(nodeId) ?? [];\n return targets.includes(nodeId);\n};\n\nconst computeCyclesAndDepth = (graph: GraphData): DepthComputation => {\n const { components } = runTarjanScc(graph.adjacencyById);\n\n const cycles: GraphCycle[] = [];\n const componentByNodeId = new Map<string, number>();\n components.forEach((component, index) => {\n for (const nodeId of component) {\n componentByNodeId.set(nodeId, index);\n }\n\n if (component.length > 1) {\n cycles.push({ nodes: [...component] });\n return;\n }\n\n const onlyNode = component[0];\n if (onlyNode !== undefined && hasSelfLoop(onlyNode, graph.adjacencyById)) {\n cycles.push({ nodes: [...component] });\n }\n });\n\n const dagOutgoing = new Map<number, Set<number>>();\n const inDegree = new Map<number, number>();\n\n for (let i = 0; i < components.length; i += 1) {\n dagOutgoing.set(i, new Set());\n inDegree.set(i, 0);\n }\n\n for (const edge of graph.edges) {\n const fromComponent = componentByNodeId.get(edge.from);\n const toComponent = componentByNodeId.get(edge.to);\n\n if (fromComponent === undefined || toComponent === undefined || fromComponent === toComponent) {\n continue;\n }\n\n const outgoing = dagOutgoing.get(fromComponent);\n if (outgoing?.has(toComponent) === true) {\n continue;\n }\n\n outgoing?.add(toComponent);\n inDegree.set(toComponent, (inDegree.get(toComponent) ?? 0) + 1);\n }\n\n const queue: number[] = [];\n const depthByComponent = new Map<number, number>();\n\n for (let i = 0; i < components.length; i += 1) {\n if ((inDegree.get(i) ?? 0) === 0) {\n queue.push(i);\n depthByComponent.set(i, 0);\n }\n }\n\n let cursor = 0;\n while (cursor < queue.length) {\n const componentId = queue[cursor];\n cursor += 1;\n\n if (componentId === undefined) {\n continue;\n }\n\n const currentDepth = depthByComponent.get(componentId) ?? 0;\n const outgoing = dagOutgoing.get(componentId) ?? new Set<number>();\n\n for (const nextComponent of outgoing) {\n const nextDepth = depthByComponent.get(nextComponent) ?? 0;\n if (currentDepth + 1 > nextDepth) {\n depthByComponent.set(nextComponent, currentDepth + 1);\n }\n\n const remainingIncoming = (inDegree.get(nextComponent) ?? 0) - 1;\n inDegree.set(nextComponent, remainingIncoming);\n if (remainingIncoming === 0) {\n queue.push(nextComponent);\n }\n }\n }\n\n const depthByNodeId = new Map<string, number>();\n let graphDepth = 0;\n\n components.forEach((component, componentId) => {\n const componentDepth = depthByComponent.get(componentId) ?? 0;\n if (componentDepth > graphDepth) {\n graphDepth = componentDepth;\n }\n\n for (const nodeId of component) {\n depthByNodeId.set(nodeId, componentDepth);\n }\n });\n\n cycles.sort((a, b) => {\n const firstA = a.nodes[0] ?? \"\";\n const firstB = b.nodes[0] ?? \"\";\n return firstA.localeCompare(firstB);\n });\n\n return {\n depthByNodeId,\n graphDepth,\n cycles,\n };\n};\n\nexport const createGraphAnalysisSummary = (\n targetPath: string,\n graph: GraphData,\n): GraphAnalysisSummary => {\n const fanInById = new Map<string, number>();\n const fanOutById = new Map<string, number>();\n\n for (const node of graph.nodes) {\n fanInById.set(node.id, 0);\n fanOutById.set(node.id, graph.adjacencyById.get(node.id)?.length ?? 0);\n }\n\n for (const edge of graph.edges) {\n fanInById.set(edge.to, (fanInById.get(edge.to) ?? 0) + 1);\n }\n\n const { cycles, depthByNodeId, graphDepth } = computeCyclesAndDepth(graph);\n\n let maxFanIn = 0;\n let maxFanOut = 0;\n\n const files: FileDependency[] = graph.nodes.map((node) => {\n const fanIn = fanInById.get(node.id) ?? 0;\n const fanOut = fanOutById.get(node.id) ?? 0;\n\n if (fanIn > maxFanIn) {\n maxFanIn = fanIn;\n }\n\n if (fanOut > maxFanOut) {\n maxFanOut = fanOut;\n }\n\n return {\n id: node.id,\n relativePath: node.relativePath,\n directDependencies: graph.adjacencyById.get(node.id) ?? [],\n fanIn,\n fanOut,\n depth: depthByNodeId.get(node.id) ?? 0,\n };\n });\n\n const metrics: GraphMetrics = {\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n cycleCount: cycles.length,\n graphDepth,\n maxFanIn,\n maxFanOut,\n };\n\n return {\n targetPath,\n nodes: graph.nodes,\n edges: graph.edges,\n cycles,\n files,\n metrics,\n };\n};\n","import { extname, isAbsolute, relative, resolve } from \"node:path\";\nimport * as ts from \"typescript\";\nimport type { EdgeRecord, NodeRecord } from \"../domain/graph-model.js\";\n\ntype ParsedProject = {\n nodes: readonly NodeRecord[];\n edges: readonly EdgeRecord[];\n};\n\nconst SOURCE_EXTENSIONS = new Set([\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".jsx\", \".mjs\", \".cjs\"]);\n\nconst normalizePath = (pathValue: string): string => pathValue.replaceAll(\"\\\\\", \"/\");\n\nconst isProjectSourceFile = (filePath: string, projectRoot: string): boolean => {\n const extension = extname(filePath);\n if (!SOURCE_EXTENSIONS.has(extension)) {\n return false;\n }\n\n const relativePath = relative(projectRoot, filePath);\n if (relativePath.startsWith(\"..\")) {\n return false;\n }\n\n return !relativePath.includes(\"node_modules\");\n};\n\nconst findProjectFiles = (projectRoot: string): readonly string[] => {\n const files = ts.sys.readDirectory(projectRoot, [...SOURCE_EXTENSIONS], undefined, undefined);\n return files.map((filePath) => resolve(filePath));\n};\n\nconst parseTsConfig = (projectRoot: string): { fileNames: readonly string[]; options: ts.CompilerOptions } => {\n const configPath = ts.findConfigFile(projectRoot, ts.sys.fileExists, \"tsconfig.json\");\n if (configPath === undefined) {\n return {\n fileNames: findProjectFiles(projectRoot),\n options: {\n allowJs: true,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n },\n };\n }\n\n const parsedCommandLine = ts.getParsedCommandLineOfConfigFile(\n configPath,\n {},\n {\n ...ts.sys,\n onUnRecoverableConfigFileDiagnostic: () => {\n throw new Error(`Failed to parse TypeScript configuration at ${configPath}`);\n },\n },\n );\n\n if (parsedCommandLine === undefined) {\n throw new Error(`Failed to parse TypeScript configuration at ${configPath}`);\n }\n\n const fileNames = parsedCommandLine.fileNames.map((filePath) => resolve(filePath));\n if (fileNames.length === 0) {\n return {\n fileNames: findProjectFiles(projectRoot),\n options: parsedCommandLine.options,\n };\n }\n\n return {\n fileNames,\n options: parsedCommandLine.options,\n };\n};\n\nconst getSpecifierFromExpression = (expression: ts.Expression): string | undefined => {\n if (ts.isStringLiteral(expression)) {\n return expression.text;\n }\n\n if (ts.isNoSubstitutionTemplateLiteral(expression)) {\n return expression.text;\n }\n\n return undefined;\n};\n\nconst hasRuntimeImport = (importDeclaration: ts.ImportDeclaration): boolean => {\n const importClause = importDeclaration.importClause;\n if (importClause === undefined) {\n return true;\n }\n\n if (importClause.isTypeOnly) {\n return false;\n }\n\n if (importClause.name !== undefined) {\n return true;\n }\n\n const namedBindings = importClause.namedBindings;\n if (namedBindings === undefined) {\n return false;\n }\n\n if (ts.isNamespaceImport(namedBindings)) {\n return true;\n }\n\n if (namedBindings.elements.length === 0) {\n return true;\n }\n\n return namedBindings.elements.some((element) => !element.isTypeOnly);\n};\n\nconst extractModuleSpecifiers = (sourceFile: ts.SourceFile): readonly string[] => {\n const specifiers = new Set<string>();\n\n const visit = (node: ts.Node): void => {\n if (ts.isImportDeclaration(node)) {\n if (hasRuntimeImport(node) && node.moduleSpecifier !== undefined) {\n const specifier = getSpecifierFromExpression(node.moduleSpecifier);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n return;\n }\n\n if (ts.isExportDeclaration(node)) {\n if (!node.isTypeOnly && node.moduleSpecifier !== undefined) {\n const specifier = getSpecifierFromExpression(node.moduleSpecifier);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n return;\n }\n\n if (ts.isCallExpression(node)) {\n if (node.expression.kind === ts.SyntaxKind.ImportKeyword && node.arguments.length > 0) {\n const firstArgument = node.arguments[0];\n if (firstArgument !== undefined) {\n const specifier = getSpecifierFromExpression(firstArgument);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n }\n\n if (ts.isIdentifier(node.expression) && node.expression.text === \"require\" && node.arguments.length > 0) {\n const firstArgument = node.arguments[0];\n if (firstArgument !== undefined) {\n const specifier = getSpecifierFromExpression(firstArgument);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n }\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return [...specifiers];\n};\n\nexport const parseTypescriptProject = (projectPath: string): ParsedProject => {\n const projectRoot = isAbsolute(projectPath) ? projectPath : resolve(projectPath);\n const { fileNames, options } = parseTsConfig(projectRoot);\n\n const sourceFilePaths = fileNames\n .filter((filePath) => isProjectSourceFile(filePath, projectRoot))\n .map((filePath) => normalizePath(resolve(filePath)));\n\n const uniqueSourceFilePaths = [...new Set(sourceFilePaths)].sort((a, b) => a.localeCompare(b));\n const sourceFilePathSet = new Set(uniqueSourceFilePaths);\n\n const program = ts.createProgram({\n rootNames: uniqueSourceFilePaths,\n options,\n });\n\n const nodeByAbsolutePath = new Map<string, NodeRecord>();\n for (const sourcePath of uniqueSourceFilePaths) {\n const relativePath = normalizePath(relative(projectRoot, sourcePath));\n const nodeId = relativePath;\n nodeByAbsolutePath.set(sourcePath, {\n id: nodeId,\n absolutePath: sourcePath,\n relativePath,\n });\n }\n\n const resolverCache = new Map<string, string | undefined>();\n const edges: EdgeRecord[] = [];\n\n for (const sourcePath of uniqueSourceFilePaths) {\n const sourceFile = program.getSourceFile(sourcePath);\n if (sourceFile === undefined) {\n continue;\n }\n\n const fromNode = nodeByAbsolutePath.get(sourcePath);\n if (fromNode === undefined) {\n continue;\n }\n\n const moduleSpecifiers = extractModuleSpecifiers(sourceFile);\n for (const specifier of moduleSpecifiers) {\n const cacheKey = `${sourcePath}\\u0000${specifier}`;\n let resolvedPath = resolverCache.get(cacheKey);\n\n if (resolvedPath === undefined && !resolverCache.has(cacheKey)) {\n const resolved = ts.resolveModuleName(specifier, sourcePath, options, ts.sys).resolvedModule;\n if (resolved !== undefined) {\n resolvedPath = normalizePath(resolve(resolved.resolvedFileName));\n }\n resolverCache.set(cacheKey, resolvedPath);\n }\n\n if (resolvedPath === undefined || !sourceFilePathSet.has(resolvedPath)) {\n continue;\n }\n\n const toNode = nodeByAbsolutePath.get(resolvedPath);\n if (toNode === undefined) {\n continue;\n }\n\n edges.push({ from: fromNode.id, to: toNode.id });\n }\n }\n\n return {\n nodes: [...nodeByAbsolutePath.values()],\n edges,\n };\n};\n","import type { GraphAnalysisSummary } from \"@codesentinel/core\";\nimport { createGraphData } from \"../domain/graph-model.js\";\nimport { createGraphAnalysisSummary } from \"../domain/graph-metrics.js\";\nimport { parseTypescriptProject } from \"../infrastructure/typescript-project.js\";\n\nexport type BuildProjectGraphSummaryInput = {\n projectPath: string;\n};\n\nexport const buildProjectGraphSummary = (\n input: BuildProjectGraphSummaryInput,\n): GraphAnalysisSummary => {\n const parsedProject = parseTypescriptProject(input.projectPath);\n const graphData = createGraphData(parsedProject.nodes, parsedProject.edges);\n return createGraphAnalysisSummary(input.projectPath, graphData);\n};\n","import { resolve } from \"node:path\";\n\nexport type AnalyzeTarget = {\n absolutePath: string;\n};\n\nexport type GraphNode = {\n id: string;\n absolutePath: string;\n relativePath: string;\n};\n\nexport type GraphEdge = {\n from: string;\n to: string;\n};\n\nexport type GraphCycle = {\n nodes: readonly string[];\n};\n\nexport type FileDependency = {\n id: string;\n relativePath: string;\n directDependencies: readonly string[];\n fanIn: number;\n fanOut: number;\n depth: number;\n};\n\nexport type GraphMetrics = {\n nodeCount: number;\n edgeCount: number;\n cycleCount: number;\n graphDepth: number;\n maxFanIn: number;\n maxFanOut: number;\n};\n\nexport type GraphAnalysisSummary = {\n targetPath: string;\n nodes: readonly GraphNode[];\n edges: readonly GraphEdge[];\n cycles: readonly GraphCycle[];\n files: readonly FileDependency[];\n metrics: GraphMetrics;\n};\n\nexport const resolveTargetPath = (\n inputPath: string | undefined,\n cwd: string = process.cwd(),\n): AnalyzeTarget => {\n const absolutePath = resolve(cwd, inputPath ?? \".\");\n return { absolutePath };\n};\n","import { buildProjectGraphSummary } from \"@codesentinel/code-graph\";\nimport { resolveTargetPath } from \"@codesentinel/core\";\n\nexport const runAnalyzeCommand = (inputPath: string | undefined): string => {\n const invocationCwd = process.env[\"INIT_CWD\"] ?? process.cwd();\n const target = resolveTargetPath(inputPath, invocationCwd);\n const summary = buildProjectGraphSummary({ projectPath: target.absolutePath });\n return JSON.stringify(summary, null, 2);\n};\n"],"mappings":"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","names":["nodeLowLink","program","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../../code-graph/src/domain/graph-model.ts","../../code-graph/src/domain/tarjan.ts","../../code-graph/src/domain/graph-metrics.ts","../../code-graph/src/infrastructure/typescript-project.ts","../../code-graph/src/application/build-project-graph-summary.ts","../../core/src/index.ts","../src/application/run-analyze-command.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { runAnalyzeCommand } from \"./application/run-analyze-command.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"codesentinel\")\n .description(\"Structural and evolutionary risk analysis for TypeScript/JavaScript codebases\")\n .version(\"0.1.1\");\n\nprogram\n .command(\"analyze\")\n .argument(\"[path]\", \"path to the project to analyze\")\n .action((path?: string) => {\n const output = runAnalyzeCommand(path);\n process.stdout.write(`${output}\\n`);\n });\n\nif (process.argv.length <= 2) {\n program.outputHelp();\n process.exit(0);\n}\n\nprogram.parse(process.argv);\n","export type NodeRecord = {\n id: string;\n absolutePath: string;\n relativePath: string;\n};\n\nexport type EdgeRecord = {\n from: string;\n to: string;\n};\n\nexport type GraphData = {\n nodes: readonly NodeRecord[];\n edges: readonly EdgeRecord[];\n adjacencyById: ReadonlyMap<string, readonly string[]>;\n};\n\nconst edgeKey = (from: string, to: string): string => `${from}\\u0000${to}`;\n\nexport const createGraphData = (\n nodes: readonly NodeRecord[],\n rawEdges: readonly EdgeRecord[],\n): GraphData => {\n const sortedNodes = [...nodes].sort((a, b) => a.id.localeCompare(b.id));\n const knownNodeIds = new Set(sortedNodes.map((node) => node.id));\n\n const uniqueEdgeMap = new Map<string, EdgeRecord>();\n for (const edge of rawEdges) {\n if (edge.from === edge.to) {\n continue;\n }\n\n if (!knownNodeIds.has(edge.from) || !knownNodeIds.has(edge.to)) {\n continue;\n }\n\n uniqueEdgeMap.set(edgeKey(edge.from, edge.to), edge);\n }\n\n const sortedEdges = [...uniqueEdgeMap.values()].sort((a, b) => {\n const fromCompare = a.from.localeCompare(b.from);\n if (fromCompare !== 0) {\n return fromCompare;\n }\n\n return a.to.localeCompare(b.to);\n });\n\n const adjacency = new Map<string, string[]>();\n for (const node of sortedNodes) {\n adjacency.set(node.id, []);\n }\n\n for (const edge of sortedEdges) {\n adjacency.get(edge.from)?.push(edge.to);\n }\n\n const adjacencyById = new Map<string, readonly string[]>();\n for (const [nodeId, targets] of adjacency.entries()) {\n adjacencyById.set(nodeId, [...targets]);\n }\n\n return {\n nodes: sortedNodes,\n edges: sortedEdges,\n adjacencyById,\n };\n};\n","type TarjanResult = {\n components: readonly (readonly string[])[];\n};\n\nexport const runTarjanScc = (adjacencyById: ReadonlyMap<string, readonly string[]>): TarjanResult => {\n let index = 0;\n const indices = new Map<string, number>();\n const lowLink = new Map<string, number>();\n const stack: string[] = [];\n const onStack = new Set<string>();\n const components: string[][] = [];\n\n const strongConnect = (nodeId: string): void => {\n indices.set(nodeId, index);\n lowLink.set(nodeId, index);\n index += 1;\n\n stack.push(nodeId);\n onStack.add(nodeId);\n\n const neighbors = adjacencyById.get(nodeId) ?? [];\n for (const nextId of neighbors) {\n if (!indices.has(nextId)) {\n strongConnect(nextId);\n const nodeLowLink = lowLink.get(nodeId);\n const nextLowLink = lowLink.get(nextId);\n if (nodeLowLink !== undefined && nextLowLink !== undefined && nextLowLink < nodeLowLink) {\n lowLink.set(nodeId, nextLowLink);\n }\n continue;\n }\n\n if (onStack.has(nextId)) {\n const nodeLowLink = lowLink.get(nodeId);\n const nextIndex = indices.get(nextId);\n if (nodeLowLink !== undefined && nextIndex !== undefined && nextIndex < nodeLowLink) {\n lowLink.set(nodeId, nextIndex);\n }\n }\n }\n\n const nodeLowLink = lowLink.get(nodeId);\n const nodeIndex = indices.get(nodeId);\n if (nodeLowLink === undefined || nodeIndex === undefined || nodeLowLink !== nodeIndex) {\n return;\n }\n\n const component: string[] = [];\n for (;;) {\n const popped = stack.pop();\n if (popped === undefined) {\n break;\n }\n\n onStack.delete(popped);\n component.push(popped);\n if (popped === nodeId) {\n break;\n }\n }\n\n component.sort((a, b) => a.localeCompare(b));\n components.push(component);\n };\n\n const nodeIds = [...adjacencyById.keys()].sort((a, b) => a.localeCompare(b));\n for (const nodeId of nodeIds) {\n if (!indices.has(nodeId)) {\n strongConnect(nodeId);\n }\n }\n\n components.sort((a, b) => {\n const firstA = a[0] ?? \"\";\n const firstB = b[0] ?? \"\";\n return firstA.localeCompare(firstB);\n });\n\n return { components };\n};\n","import type { FileDependency, GraphAnalysisSummary, GraphCycle, GraphMetrics } from \"@codesentinel/core\";\nimport type { GraphData } from \"./graph-model.js\";\nimport { runTarjanScc } from \"./tarjan.js\";\n\ntype DepthComputation = {\n depthByNodeId: ReadonlyMap<string, number>;\n graphDepth: number;\n cycles: readonly GraphCycle[];\n};\n\nconst hasSelfLoop = (nodeId: string, adjacencyById: ReadonlyMap<string, readonly string[]>): boolean => {\n const targets = adjacencyById.get(nodeId) ?? [];\n return targets.includes(nodeId);\n};\n\nconst computeCyclesAndDepth = (graph: GraphData): DepthComputation => {\n const { components } = runTarjanScc(graph.adjacencyById);\n\n const cycles: GraphCycle[] = [];\n const componentByNodeId = new Map<string, number>();\n components.forEach((component, index) => {\n for (const nodeId of component) {\n componentByNodeId.set(nodeId, index);\n }\n\n if (component.length > 1) {\n cycles.push({ nodes: [...component] });\n return;\n }\n\n const onlyNode = component[0];\n if (onlyNode !== undefined && hasSelfLoop(onlyNode, graph.adjacencyById)) {\n cycles.push({ nodes: [...component] });\n }\n });\n\n const dagOutgoing = new Map<number, Set<number>>();\n const inDegree = new Map<number, number>();\n\n for (let i = 0; i < components.length; i += 1) {\n dagOutgoing.set(i, new Set());\n inDegree.set(i, 0);\n }\n\n for (const edge of graph.edges) {\n const fromComponent = componentByNodeId.get(edge.from);\n const toComponent = componentByNodeId.get(edge.to);\n\n if (fromComponent === undefined || toComponent === undefined || fromComponent === toComponent) {\n continue;\n }\n\n const outgoing = dagOutgoing.get(fromComponent);\n if (outgoing?.has(toComponent) === true) {\n continue;\n }\n\n outgoing?.add(toComponent);\n inDegree.set(toComponent, (inDegree.get(toComponent) ?? 0) + 1);\n }\n\n const queue: number[] = [];\n const depthByComponent = new Map<number, number>();\n\n for (let i = 0; i < components.length; i += 1) {\n if ((inDegree.get(i) ?? 0) === 0) {\n queue.push(i);\n depthByComponent.set(i, 0);\n }\n }\n\n let cursor = 0;\n while (cursor < queue.length) {\n const componentId = queue[cursor];\n cursor += 1;\n\n if (componentId === undefined) {\n continue;\n }\n\n const currentDepth = depthByComponent.get(componentId) ?? 0;\n const outgoing = dagOutgoing.get(componentId) ?? new Set<number>();\n\n for (const nextComponent of outgoing) {\n const nextDepth = depthByComponent.get(nextComponent) ?? 0;\n if (currentDepth + 1 > nextDepth) {\n depthByComponent.set(nextComponent, currentDepth + 1);\n }\n\n const remainingIncoming = (inDegree.get(nextComponent) ?? 0) - 1;\n inDegree.set(nextComponent, remainingIncoming);\n if (remainingIncoming === 0) {\n queue.push(nextComponent);\n }\n }\n }\n\n const depthByNodeId = new Map<string, number>();\n let graphDepth = 0;\n\n components.forEach((component, componentId) => {\n const componentDepth = depthByComponent.get(componentId) ?? 0;\n if (componentDepth > graphDepth) {\n graphDepth = componentDepth;\n }\n\n for (const nodeId of component) {\n depthByNodeId.set(nodeId, componentDepth);\n }\n });\n\n cycles.sort((a, b) => {\n const firstA = a.nodes[0] ?? \"\";\n const firstB = b.nodes[0] ?? \"\";\n return firstA.localeCompare(firstB);\n });\n\n return {\n depthByNodeId,\n graphDepth,\n cycles,\n };\n};\n\nexport const createGraphAnalysisSummary = (\n targetPath: string,\n graph: GraphData,\n): GraphAnalysisSummary => {\n const fanInById = new Map<string, number>();\n const fanOutById = new Map<string, number>();\n\n for (const node of graph.nodes) {\n fanInById.set(node.id, 0);\n fanOutById.set(node.id, graph.adjacencyById.get(node.id)?.length ?? 0);\n }\n\n for (const edge of graph.edges) {\n fanInById.set(edge.to, (fanInById.get(edge.to) ?? 0) + 1);\n }\n\n const { cycles, depthByNodeId, graphDepth } = computeCyclesAndDepth(graph);\n\n let maxFanIn = 0;\n let maxFanOut = 0;\n\n const files: FileDependency[] = graph.nodes.map((node) => {\n const fanIn = fanInById.get(node.id) ?? 0;\n const fanOut = fanOutById.get(node.id) ?? 0;\n\n if (fanIn > maxFanIn) {\n maxFanIn = fanIn;\n }\n\n if (fanOut > maxFanOut) {\n maxFanOut = fanOut;\n }\n\n return {\n id: node.id,\n relativePath: node.relativePath,\n directDependencies: graph.adjacencyById.get(node.id) ?? [],\n fanIn,\n fanOut,\n depth: depthByNodeId.get(node.id) ?? 0,\n };\n });\n\n const metrics: GraphMetrics = {\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n cycleCount: cycles.length,\n graphDepth,\n maxFanIn,\n maxFanOut,\n };\n\n return {\n targetPath,\n nodes: graph.nodes,\n edges: graph.edges,\n cycles,\n files,\n metrics,\n };\n};\n","import { extname, isAbsolute, relative, resolve } from \"node:path\";\nimport * as ts from \"typescript\";\nimport type { EdgeRecord, NodeRecord } from \"../domain/graph-model.js\";\n\ntype ParsedProject = {\n nodes: readonly NodeRecord[];\n edges: readonly EdgeRecord[];\n};\n\nconst SOURCE_EXTENSIONS = new Set([\".ts\", \".tsx\", \".mts\", \".cts\", \".js\", \".jsx\", \".mjs\", \".cjs\"]);\n\nconst normalizePath = (pathValue: string): string => pathValue.replaceAll(\"\\\\\", \"/\");\n\nconst isProjectSourceFile = (filePath: string, projectRoot: string): boolean => {\n const extension = extname(filePath);\n if (!SOURCE_EXTENSIONS.has(extension)) {\n return false;\n }\n\n const relativePath = relative(projectRoot, filePath);\n if (relativePath.startsWith(\"..\")) {\n return false;\n }\n\n return !relativePath.includes(\"node_modules\");\n};\n\nconst findProjectFiles = (projectRoot: string): readonly string[] => {\n const files = ts.sys.readDirectory(projectRoot, [...SOURCE_EXTENSIONS], undefined, undefined);\n return files.map((filePath) => resolve(filePath));\n};\n\nconst parseTsConfig = (projectRoot: string): { fileNames: readonly string[]; options: ts.CompilerOptions } => {\n const configPath = ts.findConfigFile(projectRoot, ts.sys.fileExists, \"tsconfig.json\");\n if (configPath === undefined) {\n return {\n fileNames: findProjectFiles(projectRoot),\n options: {\n allowJs: true,\n moduleResolution: ts.ModuleResolutionKind.NodeNext,\n },\n };\n }\n\n const parsedCommandLine = ts.getParsedCommandLineOfConfigFile(\n configPath,\n {},\n {\n ...ts.sys,\n onUnRecoverableConfigFileDiagnostic: () => {\n throw new Error(`Failed to parse TypeScript configuration at ${configPath}`);\n },\n },\n );\n\n if (parsedCommandLine === undefined) {\n throw new Error(`Failed to parse TypeScript configuration at ${configPath}`);\n }\n\n const fileNames = parsedCommandLine.fileNames.map((filePath) => resolve(filePath));\n if (fileNames.length === 0) {\n return {\n fileNames: findProjectFiles(projectRoot),\n options: parsedCommandLine.options,\n };\n }\n\n return {\n fileNames,\n options: parsedCommandLine.options,\n };\n};\n\nconst getSpecifierFromExpression = (expression: ts.Expression): string | undefined => {\n if (ts.isStringLiteral(expression)) {\n return expression.text;\n }\n\n if (ts.isNoSubstitutionTemplateLiteral(expression)) {\n return expression.text;\n }\n\n return undefined;\n};\n\nconst hasRuntimeImport = (importDeclaration: ts.ImportDeclaration): boolean => {\n const importClause = importDeclaration.importClause;\n if (importClause === undefined) {\n return true;\n }\n\n if (importClause.isTypeOnly) {\n return false;\n }\n\n if (importClause.name !== undefined) {\n return true;\n }\n\n const namedBindings = importClause.namedBindings;\n if (namedBindings === undefined) {\n return false;\n }\n\n if (ts.isNamespaceImport(namedBindings)) {\n return true;\n }\n\n if (namedBindings.elements.length === 0) {\n return true;\n }\n\n return namedBindings.elements.some((element) => !element.isTypeOnly);\n};\n\nconst extractModuleSpecifiers = (sourceFile: ts.SourceFile): readonly string[] => {\n const specifiers = new Set<string>();\n\n const visit = (node: ts.Node): void => {\n if (ts.isImportDeclaration(node)) {\n if (hasRuntimeImport(node) && node.moduleSpecifier !== undefined) {\n const specifier = getSpecifierFromExpression(node.moduleSpecifier);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n return;\n }\n\n if (ts.isExportDeclaration(node)) {\n if (!node.isTypeOnly && node.moduleSpecifier !== undefined) {\n const specifier = getSpecifierFromExpression(node.moduleSpecifier);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n return;\n }\n\n if (ts.isCallExpression(node)) {\n if (node.expression.kind === ts.SyntaxKind.ImportKeyword && node.arguments.length > 0) {\n const firstArgument = node.arguments[0];\n if (firstArgument !== undefined) {\n const specifier = getSpecifierFromExpression(firstArgument);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n }\n\n if (ts.isIdentifier(node.expression) && node.expression.text === \"require\" && node.arguments.length > 0) {\n const firstArgument = node.arguments[0];\n if (firstArgument !== undefined) {\n const specifier = getSpecifierFromExpression(firstArgument);\n if (specifier !== undefined) {\n specifiers.add(specifier);\n }\n }\n }\n }\n\n ts.forEachChild(node, visit);\n };\n\n visit(sourceFile);\n return [...specifiers];\n};\n\nexport const parseTypescriptProject = (projectPath: string): ParsedProject => {\n const projectRoot = isAbsolute(projectPath) ? projectPath : resolve(projectPath);\n const { fileNames, options } = parseTsConfig(projectRoot);\n\n const sourceFilePaths = fileNames\n .filter((filePath) => isProjectSourceFile(filePath, projectRoot))\n .map((filePath) => normalizePath(resolve(filePath)));\n\n const uniqueSourceFilePaths = [...new Set(sourceFilePaths)].sort((a, b) => a.localeCompare(b));\n const sourceFilePathSet = new Set(uniqueSourceFilePaths);\n\n const program = ts.createProgram({\n rootNames: uniqueSourceFilePaths,\n options,\n });\n\n const nodeByAbsolutePath = new Map<string, NodeRecord>();\n for (const sourcePath of uniqueSourceFilePaths) {\n const relativePath = normalizePath(relative(projectRoot, sourcePath));\n const nodeId = relativePath;\n nodeByAbsolutePath.set(sourcePath, {\n id: nodeId,\n absolutePath: sourcePath,\n relativePath,\n });\n }\n\n const resolverCache = new Map<string, string | undefined>();\n const edges: EdgeRecord[] = [];\n\n for (const sourcePath of uniqueSourceFilePaths) {\n const sourceFile = program.getSourceFile(sourcePath);\n if (sourceFile === undefined) {\n continue;\n }\n\n const fromNode = nodeByAbsolutePath.get(sourcePath);\n if (fromNode === undefined) {\n continue;\n }\n\n const moduleSpecifiers = extractModuleSpecifiers(sourceFile);\n for (const specifier of moduleSpecifiers) {\n const cacheKey = `${sourcePath}\\u0000${specifier}`;\n let resolvedPath = resolverCache.get(cacheKey);\n\n if (resolvedPath === undefined && !resolverCache.has(cacheKey)) {\n const resolved = ts.resolveModuleName(specifier, sourcePath, options, ts.sys).resolvedModule;\n if (resolved !== undefined) {\n resolvedPath = normalizePath(resolve(resolved.resolvedFileName));\n }\n resolverCache.set(cacheKey, resolvedPath);\n }\n\n if (resolvedPath === undefined || !sourceFilePathSet.has(resolvedPath)) {\n continue;\n }\n\n const toNode = nodeByAbsolutePath.get(resolvedPath);\n if (toNode === undefined) {\n continue;\n }\n\n edges.push({ from: fromNode.id, to: toNode.id });\n }\n }\n\n return {\n nodes: [...nodeByAbsolutePath.values()],\n edges,\n };\n};\n","import type { GraphAnalysisSummary } from \"@codesentinel/core\";\nimport { createGraphData } from \"../domain/graph-model.js\";\nimport { createGraphAnalysisSummary } from \"../domain/graph-metrics.js\";\nimport { parseTypescriptProject } from \"../infrastructure/typescript-project.js\";\n\nexport type BuildProjectGraphSummaryInput = {\n projectPath: string;\n};\n\nexport const buildProjectGraphSummary = (\n input: BuildProjectGraphSummaryInput,\n): GraphAnalysisSummary => {\n const parsedProject = parseTypescriptProject(input.projectPath);\n const graphData = createGraphData(parsedProject.nodes, parsedProject.edges);\n return createGraphAnalysisSummary(input.projectPath, graphData);\n};\n","import { resolve } from \"node:path\";\n\nexport type AnalyzeTarget = {\n absolutePath: string;\n};\n\nexport type GraphNode = {\n id: string;\n absolutePath: string;\n relativePath: string;\n};\n\nexport type GraphEdge = {\n from: string;\n to: string;\n};\n\nexport type GraphCycle = {\n nodes: readonly string[];\n};\n\nexport type FileDependency = {\n id: string;\n relativePath: string;\n directDependencies: readonly string[];\n fanIn: number;\n fanOut: number;\n depth: number;\n};\n\nexport type GraphMetrics = {\n nodeCount: number;\n edgeCount: number;\n cycleCount: number;\n graphDepth: number;\n maxFanIn: number;\n maxFanOut: number;\n};\n\nexport type GraphAnalysisSummary = {\n targetPath: string;\n nodes: readonly GraphNode[];\n edges: readonly GraphEdge[];\n cycles: readonly GraphCycle[];\n files: readonly FileDependency[];\n metrics: GraphMetrics;\n};\n\nexport const resolveTargetPath = (\n inputPath: string | undefined,\n cwd: string = process.cwd(),\n): AnalyzeTarget => {\n const absolutePath = resolve(cwd, inputPath ?? \".\");\n return { absolutePath };\n};\n","import { buildProjectGraphSummary } from \"@codesentinel/code-graph\";\nimport { resolveTargetPath } from \"@codesentinel/core\";\n\nexport const runAnalyzeCommand = (inputPath: string | undefined): string => {\n const invocationCwd = process.env[\"INIT_CWD\"] ?? process.cwd();\n const target = resolveTargetPath(inputPath, invocationCwd);\n const summary = buildProjectGraphSummary({ projectPath: target.absolutePath });\n return JSON.stringify(summary, null, 2);\n};\n"],"mappings":"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","names":["nodeLowLink","program","resolve"]}
|