@hyperfrontend/project-scope/heuristics

Heuristics Module

The heuristics module provides intelligent detection of project characteristics using multiple signals. It analyzes project structure, configuration files, dependencies, and code patterns to make accurate determinations about project type, frameworks, entry points, and dependency graphs.

Capabilities

Project Type Detection

Determine if a project is an application, library, e2e test suite, CLI tool, or plugin.

import { detectProjectType } from '@hyperfrontend/project-scope'

const result = detectProjectType('./my-project')
console.log(result.type) // 'library' | 'application' | 'e2e' | 'tool' | 'plugin'
console.log(result.confidence) // 85
console.log(result.evidence) // [{ factor: 'exports', confidence: 20, description: '...' }]

Detection Factors

Factor Signals Confidence Impact
Package name -lib, -app, -e2e, -cli suffixes 15-30
Exports field Has exports, main, or module +20 for library
Bin field Has CLI executable definition +40 for tool
Entry points server.ts vs index.ts patterns 20-30
Directory structure public/, pages/, lib/, cypress/ 10-20
Framework presence Frontend/backend frameworks +20 for application
E2E frameworks Cypress, Playwright, Puppeteer +25 for e2e

Framework Identification

Comprehensive framework detection with confidence scoring.

import { identifyFrameworks } from '@hyperfrontend/project-scope'

const result = identifyFrameworks('./my-react-app')

console.log(result.summary) // 'React + Next.js with Jest'
console.log(result.primary?.name) // 'React'
console.log(result.frontend) // [{ id: 'react', name: 'React', ... }]
console.log(result.backend) // [{ id: 'express', name: 'Express', ... }]
console.log(result.metaFrameworks) // [{ id: 'nextjs', name: 'Next.js', ... }]
console.log(result.testing) // [{ id: 'jest', name: 'Jest', ... }]

// Stack summary for quick access
console.log(result.stack.frontend) // ['react', 'nextjs']
console.log(result.stack.testing) // ['jest']
console.log(result.stack.build) // ['webpack']
console.log(result.stack.linting) // ['eslint', 'prettier']

Entry Point Discovery

Find application entry points from package.json and conventions.

import { discoverEntryPoints } from '@hyperfrontend/project-scope'

const entryPoints = discoverEntryPoints('./my-app')

for (const entry of entryPoints) {
  console.log(`${entry.path} (${entry.type}) - ${entry.confidence}% confidence`)
}
// Output:
// src/index.ts (main) - 100% confidence
// src/cli.ts (cli) - 85% confidence
// src/server.ts (server) - 80% confidence

Entry Point Sources

Source Priority Examples
package.json fields 100% main, module, browser, bin, exports
Convention patterns 80-90% src/index.ts, src/main.ts, src/server.ts
Framework-specific 85% Next.js pages, Angular modules

Dependency Graph Analysis

Build internal dependency graphs from source code.

import { buildDependencyGraph } from '@hyperfrontend/project-scope'

const graph = buildDependencyGraph('./my-lib')

console.log('Root files:', graph.roots) // Files not imported by anything
console.log('Leaf files:', graph.leaves) // Files that don't import anything
console.log('Total nodes:', graph.nodes.size)

// Examine dependencies
const node = graph.nodes.get('src/utils/helper.ts')
console.log('Depends on:', node?.dependencies) // ['src/utils/base.ts']
console.log('Used by:', node?.dependents) // ['src/index.ts', 'src/cli.ts']

Dependency Extraction

Supports multiple import/export patterns:

  • ES imports: import { x } from './module'
  • Dynamic imports: import('./module')
  • CommonJS: require('./module')
  • Re-exports: export * from './module'

Package Dependencies

Analyze npm dependencies from package.json.

import { getProjectDependencies } from '@hyperfrontend/project-scope'

const deps = getProjectDependencies('./my-project')

console.log('Runtime:', deps.runtime) // ['react', 'lodash']
console.log('Development:', deps.development) // ['typescript', 'jest']
console.log('Peer:', deps.peer) // ['react']
console.log('Total:', deps.total) // 25

Caching

All detection functions use intelligent caching:

  • TTL: 60 seconds (appropriate for active development)
  • Automatic invalidation: Cache keys include all relevant options
  • Skip cache: Pass { skipCache: true } for fresh results
// Force fresh detection
const result = detectProjectType('./project', { skipCache: true })

Design Principles

  1. Multi-signal detection: Never rely on a single indicator
  2. Confidence scoring: All detections include confidence percentages
  3. Evidence tracking: Understand why a detection was made
  4. Graceful degradation: Always returns a result, even with low confidence
  5. Performance: Aggressive caching with appropriate TTLs

API Reference

ƒ Functions

