What
Upgrade Next.js detection from "this project uses Next.js" to a rich architecture summary: which router, how many routes, how many server vs client components, middleware presence.
Why
The current scanner detects nextjs from package.json but says nothing about the architecture. Knowing "App Router with 23 routes and 6 client components" produces dramatically better skills than just "uses Next.js."
How
Edit src/lib/scanner.js. Add a probeNextjsArchitecture(repoPath) function that runs when nextjs is in the detected frameworks.
What to detect
Router type:
app/ directory (or src/app/) with layout.tsx/layout.js → App Router
pages/ directory (or src/pages/) → Pages Router
- Both present → Both (migration in progress)
Route counting (App Router):
- Glob for
app/**/page.tsx and app/**/page.js — each is a route
- Glob for
app/**/route.ts and app/**/route.js — each is an API endpoint
- Count dynamic routes: directories matching
[param], [...param], [[...param]]
- Count route groups: directories matching
(groupName)
Route counting (Pages Router):
- Every file directly under
pages/ (except _app, _document, _error) is a route
- Files under
pages/api/ are API routes
Server vs Client components (App Router only):
- Read the first line of every
.tsx/.jsx file under app/
- Files starting with
'use client' or "use client" → client component
- Everything else → server component (default)
Middleware:
middleware.ts or middleware.js at project root → Edge Middleware present
Implementation
function probeNextjsArchitecture(repoPath) {
const result = { router: null, routes: 0, apiRoutes: 0, serverComponents: 0, clientComponents: 0, hasMiddleware: false };
// Check both root and src/ for app/ and pages/
const appDir = findDir(repoPath, ['app', 'src/app']);
const pagesDir = findDir(repoPath, ['pages', 'src/pages']);
if (appDir && existsSync(join(appDir, 'layout.tsx')) || existsSync(join(appDir, 'layout.js'))) {
result.router = pagesDir ? 'both' : 'app';
// Count routes: walk app/ for page.tsx/page.js files
// Count API routes: walk app/ for route.ts/route.js files
// Count server vs client: read first line of .tsx/.jsx files
} else if (pagesDir) {
result.router = 'pages';
// Count files in pages/ (excluding _app, _document, _error)
// Count files in pages/api/
}
// Middleware
result.hasMiddleware = existsSync(join(repoPath, 'middleware.ts')) || existsSync(join(repoPath, 'middleware.js'));
return result;
}
// Helper to find a directory from a list of candidates
function findDir(repoPath, candidates) {
for (const candidate of candidates) {
const full = join(repoPath, candidate);
if (existsSync(full) && isDir(full)) return full;
}
return null;
}
Call from scanRepo() when nextjs is in frameworks:
if (result.frameworks.includes('nextjs')) {
result.nextjsArchitecture = probeNextjsArchitecture(repoPath);
}
Display in src/commands/scan.js:
Next.js: App Router — 23 routes, 4 API endpoints, 47 server / 6 client components, middleware
Performance note
The 'use client' check reads the first line of each .tsx/.jsx file under app/. For a project with 200 components, that's 200 readFileSync calls reading ~100 bytes each. This is fast (<50ms).
Files to change
src/lib/scanner.js — add probeNextjsArchitecture(), call from scanRepo()
src/commands/scan.js — display architecture details
tests/scanner.test.js — add tests for App Router, Pages Router, both, middleware
Acceptance criteria
What
Upgrade Next.js detection from "this project uses Next.js" to a rich architecture summary: which router, how many routes, how many server vs client components, middleware presence.
Why
The current scanner detects
nextjsfrompackage.jsonbut says nothing about the architecture. Knowing "App Router with 23 routes and 6 client components" produces dramatically better skills than just "uses Next.js."How
Edit
src/lib/scanner.js. Add aprobeNextjsArchitecture(repoPath)function that runs whennextjsis in the detected frameworks.What to detect
Router type:
app/directory (orsrc/app/) withlayout.tsx/layout.js→ App Routerpages/directory (orsrc/pages/) → Pages RouterRoute counting (App Router):
app/**/page.tsxandapp/**/page.js— each is a routeapp/**/route.tsandapp/**/route.js— each is an API endpoint[param],[...param],[[...param]](groupName)Route counting (Pages Router):
pages/(except_app,_document,_error) is a routepages/api/are API routesServer vs Client components (App Router only):
.tsx/.jsxfile underapp/'use client'or"use client"→ client componentMiddleware:
middleware.tsormiddleware.jsat project root → Edge Middleware presentImplementation
Call from
scanRepo()whennextjsis in frameworks:Display in
src/commands/scan.js:Performance note
The
'use client'check reads the first line of each.tsx/.jsxfile underapp/. For a project with 200 components, that's 200readFileSynccalls reading ~100 bytes each. This is fast (<50ms).Files to change
src/lib/scanner.js— addprobeNextjsArchitecture(), call fromscanRepo()src/commands/scan.js— display architecture detailstests/scanner.test.js— add tests for App Router, Pages Router, both, middlewareAcceptance criteria
npm testpassesapp/at root andsrc/app/