peer-ai 1.0.0-next.0

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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +403 -0
  3. package/dist/assess.d.ts +102 -0
  4. package/dist/assess.js +545 -0
  5. package/dist/check.d.ts +30 -0
  6. package/dist/check.js +253 -0
  7. package/dist/checks.d.ts +15 -0
  8. package/dist/checks.js +15 -0
  9. package/dist/cli.d.ts +10 -0
  10. package/dist/cli.js +231 -0
  11. package/dist/detect.d.ts +42 -0
  12. package/dist/detect.js +459 -0
  13. package/dist/doctor.d.ts +36 -0
  14. package/dist/doctor.js +297 -0
  15. package/dist/document.d.ts +30 -0
  16. package/dist/document.js +72 -0
  17. package/dist/enforcers.d.ts +6 -0
  18. package/dist/enforcers.js +307 -0
  19. package/dist/feedback.d.ts +67 -0
  20. package/dist/feedback.js +209 -0
  21. package/dist/files.d.ts +1 -0
  22. package/dist/files.js +72 -0
  23. package/dist/init.d.ts +31 -0
  24. package/dist/init.js +158 -0
  25. package/dist/mcp.d.ts +13 -0
  26. package/dist/mcp.js +247 -0
  27. package/dist/package-info.d.ts +4 -0
  28. package/dist/package-info.js +6 -0
  29. package/dist/pipeline.d.ts +82 -0
  30. package/dist/pipeline.js +265 -0
  31. package/dist/prompter.d.ts +23 -0
  32. package/dist/prompter.js +56 -0
  33. package/dist/render.d.ts +58 -0
  34. package/dist/render.js +557 -0
  35. package/dist/report.d.ts +3 -0
  36. package/dist/report.js +93 -0
  37. package/dist/routing.d.ts +24 -0
  38. package/dist/routing.js +121 -0
  39. package/dist/ruff.d.ts +19 -0
  40. package/dist/ruff.js +64 -0
  41. package/dist/standards.d.ts +46 -0
  42. package/dist/standards.js +130 -0
  43. package/dist/state.d.ts +22 -0
  44. package/dist/state.js +56 -0
  45. package/dist/test-helpers.d.ts +16 -0
  46. package/dist/test-helpers.js +62 -0
  47. package/dist/work.d.ts +147 -0
  48. package/dist/work.js +357 -0
  49. package/package.json +45 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Qudus Lawal
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,403 @@
1
+ # peer-ai
2
+
3
+ **Keeps AI coding tools to a senior team's standard: planning, testing, security and compliance, with proof of every check.**
4
+
5
+ This package is Peer AI's command-line tool and its MCP server, the connection AI tools use to follow Peer AI's way of working. It works with Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI and any tool that reads `AGENTS.md`. To learn what Peer AI does for a project, read the [project's README](https://github.com/AbuMahir980/peer-ai#readme).
6
+
7
+ > **Pre-release.** Needs Node.js 24 or newer, on macOS, Linux or Windows.
8
+
9
+ ## Start
10
+
11
+ In your project's folder:
12
+
13
+ ```bash
14
+ npx peer-ai init
15
+ npx peer-ai assess
16
+ npx peer-ai render
17
+ ```
18
+
19
+ Then open the project in your AI tool and ask for work in plain words. In a Node project, you can pin the version instead, and your AI tools then start that copy:
20
+
21
+ ```bash
22
+ npm install --save-dev peer-ai
23
+ ```
24
+
25
+ ## Commands
26
+
27
+ | Command | What it does |
28
+ |---------|--------------|
29
+ | [`peer-ai init`](#peer-ai-init) | Sets up Peer AI in a repository: one config file, from what it detects |
30
+ | [`peer-ai assess`](#peer-ai-assess) | Maps what the project has and what its stage still needs |
31
+ | [`peer-ai render`](#peer-ai-render) | Connects each AI tool: instructions, the MCP server and the skills |
32
+ | [`peer-ai doctor`](#peer-ai-doctor) | Checks the setup and says how to fix what isn't right |
33
+ | [`peer-ai check`](#peer-ai-check) | The CI gate: fails when work claims more than its record shows |
34
+ | [`peer-ai check-report`](#peer-ai-check-report) | Checks a review's report, as the `record_review` tool does |
35
+ | [`peer-ai check-document`](#peer-ai-check-document) | Checks a document against its skill's template |
36
+ | [`peer-ai feedback`](#peer-ai-feedback) | Lists, sends or drops the feedback drafts your AI tool wrote about Peer AI |
37
+ | [`peer-ai mcp`](#peer-ai-mcp) | Starts the MCP server that AI tools connect to |
38
+
39
+ ## `peer-ai init`
40
+
41
+ Sets up Peer AI in a repository by writing `peer-ai.config.json`.
42
+
43
+ ```bash
44
+ npx peer-ai init
45
+ ```
46
+
47
+ It reads the repository first and works out what it can:
48
+
49
+ | It finds | From |
50
+ |----------|------|
51
+ | The project's name and description | The project's own file, such as `package.json`, `pyproject.toml`, `Cargo.toml`, `go.mod`, `composer.json`, `pubspec.yaml` or `settings.gradle`, else the folder name |
52
+ | Whether the project is new or existing | Code and project files at the root |
53
+ | Each part and its stack | The repository root and every folder under `apps/`, `packages/`, `services/` and `libs/`. It recognises JavaScript and TypeScript frameworks (including Express, NestJS and Fastify backends), Python, Flutter, Android, the JVM, .NET, Swift, Go, Rust, Ruby, PHP and Elixir, and names the backend framework where there is one. |
54
+ | Infrastructure as code | Its files, wherever they are: Terraform or OpenTofu, Pulumi, AWS CDK, Helm, Kustomize, Serverless, AWS SAM, CloudFormation, Bicep and Ansible. Folders such as `infra/`, `deploy/`, `k8s/` and `helm/` are searched up to five levels deep, and there Docker and Kubernetes files count too. A `docker-compose.yml` at the root is local development, not infrastructure. |
55
+ | Where each part deploys | A platform's config file in that part's folder: Vercel, Netlify, Fly, Render, Railway, Cloudflare Workers, Firebase, AWS Amplify, Expo EAS, Serverless, Heroku, Google App Engine, fastlane, or a Dockerfile for a container |
56
+ | Existing CI | GitHub Actions, GitLab CI, Jenkins, Bitbucket Pipelines, Azure Pipelines, CircleCI, Buildkite, Drone, Travis, Cloud Build, Codemagic and Bitrise. Peer AI then extends that pipeline and never adds a second one. |
57
+ | The AI tools already set up | `CLAUDE.md`, `.cursor/`, `.codex/`, `.github/copilot-instructions.md`, `GEMINI.md` |
58
+ | The git host | The `origin` remote |
59
+
60
+ Then it asks four things: what you're building, whether the parts it found are right (or what kind of thing it is, if it found none), whether it's just you or a team, and what stage the project is at. It asks which AI tools you use only if it found none.
61
+
62
+ It never overwrites an existing `peer-ai.config.json`, and it never assumes anything it didn't find. A project with nothing to detect gets a part of kind `other` until you decide. A project with no infrastructure or CI yet simply has none in its config; `peer-ai assess` records those as gaps to fill when the project's stage calls for them.
63
+
64
+ ### Options
65
+
66
+ | Option | What it does |
67
+ |--------|--------------|
68
+ | `-y`, `--yes` | Accept what it detects instead of asking. Needed when there is no terminal, for example when an AI agent runs it. |
69
+ | `--dry-run` | Print the config instead of writing it |
70
+ | `--name <name>` | The project's name |
71
+ | `--stage <stage>` | `prototype`, `mvp` or `production` |
72
+ | `--team <team>` | `solo` or `team` |
73
+ | `--tool <tool>` | An AI tool you use; repeat it for several |
74
+
75
+ ### Exit codes
76
+
77
+ `0` success, `1` refused (a config already exists) or cancelled, `2` a usage error.
78
+
79
+ ## `peer-ai assess`
80
+
81
+ Maps what a project already has, and what its stage still needs. Run it on any project, at any point: a brief with no code, a prototype, or a product in production with no documents at all.
82
+
83
+ ```bash
84
+ npx peer-ai assess
85
+ ```
86
+
87
+ For each item on the project map it records one of four statuses, with the files that prove it:
88
+
89
+ | Status | Meaning |
90
+ |--------|---------|
91
+ | ✓ present | Found, with the evidence listed |
92
+ | ◐ partial | Some of it is there, for example tests in two of three parts, or linting with no written standard |
93
+ | ✗ missing | Not found |
94
+ | – not applicable | This project can't have it, for example a design for a project with no user interface |
95
+
96
+ The items are the requirements, architecture, threat model, specs, API contract, data model, data inventory, DPIA, design, standards, CI, environments, tests, load testing, infrastructure, observability, SLOs, runbooks and docs.
97
+
98
+ Documents are a by-product, never an entry fee. When there is no architecture document, `assess` works the architecture out from the code and marks it **inferred**, for you to confirm. The same goes for anything it judged not applicable.
99
+
100
+ Then it ranks the gaps by the project's stage (the `stage` in `peer-ai.config.json`, or `mvp` when there is no config):
101
+
102
+ - **prototype**: nothing is required.
103
+ - **mvp**: requirements, API contract, CI, tests, threat model, data inventory and docs.
104
+ - **production**: all of those, plus the architecture, specs, data model, DPIA, design, standards, environments, infrastructure, observability, SLOs, runbooks and load testing.
105
+
106
+ It also reports what the next stage will need, so nothing arrives as a surprise.
107
+
108
+ ### Compliance signals
109
+
110
+ `assess` reads the schema and migrations for personal data (emails, phone numbers, dates of birth, addresses, national ID numbers and more) and card-related names, and the dependency manifests for payment providers. It reports them as things to check, not as findings, and suggests the rule packs to consider, such as PCI DSS or the data protection law where you operate.
111
+
112
+ ### Traits to consider
113
+
114
+ A trait says what the product is or does, and switches on the rules for it (see `peer-ai-standards`). `assess` suggests the traits the code points to, each with what it found, and leaves out any the config already declares. A person decides: add the ones that fit to `project.traits`.
115
+
116
+ | Trait | Suggested by |
117
+ |-------|--------------|
118
+ | `money` | A payment provider, or card-related names in the schema |
119
+ | `safety-critical` | Names such as `allergens`, `medication` or `dosage` in the schema |
120
+ | `several-audiences` | Two or more apps sharing a backend, or names such as `tenant_id` or `organizationId` in the schema |
121
+ | `offline` | A service worker, or an offline or on-device database library such as Workbox, Dexie, WatermelonDB or sqflite |
122
+ | `real-time` | A live-connection library such as Socket.IO, a WebSocket library, Pusher, Ably or SignalR |
123
+ | `uploads` | An upload library such as Multer, `python-multipart`, Uppy or an image picker |
124
+ | `ai-features` | An AI model SDK such as OpenAI's, Anthropic's, the Vercel AI SDK, LangChain or Gemini's |
125
+
126
+ ### Stack profiles to consider
127
+
128
+ A stack profile says how to follow the core rules in one stack, and which tool enforces each automatic rule (RFC 0006). `assess` suggests the most specific profile for each part's stack, such as `react-native` for a part tagged `expo`, which brings React and TypeScript with it. It leaves out profiles the config already lists. Add the ones that fit to `standards.profiles`.
129
+
130
+ A listed profile applies to every part that names no stack, so `assess` also suggests a `stack` for each track that has none, from what it detects.
131
+
132
+ ### What it reads
133
+
134
+ The files git tracks, plus new files git doesn't ignore, so `.gitignore` is respected. Outside a git repository it walks the folder and skips dependency and build folders such as `node_modules/`, `.venv/` and `dist/`. A copy of the v0 playbook in `peer-ai/` is left out, and the report says so.
135
+
136
+ It writes the result to `.peer-ai/map.json`, which agents read to know where the project stands. Commit it.
137
+
138
+ ### Options
139
+
140
+ | Option | What it does |
141
+ |--------|--------------|
142
+ | `--target <stage>` | Assess against a stage other than the project's own, for example `--target production` to see what launch needs |
143
+ | `--json` | Print the project map as JSON instead of the report |
144
+ | `--dry-run` | Print the report without writing `.peer-ai/map.json` |
145
+
146
+ ### Exit codes
147
+
148
+ `0` success, `2` a usage error or an invalid `peer-ai.config.json`. Gaps are not errors: `assess` maps, and `peer-ai check` is the command that fails a build.
149
+
150
+ ## `peer-ai render`
151
+
152
+ Sets up each AI tool listed in `tools` in `peer-ai.config.json`, so every tool works the project the same way.
153
+
154
+ ```bash
155
+ npx peer-ai render
156
+ ```
157
+
158
+ | Tool | Instructions | MCP server registration |
159
+ |------|--------------|-------------------------|
160
+ | Claude Code | A block in `CLAUDE.md`, unless it imports `AGENTS.md` | `.mcp.json` |
161
+ | Codex | A block in `AGENTS.md` | Codex keeps servers in your own config, so render prints the `codex mcp add` command to run once. Codex asks before `run_verify` runs the project's verify command; render prints the setting that allows it without asking, if you choose to. |
162
+ | Cursor | `.cursor/rules/peer-ai.mdc`, a rule that always applies | `.cursor/mcp.json` |
163
+ | GitHub Copilot | A block in `.github/copilot-instructions.md` | `.vscode/mcp.json` |
164
+ | Gemini CLI | A block in `GEMINI.md`, unless it imports `AGENTS.md` | `.gemini/settings.json` |
165
+
166
+ `AGENTS.md` gets the block whenever a tool other than Claude Code is listed, when it already exists, or when `CLAUDE.md` imports it.
167
+
168
+ The instructions are short: how to work through the MCP server, the project's parts, its commands, its compliance packs and its own rules. The server serves the detail when it's needed, rather than every rule on every turn.
169
+
170
+ ### Skills
171
+
172
+ Render writes Peer AI's skills where the listed tools read them, each named `peer-ai-<skill>`, such as `peer-ai-security-review`. The prefix means a Peer AI skill never replaces one of a tool's own, such as Claude Code's `/code-review`.
173
+
174
+ | Folder | Read by | Written when the config lists |
175
+ |--------|---------|-------------------------------|
176
+ | `.claude/skills/` | Claude Code, Cursor, GitHub Copilot | Claude Code |
177
+ | `.agents/skills/` | Codex, Cursor, GitHub Copilot, Gemini CLI | Codex, Gemini CLI or another tool; or Cursor or Copilot without Claude Code |
178
+
179
+ - **They stay out of git.** They're rebuilt from the installed version, so a version bump stays a one-line change. Render adds them to `.gitignore` in a marked block.
180
+ - **After cloning,** run `peer-ai render` to write them. In a Node project, a `prepare` script can do it on install. `peer-ai doctor` warns when they're missing or out of date.
181
+ - **Only its own skills.** Render replaces and removes only folders named `peer-ai-…`. A skill of your own sits beside them untouched.
182
+ - **Cloud agents** start from a fresh clone, so render gives each one a setup step that writes the skills before it starts: `peer-ai render --skills --quiet`, which touches nothing committed.
183
+
184
+ | Tool | The setup step |
185
+ |------|----------------|
186
+ | Claude Code | A `SessionStart` hook in `.claude/settings.json`. It runs in cloud sessions and routines too, and keeps skills fresh on your machine after an upgrade. |
187
+ | Cursor | Added to the `start` command in `.cursor/environment.json` |
188
+ | GitHub Copilot | A step in `.github/workflows/copilot-setup-steps.yml`. An existing workflow is left to you, with the step to add. |
189
+ | Codex | Codex cloud keeps its setup script in its own settings, so render prints the line to add there |
190
+
191
+ Each edit keeps everything else in the file, and updates only Peer AI's own command.
192
+
193
+ - **Committing them instead.** Set `"skills": { "commit": true }` for a tool that can't run a setup step. Render then commits the skills, marks them as generated in `.gitattributes` so pull requests fold them away, and `render --check` checks them too.
194
+
195
+ What render changes, and what it leaves alone:
196
+
197
+ - **A block, not the file.** It writes between `<!-- peer-ai:start -->` and `<!-- peer-ai:end -->`, and never touches anything outside them. A file without the block gets it at the end.
198
+ - **One server entry, not the config.** It adds or updates the `peer-ai` entry and keeps every other server and setting. It refuses a file it can't read as plain JSON, such as one with comments, and prints the entry to add by hand.
199
+ - **The pinned version.** When `package.json` has `peer-ai` in its dependencies, tools start that copy; otherwise they start this exact version with `npx`.
200
+ - **Nothing twice.** A second run changes nothing. `peer-ai doctor` warns when these files or the skills no longer match the config.
201
+
202
+ ### Settings for the tools that enforce the stack profiles
203
+
204
+ - **ESLint** reads Peer AI's settings from the `peer-ai-eslint-config` package, which your `eslint.config.js` spreads in. Render writes nothing for it.
205
+ - **Ruff** reads settings from a file, so render writes `.peer-ai/enforce/ruff.toml`, with every Ruff rule of the project's profiles and its values. Your own Ruff settings extend it, such as `extend = ".peer-ai/enforce/ruff.toml"` under `[tool.ruff]` in `pyproject.toml`, directly or through a shared file that extends it. Add rules of your own with `extend-select`: a `select` replaces Peer AI's rules instead of adding to them, and doctor fails it, as it does an `ignore` that drops one of Peer AI's codes. Commit the file, so CI's Ruff uses it; `render --check` fails when it falls behind the config.
206
+ - **The TypeScript compiler** reads each part's own `tsconfig.json`, which render never edits.
207
+ - **The pipeline's checks,** for a project listing the `github-actions` profile, run from `.github/workflows/peer-ai-security.yml`, which render writes. Each tool is a release checked against its checksum, or an image pinned to its digest:
208
+ - `peer-ai / secrets`: Gitleaks, on a pull request's commits and on the whole history every day. A secret found in old history that's already been replaced goes in `.gitleaksignore`, with why.
209
+ - `peer-ai / dependencies`: OSV-Scanner, on every lockfile and manifest it can read, on every change and every day. It warns when it finds none.
210
+ - `peer-ai / workflows`: zizmor, on the workflows and any actions in the repository.
211
+ - `peer-ai / code`: Semgrep, with its security rules for the common languages pinned to a commit of `semgrep/semgrep-rules`. Those rules are under the Semgrep Rules License, not an open-source licence.
212
+ - `peer-ai / tls`: SSLyze, against Mozilla's intermediate profile, every day, for each environment with a `url`.
213
+ - `peer-ai / running-app`: OWASP ZAP's baseline scan, every day, only in environments marked `"production": false`; one not marked might be production, so it's never scanned. Accept a finding in `.github/zap-rules.tsv`, with the reason. The reports are kept with each run.
214
+
215
+ Make the jobs required checks in your branch protection: their names never change. The file's header records a hash of what render wrote: while it matches, render keeps the file up to date; once someone changes it by hand, render leaves it alone, and doctor checks it still has every job.
216
+
217
+ ### Options
218
+
219
+ | Option | What it does |
220
+ |--------|--------------|
221
+ | `--check` | Change nothing, and fail when a committed file is out of date. For CI. It leaves the skills out, since CI never has them, unless the project commits them. |
222
+ | `--skills` | Write only the skills, touching nothing committed. It's what each tool's setup step runs. |
223
+ | `--quiet` | Print nothing unless something fails |
224
+
225
+ ### Exit codes
226
+
227
+ `0` done or up to date, `1` a file was refused, or is out of date with `--check`, `2` a usage error or no valid `peer-ai.config.json`.
228
+
229
+ ## `peer-ai doctor`
230
+
231
+ Checks that Peer AI is set up correctly in a repository, and says how to fix what isn't. It only reads; it never changes a file.
232
+
233
+ You rarely need to run it yourself (RFC 0007): `peer-ai check` fails in CI on anything doctor fails on, and your AI tool hears about every problem it finds through `next_work` at the start of each session.
234
+
235
+ ```bash
236
+ npx peer-ai doctor
237
+ ```
238
+
239
+ | It checks | A problem looks like |
240
+ |-----------|----------------------|
241
+ | Node.js | A version older than the one Peer AI needs |
242
+ | `peer-ai.config.json` | Missing, or not valid, with each error |
243
+ | Tracks | A track whose folder has moved or gone, or a part of the repository no track covers. A track with no `path` is the repository root, so a monorepo needs a track for each part, or one whose folder holds several. A dormant track may not have a folder yet. |
244
+ | Files the config names | A contract, design, standards document, data inventory, checklist or input that doesn't exist. URLs, glob patterns and places still to be made, such as `docs.dir`, are left alone. |
245
+ | AI tools | A tool set up in the repository, such as a `CLAUDE.md` or `.cursor/`, that the config doesn't list |
246
+ | What render writes | Instructions or MCP registrations that no longer match the config, or skills that are missing or out of date |
247
+ | CI | A config that says there is no CI when the repository has a pipeline, which would lead Peer AI to add a second one |
248
+ | The project map | Missing, not valid, or out of date. It runs a fresh assessment and lists every item whose status has changed since `.peer-ai/map.json` was written. |
249
+ | Work items | A file in `.peer-ai/work/` that isn't valid, isn't named after its id, or names a track the config doesn't have |
250
+ | Git | A folder that isn't a git repository, or a `.gitignore` that hides Peer AI's files from the team and CI |
251
+ | Rules set aside or changed | Every entry in `standards.exceptions` and `standards.overrides` is listed, so nothing is switched off silently. It warns about an exception whose `until` date has passed, a rule id that isn't one of Peer AI's rules, a rule set aside twice, and an override for a rule with no value to change, or of the wrong type. |
252
+ | Stack profiles | A listed profile Peer AI has no rules for yet |
253
+ | The tools that enforce them | For each part, that the ESLint config nearest it spreads in `peer-ai-eslint-config`, that the Ruff settings nearest it extend `.peer-ai/enforce/ruff.toml`, and that its tsconfig files, including those a solution tsconfig references, set what the compiler rules need; and that the pipeline's workflow is there, as render wrote it, and up to date. A warning, and a failure at production. |
254
+ | The v0 playbook | A copy left in `peer-ai/`, with how to remove it |
255
+
256
+ Every check reports, including the ones it had to skip (for example, the tracks can't be checked without a valid config), so a clean report means everything was looked at.
257
+
258
+ A failure (✗) means Peer AI can't work as intended until it's fixed. A warning (!) is something to tidy up.
259
+
260
+ ### Options
261
+
262
+ | Option | What it does |
263
+ |--------|--------------|
264
+ | `--json` | Print the checks as JSON |
265
+
266
+ ### Exit codes
267
+
268
+ `0` nothing failed (warnings are allowed), `1` at least one check failed, `2` a usage error.
269
+
270
+ ## `peer-ai check`
271
+
272
+ The gate CI runs. It fails when the setup is broken, or when a work item claims more than its record shows.
273
+
274
+ ```bash
275
+ npx peer-ai check
276
+ ```
277
+
278
+ | It fails when | Why |
279
+ |---------------|-----|
280
+ | The config is missing or not valid | Nothing else can be checked (exit code `2`) |
281
+ | A track's folder doesn't exist | The config no longer describes the repository |
282
+ | `.peer-ai/map.json` or a work item isn't valid, or a work item names a track the config doesn't have | State that agents read has to be trustworthy |
283
+ | A work item at `ship` or `done` has no recorded verify, or its last verify failed | `commands.verify` runs before any work is called done. Without a verify command, only a recorded failure counts. |
284
+ | A work item at `ship` or `done` has a review whose latest result failed, or is incomplete | A review that didn't check every rule hasn't passed. A later passing review from the same skill replaces an earlier failure. At the `prototype` stage, an incomplete review is allowed; a failed one never is. |
285
+ | A production project's work item at `ship` or `done` has a review with no report | Without a report, the result is only the agent's word. For an MVP this is a warning; for a prototype it's allowed. |
286
+ | A work item at `ship` or `done` is missing a review it needs | When an item reaches verify, Peer AI works out the reviews it needs from the files it touched, such as a security review for code at MVP or production. Missing one is a warning for an MVP and a failure in production. `activities.verify.reviews` in the config can require more, or skip one with a reason. |
287
+ | A gap work item is at `done`, but a fresh assessment still finds the gap | The work didn't fill it |
288
+ | A work item at `ship` or `done` depends on an item that hasn't shipped | Changes land in the order they depend on (RFC 0005). Building before a dependency ships is fine. |
289
+ | A work item depends on an item that doesn't exist, or items depend on each other in a loop | The plan can't be followed |
290
+
291
+ It also fails on anything [`peer-ai doctor`](#peer-ai-doctor) fails on (RFC 0007), listed under their own heading, so a setup that stopped working never passes CI unnoticed: for example, a production project whose linter no longer enforces its stack profile. Doctor's warnings don't fail the build; `check` counts them in one line. The skills are left out, since CI never has them.
292
+
293
+ It warns, and still passes, when:
294
+
295
+ - the project map is out of date, so it should be assessed again and committed
296
+ - the stage needs something that is missing and no open gap work item covers it
297
+ - an MVP or production project has no verify command
298
+
299
+ Gaps are never failures. They become work items, so a project can adopt Peer AI at any point without its build going red.
300
+
301
+ A review's result is worked out from its report when it is recorded, so an open problem at or above the project's blocking level (`gates.blockOn`) makes the review fail, and the work item can't ship until the problem is fixed or a person accepts the risk.
302
+
303
+ ### In CI
304
+
305
+ Run it after the project's own checks:
306
+
307
+ ```yaml
308
+ - run: npx peer-ai check
309
+ ```
310
+
311
+ ### Options
312
+
313
+ | Option | What it does |
314
+ |--------|--------------|
315
+ | `--json` | Print the checks as JSON |
316
+
317
+ ### Exit codes
318
+
319
+ `0` passed (warnings are allowed), `1` failed, `2` a usage error or no valid `peer-ai.config.json`.
320
+
321
+ ## `peer-ai check-report`
322
+
323
+ Checks a review's report the way the `record_review` tool does: that it's valid, gives every rule its skill answers for a line, and claims the result its findings and coverage support. It records nothing. It's there for AI tools that work in a shell rather than through the MCP server, and for a person checking a report by hand.
324
+
325
+ ```bash
326
+ npx peer-ai check-report .peer-ai/reports/project/security-review-20261001T0900Z.json
327
+ ```
328
+
329
+ | Option | What it does |
330
+ |--------|--------------|
331
+ | `--skill <skill>` | The skill the report is for. By default, the one the report names. |
332
+ | `--work-item <id>` | The work item it's for, when there is one |
333
+ | `--json` | Print the result as JSON |
334
+
335
+ Exit codes: `0` when the report passes, `1` when it doesn't, and `2` without a valid config or a report path.
336
+
337
+ ## `peer-ai check-document`
338
+
339
+ Checks a document a Peer AI skill wrote, such as the requirements, the way the `check_document` tool does: every required part of the skill's template is there and filled in, no template text is left in, and every rule id it cites exists. It changes nothing. It's there for AI tools that work in a shell, and for CI.
340
+
341
+ ```bash
342
+ npx peer-ai check-document docs/requirements.md --skill requirements-analysis
343
+ ```
344
+
345
+ | Option | What it does |
346
+ |--------|--------------|
347
+ | `--skill <skill>` | The document skill that wrote it. Required. |
348
+ | `--template <name>` | Which of the skill's templates it follows, when it has several. By default, the main one. |
349
+ | `--json` | Print the result as JSON |
350
+
351
+ Exit codes: `0` when the document is ready, `1` when it isn't or can't be checked, and `2` without a path or a skill.
352
+
353
+ ## `peer-ai feedback`
354
+
355
+ When Peer AI gets something wrong in your project, such as a review that misses a problem or a check that blocks work by mistake, your AI tool drafts a report with the `draft_feedback` tool and keeps it in `.peer-ai/feedback/`, out of git. You decide what happens to each one (RFC 0007).
356
+
357
+ ```bash
358
+ npx peer-ai feedback
359
+ npx peer-ai feedback send 2026-10-02-check-blocked-a-merge.md
360
+ npx peer-ai feedback drop 2026-10-02-check-blocked-a-merge.md
361
+ ```
362
+
363
+ | Command | What it does |
364
+ |---------|--------------|
365
+ | `peer-ai feedback` | Lists the drafts waiting, with each title |
366
+ | `peer-ai feedback send <draft>` | Opens the draft as an issue on Peer AI's repository, labelled `feedback`, under your own GitHub account through the GitHub CLI, `gh`. The draft moves to `.peer-ai/feedback/sent/` with the issue's link. Without a signed-in `gh`, it prints a link to a new issue with the report filled in, for you to submit. |
367
+ | `peer-ai feedback drop <draft>` | Deletes the draft |
368
+
369
+ Your AI tool asks you about each draft at a natural stopping point, and runs `send` or `drop` only after you answer. Nothing is ever sent without a person's yes, and a report never holds your code: Peer AI refuses a draft with a block of code, anything that looks like a key or a token, or an email address.
370
+
371
+ Exit codes: `0` done, `1` a draft that doesn't exist, `2` a usage error.
372
+
373
+ ## `peer-ai mcp`
374
+
375
+ Starts the Peer AI MCP server over stdio. Any AI tool that supports MCP servers reaches the same project map, work items and gates through it, so a project behaves the same whichever tool a person uses.
376
+
377
+ The AI tool starts it, from the project's folder or one inside it. For example, in a project's `.mcp.json` for Claude Code:
378
+
379
+ ```json
380
+ {
381
+ "mcpServers": {
382
+ "peer-ai": { "command": "npx", "args": ["peer-ai", "mcp"] }
383
+ }
384
+ }
385
+ ```
386
+
387
+ `peer-ai render` writes this registration for each tool in the config.
388
+
389
+ | Tool | What it does |
390
+ |------|--------------|
391
+ | `project_map` | Each item on the project map with its evidence, what the stage still needs, compliance signals and traits to consider. It assesses afresh on every call, and says whether the committed map has fallen behind. |
392
+ | `next_work` | Any setup problem `peer-ai doctor` finds (`setup`), each with its fix, for the AI tool to fix or tell the person about before other work. Then the open work item for the current git branch, with where it stopped, its next action and the reviews it needs, and every other open item, with the items each is waiting for before it can ship (`waiting`). When nothing is open, the gaps the stage needs, with the Peer AI skill to use for each (`useSkill`). |
393
+ | `standards_for_file` | The track a file belongs to, the stack profiles, and the project's own standards documents and rules for that track |
394
+ | `create_work_item` | Starts a feature, bug, refactor, migration, discovery, chore or gap at `prepare`. Its id comes from `tracker.ticketPrefix` (or `ITEM`) unless a tracker key is given, and its branch from `repo.branchNaming`. It can carry its plan (RFC 0005): a goal, acceptance criteria, the sources it implements, and the items it depends on. |
395
+ | `update_work_item` | Records the next action and the activity and step where work stopped, so the next session resumes there. It also sets the item's goal, acceptance criteria, sources and dependencies. |
396
+ | `run_verify` | Runs `commands.verify` and records the result with the end of its output. Only this tool records a verify, so a pass is proven rather than claimed. |
397
+ | `record_review` | Records a review from its report: Peer AI checks the report and works out pass, fail or incomplete from it, and refuses a result the report doesn't support, or a report that leaves out any of the skill's rules. A review recorded without a report is marked unproven. For a review of the whole project, leave out the work item: Peer AI checks the report the same way and gives its result, without recording it. |
398
+ | `check_document` | Checks a document a Peer AI skill wrote against the skill's template, and lists what to change: missing or empty parts, template text left in, and rule ids that don't exist. The skill fixes them and checks again, until the document is ready. |
399
+ | `advance_work_item` | Moves a work item to its next stage, back to an earlier one, or to cancelled. A move to `ship` or `done` passes the same gates as `peer-ai check`, and a refusal lists what to fix. Moving to verify works out the reviews the change needs from the files it touched, and keeps them on the item. |
400
+ | `draft_feedback` | Drafts a report for Peer AI's maintainers when Peer AI itself gets something wrong, with Peer AI's version, the AI tool, the stage and the stack profiles added. It writes the draft to `.peer-ai/feedback/` and refuses one holding code, a key or token, or an email address. The person decides whether it's sent: see [`peer-ai feedback`](#peer-ai-feedback). |
401
+
402
+ Every change to a work item is validated against its schema before it is written. `run_verify` runs the project's own command through the shell, exactly as a person would type it.
403
+
@@ -0,0 +1,102 @@
1
+ import { readConfig, type KnownMapItemId, type PeerAiConfig, type ProjectMap, type Trait } from "peer-ai-workflow";
2
+ import type { Output, Stage } from "./init.ts";
3
+ export declare const MAP_FILE = ".peer-ai/map.json";
4
+ export declare const MAP_SCHEMA_URL = "https://raw.githubusercontent.com/AbuMahir980/peer-ai/main/packages/workflow/schemas/map.schema.json";
5
+ export type Status = "present" | "partial" | "missing" | "not-applicable";
6
+ export interface ItemResult {
7
+ status: Status;
8
+ evidence?: string[];
9
+ note?: string;
10
+ inferred?: boolean;
11
+ }
12
+ export interface Track {
13
+ id: string;
14
+ kind: string;
15
+ path?: string;
16
+ deploy?: string;
17
+ status: string;
18
+ }
19
+ export interface Finding {
20
+ name: string;
21
+ file: string;
22
+ }
23
+ export interface Signals {
24
+ personalData: Finding[];
25
+ cardData: Finding[];
26
+ paymentProviders: string[];
27
+ }
28
+ /** A trait the code suggests the product has, which the config doesn't declare yet. */
29
+ export interface TraitSuggestion {
30
+ trait: Trait;
31
+ /** What was found, and where, such as "stripe in services/api/package.json". */
32
+ evidence: string;
33
+ }
34
+ /** A stack found in a part the config lists with no stack of its own. */
35
+ export interface StackSuggestion {
36
+ track: string;
37
+ stack: string[];
38
+ }
39
+ /** A stack profile that fits a part of the project, which the config doesn't list yet. */
40
+ export interface ProfileSuggestion {
41
+ profile: string;
42
+ /** Why it fits, such as "web is tagged expo". */
43
+ evidence: string;
44
+ }
45
+ export interface Assessment {
46
+ name: string;
47
+ stage: Stage;
48
+ tracks: Track[];
49
+ items: Record<KnownMapItemId, ItemResult>;
50
+ signals: Signals;
51
+ /** Traits to consider adding to project.traits, each switching on extra rules (RFC 0003). */
52
+ suggestedTraits: TraitSuggestion[];
53
+ /** Stack profiles to consider adding to standards.profiles, each with the tools that enforce it (RFC 0006). */
54
+ suggestedProfiles: ProfileSuggestion[];
55
+ /**
56
+ * Stacks to add to parts that name none. A listed profile applies to every part without a stack,
57
+ * so each part's stack keeps a profile to the parts it fits.
58
+ */
59
+ suggestedStacks: StackSuggestion[];
60
+ /** A copy of the v0 playbook was found and left out of the assessment. */
61
+ legacyPlaybook: boolean;
62
+ }
63
+ /** What each stage needs. Items not applicable to a project are never required. */
64
+ export declare const REQUIRED: Record<Stage, KnownMapItemId[]>;
65
+ export declare const NEXT_STAGE: Record<Stage, Stage | undefined>;
66
+ export declare const UI_KINDS: string[];
67
+ export declare const MANIFEST: RegExp;
68
+ export declare const SCHEMA_FILE: RegExp;
69
+ export declare const PERSONAL_FIELD: RegExp;
70
+ export declare const INFRASTRUCTURE_AS_CODE: RegExp;
71
+ export declare const TRAIT_LIBRARIES: [trait: Trait, pattern: RegExp][];
72
+ export declare const LEGACY_PLAYBOOK = "peer-ai/";
73
+ export declare const LEGACY_MARKERS: string[];
74
+ export declare const TEST_FILE: RegExp;
75
+ interface Context {
76
+ root: string;
77
+ files: string[];
78
+ tracks: Track[];
79
+ config: PeerAiConfig | undefined;
80
+ read: (file: string) => string;
81
+ }
82
+ /**
83
+ * Splits camelCase and PascalCase names into words the way snake_case already is, so phoneNumber
84
+ * reads as phone_Number and IPAddress as IP_Address. A lone leading "i", as in iPhone, stays part
85
+ * of its word.
86
+ */
87
+ export declare function snakeCase(text: string): string;
88
+ export declare function collectSignals(ctx: Context): Signals;
89
+ export declare function assess(root: string, config: PeerAiConfig | undefined, stage: Stage): Assessment;
90
+ export declare function gaps(assessment: Assessment, stage: Stage): KnownMapItemId[];
91
+ export declare function toMap(assessment: Assessment, now: Date): ProjectMap;
92
+ /** Reads peer-ai.config.json, following a relative `extends`. Returns errors instead of throwing. */
93
+ export declare const loadConfig: typeof readConfig;
94
+ export interface AssessOptions {
95
+ cwd: string;
96
+ target?: Stage;
97
+ json: boolean;
98
+ dryRun: boolean;
99
+ now?: Date;
100
+ }
101
+ export declare function runAssess(options: AssessOptions, out: Output, report: (assessment: Assessment, stage: Stage) => string[]): number;
102
+ export {};