§function

buildDependencyGraph(projectPath: string, options?: BuildGraphOptions): DependencyGraph

Build dependency graph from source files.
Analyzes imports/exports in source files to build a graph of internal dependencies.

Parameters

NameTypeDescription
§projectPath
string
Absolute path to project root
§options?
BuildGraphOptions
Configuration for graph building

Returns

DependencyGraph
Dependency graph with nodes, roots, and leaves

Example

Building a dependency graph

import { buildDependencyGraph } from '@hyperfrontend/project-scope'

const graph = buildDependencyGraph('./my-lib')
console.log('Root files:', graph.roots)   // Files not imported by anything
console.log('Leaf files:', graph.leaves)  // Files that don't import anything
console.log('Total nodes:', graph.nodes.size)

// Examine a specific node's dependencies
const node = graph.nodes.get('src/utils/helper.ts')
console.log('Depends on:', node?.dependencies)
console.log('Used by:', node?.dependents)
§function

clearEntryPointCache(): void

Clear the entry point discovery cache.
Useful for testing or when the project files have changed.

Example

Clearing the entry point cache

import { clearEntryPointCache } from '@hyperfrontend/project-scope'

// Reset cache before re-analyzing after file changes
clearEntryPointCache()
§function

clearFrameworkIdentificationCache(): void

Clear the framework identification cache.
Useful for testing or when the project files have changed.

Example

Clearing the framework cache

import { clearFrameworkIdentificationCache } from '@hyperfrontend/project-scope'

// Reset cache before re-identifying frameworks
clearFrameworkIdentificationCache()
§function

detectProjectType(projectPath: string, options?: DetectProjectTypeOptions): ProjectTypeDetection

Detect the type of a project based on its structure and configuration.
Uses multiple heuristics including:
  • Package name patterns
  • Exports/main/module fields
  • Binary (bin) field
  • Entry point patterns
  • Testing framework presence
  • Directory structure
  • Framework detection
  • NX project type field

Parameters

NameTypeDescription
§projectPath
string
Project directory path
§options?
DetectProjectTypeOptions
Detection options

Returns

ProjectTypeDetection
Project type detection result with confidence score

Example

Detecting project type

import { detectProjectType } from '@hyperfrontend/project-scope'

const result = detectProjectType('./my-lib')
console.log(result.type)       // 'library' | 'application' | 'e2e' | 'tool' | 'plugin'
console.log(result.confidence) // 85
console.log(result.evidence)   // [{ factor: 'exports', confidence: 20, ... }]
§function

discoverEntryPoints(projectPath: string, options?: DiscoverEntryPointsOptions): EntryPointInfo[]

Discover entry points in project.
Analyzes package.json fields (main, module, bin, exports), convention-based patterns, and framework-specific entries.
Results are cached for 60 seconds per project path and options to avoid redundant file system operations on repeated calls.

Parameters

NameTypeDescription
§projectPath
string
Project directory path
§options?
DiscoverEntryPointsOptions
Discovery options

Returns

EntryPointInfo[]
Array of discovered entry points sorted by confidence

Example

Discovering project entry points

import { discoverEntryPoints } from '@hyperfrontend/project-scope'

const entryPoints = discoverEntryPoints('./my-app')
for (const entry of entryPoints) {
  console.log(`${entry.path} (${entry.type}) - ${entry.confidence}% confidence`)
}
// Output:
// src/index.ts (main) - 100% confidence
// src/cli.ts (cli) - 85% confidence
§function

findCircularDependencies(graph: DependencyGraph): CircularDependency[]

Find circular dependencies in graph using DFS.

Parameters

NameTypeDescription
§graph
DependencyGraph
Dependency graph

Returns

CircularDependency[]
Array of circular dependencies found

Example

Finding circular dependencies

import { buildDependencyGraph, findCircularDependencies } from '@hyperfrontend/project-scope'

const graph = buildDependencyGraph('/workspace')
const cycles = findCircularDependencies(graph)
cycles.forEach(c => console.log(`Cycle: ${c.cycle.join(' -> ')}`))
§function

getProjectDependencies(projectPath: string): ProjectDependencies

Collect all dependencies from package.json grouped by category.

Parameters

NameTypeDescription
§projectPath
string
Project directory

Returns

ProjectDependencies
Dependencies grouped by runtime, dev, peer, and optional

Example

Getting project dependencies

import { getProjectDependencies } from '@hyperfrontend/project-scope'

const deps = getProjectDependencies('/path/to/project')
console.log('Runtime:', deps.runtime)     // ['express', 'lodash']
console.log('Dev:', deps.development)     // ['jest', 'typescript']
console.log('Total:', deps.total)         // 15
§function

