Creating a custom stack pack

In 1.91.1 a custom pack only takes effect when its name matches a built-in pack, and then it replaces that pack.yaml. Scaffold with paqad-ai packs create, check with packs validate, install with packs install.

  • Stack packs
  • Checked against paqad-ai 1.91.1
  • Reviewed 25 September 2026 by Eliyce

What a custom pack can do in 1.91.1

A custom pack is a stack pack you write yourself and install on your machine or in one project. A stack pack is a folder with a pack.yaml settings file that describes a framework to Paqad (see What stack packs are).

In 1.91.1 a custom pack is useful in one way: to override a built-in pack. If your pack's name is the same as a built-in pack, such as laravel or react, Paqad uses your pack.yaml instead of the built-in one. Typical reasons are a different test command, extra folders left out of the code search index, a different security file map or your own conventions text in the stack documentation.

A pack with a new framework name loads, validates and appears in paqad-ai packs list, and stack detection does try its detection rules. But the project profile only accepts the 22 built-in framework names, so a new name cannot be recorded as one of your project's frameworks. Depending on what else is detected, onboarding either leaves it out or stops with a profile validation error. Rule files in a custom pack's rules/ folder are also not added to your project's rules: the rule resolver reads the built-in packs only.

What an override changes

An override replaces the whole pack.yaml, not single fields. These are the settings that then take effect from your file:

  • detection and traits: how stack detection recognises the framework and its add-on libraries.
  • test_runners: how tests are run and how their results are read.
  • docs.conventions_template: the conventions text copied into docs/instructions/stack/frameworks.md. The path is relative to your pack folder.
  • rag and ast.file_extensions: which files the code search index includes or skips.
  • pentest.file_check_map: which security review checks apply to which paths.
  • module_health: where your source code lives for the module map.
  • visual_evidence.frontend_globs: which files count as front-end changes.
  • mcp_defaults: which MCP servers are listed, but only from a global override (see Which pack wins when names match).

Because the whole file is replaced, start from a copy of the built-in pack's pack.yaml and change only what you need. The built-in file is in your installed paqad-ai package under runtime/capabilities/coding/stacks/<name>/pack.yaml.

Step 1: create the pack folder

Either copy the built-in pack folder, or scaffold a minimal one:

paqad-ai packs create my-stack

This creates my-stack/pack.yaml and my-stack/rules/conventions.md in the current folder. Use --destination <path> to create it elsewhere, --ecosystem <id> to set the ecosystem (default node) and --tier archetype for an archetype pack (default framework). The generated file looks like this:

name: my-stack
display_name: My Stack
ecosystem: node
version: 1.0.0
description: My Stack stack pack
maintainer: your-team
detection:
  manifests:
    - file: package.json
      packages: [my-stack]
toolchains:
  - ecosystem: node
    package_managers: [pnpm]
    lockfiles: [pnpm-lock.yaml]
docs:
  conventions_template: rules/conventions.md

Pack names must be lowercase letters, digits and single dashes, for example my-stack. To override a built-in pack, set name to that pack's name.

Step 2: validate it

paqad-ai packs validate ./my-stack

This is a deterministic check run by a script. It confirms that the required fields are present, that there are no unknown fields, that any template files the pack points to exist, that trait and test runner names are not repeated, and that test runner settings are consistent. A valid pack prints its name, "valid": true and any warnings. An invalid pack stops with an error listing each problem. Warnings (for example an unknown MCP server name or a testing framework with no matching test runner) do not make the pack invalid.

Step 3: install it

paqad-ai packs install ./my-stack --scope project
ScopeWhere the pack is copiedApplies to
global (default)~/.paqad/packs/<name>/, or the folder in the PAQAD_GLOBAL_PACKS_ROOT environment variableEvery project on this machine
project.paqad/packs/<name>/ in the projectThis project only

The source can be a local folder, a git URL, or a bare name when PAQAD_PACK_REGISTRY_URL is set (Paqad then fetches <registry>/<name>.git). Git sources are fetched over the network with git clone. The pack is validated before and after copying, and an existing pack with the same name in that scope is replaced.

Step 4: check that it is in effect

paqad-ai packs list

An override shows its source in brackets, for example [project], with override=true. Settings that feed generated files, such as the stack documentation, apply the next time Paqad regenerates them.

Removing a custom pack

paqad-ai packs remove my-stack --scope project

The default scope is global. Built-in packs cannot be removed; removing your override brings the built-in version back.

Something on this page out of date or unclear? Open an issue on GitHub and name the page.