What stack detection does
Stack detection is how Paqad works out which languages, frameworks and tools your project uses, so it can copy the right rules and suggest the right commands. It runs during paqad-ai onboard, paqad-ai join and paqad-ai refresh --stack.
It is a script. It reads files and applies fixed rules; no AI model is asked. The same files give the same result on every machine.
Which files it reads
Paqad has nine readers, called parsers, one per package ecosystem. Each knows the manifest (the file where you list dependencies) and the lock file (the file where your package manager pins exact versions):
| Ecosystem | Manifest files | Lock files |
|---|---|---|
| Node (pnpm) | package.json | pnpm-lock.yaml |
| Node (npm) | package.json | package-lock.json |
| PHP | composer.json | composer.lock |
| Python | requirements.txt, pyproject.toml, Pipfile, setup.py | Pipfile.lock, poetry.lock, uv.lock |
| Ruby | Gemfile | Gemfile.lock |
| JVM (Java, Kotlin) | build.gradle, build.gradle.kts, pom.xml | gradle.lockfile |
| Go | go.mod | go.sum |
| Rust | Cargo.toml | Cargo.lock |
| Dart and Flutter | pubspec.yaml | pubspec.lock |
Where an ecosystem lists several manifest names, the parser uses the first one it finds in the order shown. It also looks for Docker and Compose files (Dockerfile, docker-compose.yml, compose.yaml and similar) to note the docker and compose traits.
Projects with several apps
Paqad does not only look at the top folder. It scans up to five folder levels down for project folders, skips folders that git ignores, and reads each project it finds. In a repository with several applications it picks a primary one and still records the frameworks it found in the others.
How versions are recorded
For each dependency, Paqad records the version your lock file pins when a lock file is present, and otherwise the version range written in the manifest. For a set of key packages (for example laravel/framework, react, vue, next, nuxt, tailwindcss and flutter) it also stores a version band: the major version, written as a range such as ^11. Bands let Paqad notice a major upgrade later. Commit your lock files so every machine records the same versions.
How frameworks are recognised
Each built-in pack has detection rules in its pack.yaml. The Laravel pack, for example, matches when composer.json lists laravel/framework, and also when an artisan file exists. Every rule that matches adds a signal. Each pack also has a priority number: the matching pack with the highest priority comes first, and among equal priorities the one with more signals. A pack can exclude another, so a Next.js project is not also treated as plain React, and a NestJS project not also as plain Express. Packs also declare traits, such as inertia, pest or tailwind, that switch on extra rules.
Framework packs are tried first: laravel, react, vue, nextjs, nestjs, express, angular, svelte, astro, django, fastapi, flask, rails, spring-boot, go-web, rust-web, dotnet, flutter and kotlin-android. If none match, Paqad tries the project-shape packs node-cli, node-library and node-service. Packs you add yourself take part too (see custom packs).
When detection is unsure
Paqad rates its result as high, medium or low confidence. One signal for the chosen pack gives low confidence, two or more give high, and a repository with several applications gives medium. When the top packs tie, no stack is chosen. In an interactive terminal, onboarding then asks you to choose the stack from a list. Without a terminal, onboarding uses what it can and, if it still cannot settle on a stack, stops with a message asking you to pass --stack (and any --capability traits). If no code framework is found at all, the project is set up for content and documentation work only.
Where the results are stored
.paqad/detection-report.json: the matched packs, traits, confidence, and each signal with the file that produced it..paqad/stack-snapshot.json: every package and version found, plus a fingerprint of each manifest and lock file. Paqad re-reads your files only when a fingerprint changes.stack_profilein.paqad/project-profile.yaml: the frameworks, traits, package managers and version bands the rest of Paqad uses.
The first two are per-machine files that git ignores. A teammate who clones the project creates them with paqad-ai join.
Running detection again
After you add or remove a framework or upgrade a major version, run:
paqad-ai refresh --stack
This re-runs detection, records what changed (see Drift detection), rewrites the stack documents in docs/instructions/stack/, and updates the profile. Keeping Paqad's files current covers what else it changes.