identifyFrameworks(projectPath: string, options?: IdentifyFrameworksOptions): FrameworkIdentification

Identify all frameworks in project.
Runs all technology detectors and aggregates results into a comprehensive framework identification with confidence scoring.

Parameters

NameTypeDescription
§projectPath
string
Project directory path
§options?
IdentifyFrameworksOptions
Identification options

Returns

FrameworkIdentification
Framework identification result

Example

Identifying all frameworks in project

import { identifyFrameworks } from '@hyperfrontend/project-scope'

const result = identifyFrameworks('./my-react-app')
console.log(result.summary)      // 'React + Next.js with Jest'
console.log(result.primary?.name) // 'React'
console.log(result.stack.frontend) // ['react', 'nextjs']
console.log(result.stack.testing)  // ['jest']
§function

usesFramework(projectPath: string, frameworkId: string, minConfidence: number): boolean

Check if a project uses a specific framework.

Parameters

NameTypeDescription
§projectPath
string
Project directory path
§frameworkId
string
Framework identifier to check
§minConfidence
number
Minimum confidence threshold (default: 50)
(default: 50)

Returns

boolean
True if the framework is detected with sufficient confidence

Example

Checking for a specific framework

import { usesFramework } from '@hyperfrontend/project-scope'

if (usesFramework('/path/to/project', 'react', 70)) {
  console.log('Project uses React with high confidence')
}

Interfaces

§interface

BuildGraphOptions

Options for dependency graph building.

Properties

§extensions?:string[]
File extensions to analyze
§includeExternal?:boolean
Include node_modules imports
§maxDepth?:number
Maximum depth to traverse
§interface

CircularDependency

Circular dependency information.

Properties

§cycle:string[]
Ordered list of files in cycle
§length:number
Cycle length
§interface

DetectProjectTypeOptions

Options for project type detection.

Properties

§skipTechDetection?:boolean
Skip technology detection (faster but less accurate)
§interface

DiscoverEntryPointsOptions

Options for entry point discovery.

Properties

§includeFrameworkEntries?:boolean
Include framework-specific entries (e.g., Next.js pages)
§maxDepth?:number
Maximum depth for file search
§skipCache?:boolean
Skip cache lookup (force fresh detection)
§interface

ExtendedEntryPointInfo

Extended entry point info with source.

Properties

§confidence:number
Detection confidence (0-100)
§path:string
File path
§source:EntryPointSource
How the entry point was discovered
§type:"main" | "app" | "server" | "cli" | "test"
Entry point type
§interface

FrameworkIdentification

Framework identification result.

Properties

§backend:FrameworkInfo[]
Backend frameworks
§frontend:FrameworkInfo[]
Frontend frameworks
§metaFrameworks:FrameworkInfo[]
Meta-frameworks (Next.js, Nuxt, etc.)
§primary?:FrameworkInfo
Primary framework (highest confidence)
§stack:StackSummary
Stack summary
§summary:string
Summary string (e.g., "React + Next.js with Jest")
§testing:TestingInfo[]
Testing frameworks
§interface

IdentifyFrameworksOptions

Options for framework identification.

Properties

§minConfidence?:number
Minimum confidence threshold (0-100)
§skipCache?:boolean
Skip cache lookup (force fresh detection)
§interface

ProjectDependencies

Project dependencies categorized.

Properties

§development:string[]
Development dependencies
§optional:string[]
Optional dependencies
§peer:string[]
Peer dependencies
§runtime:string[]
Production dependencies
§total:number
Total count
§interface

ProjectTypeDetection

Project type detection result.

Properties

§confidence:number
Detection confidence (0-100)
§evidence:TypeEvidence[]
Evidence collected
§secondaryTypes:ProjectType[]
Secondary types
§type:ProjectType
Primary project type
§interface

StackSummary

Stack summary for a project.

Properties

§backend:string[]
Backend framework IDs
§build:string[]
Build tool IDs
§frontend:string[]
Frontend framework IDs
§linting:string[]
Linting tool IDs
§testing:string[]
Testing framework IDs
§typeSystem:string[]
Type system IDs
§interface

TypeEvidence

Type evidence for detection.

Properties

§confidence:number
Confidence contribution
§description:string
Description
§factor:string
Evidence factor

Types

§type

EntryPointSource

Entry point source information. Describes how an entry point was discovered.
type EntryPointSource = PackageJsonEntrySource | ConventionEntrySource | FrameworkEntrySource | ConfigEntrySource
§type

EntryPointType

Supported entry point type enumeration.
type EntryPointType = "main" | "app" | "server" | "cli" | "test"

Variables

§type

ENTRY_POINT_PATTERNS

Common entry point patterns by project type. Used for convention-based entry point discovery.