create-afe-project 0.0.0-stage → 1.0.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.
- package/CHANGELOG.md +351 -0
- package/LICENSE +21 -0
- package/README.md +77 -2
- package/bin/create-afe-project.js +123 -0
- package/package.json +43 -4
- package/src/answers.js +147 -0
- package/src/config.js +152 -0
- package/src/project.js +217 -0
- package/src/render.js +51 -0
- package/template/.claude/harness.conf +47 -0
- package/template/.claude/hooks/post-edit-check.sh +38 -0
- package/template/.claude/hooks/protect-docs.sh +315 -0
- package/template/.claude/hooks/stop-check-decisions.sh +25 -0
- package/template/.claude/hooks/stop-check-docs.sh +29 -0
- package/template/.claude/hooks/stop-check-template.sh +23 -0
- package/template/.claude/hooks/stop-run-project-hooks.sh +27 -0
- package/template/.claude/path-classes +61 -0
- package/template/.claude/settings.project.json +5 -0
- package/template/.claude/settings.template.json +76 -0
- package/template/.claude/skills/afe-init/SKILL.md +104 -0
- package/template/.claude/skills/create-pr/SKILL.md.jinja +107 -0
- package/template/.claude/skills/update-template/SKILL.md +40 -0
- package/template/.claude/skills/{% if code_review %}review-code{% endif %}/SKILL.md.jinja +46 -0
- package/template/.claude/skills/{% if docs_review %}docs-review{% endif %}/SKILL.md +56 -0
- package/template/.claude/skills/{% if dual_review %}dual-review{% endif %}/SKILL.md +58 -0
- package/template/.github/workflows/decisions.yml.jinja +47 -0
- package/template/.github/workflows/docs.yml.jinja +40 -0
- package/template/.github/workflows/{% if code_review %}code-review.yml{% endif %}.jinja +51 -0
- package/template/.github/workflows/{% if docs_review %}docs-review.yml{% endif %}.jinja +49 -0
- package/template/.github/workflows/{% if fail_without_change %}fail-without-change.yml{% endif %}.jinja +40 -0
- package/template/.github/workflows/{% if secret_scan %}secret-scan.yml{% endif %}.jinja +47 -0
- package/template/.markdownlint-cli2.jsonc +27 -0
- package/template/.template/owned.txt.jinja +63 -0
- package/template/AGENTS.md.jinja +91 -0
- package/template/CLAUDE.md +3 -0
- package/template/README.md.jinja +41 -0
- package/template/_gitignore +14 -0
- package/template/docs/README.md.jinja +44 -0
- package/template/docs/contributing.md.jinja +206 -0
- package/template/docs/decisions/adr-template.md +38 -0
- package/template/docs/documentation-rules.md.jinja +200 -0
- package/template/docs/testing-rules.md +80 -0
- package/template/scripts/check-decisions.sh +382 -0
- package/template/scripts/check-docs.sh +20 -0
- package/template/scripts/check-links.mjs +142 -0
- package/template/scripts/check-project.sh +27 -0
- package/template/scripts/check-template.sh +88 -0
- package/template/scripts/check.sh +21 -0
- package/template/scripts/env.sh +29 -0
- package/template/scripts/gen-decisions-index.sh +57 -0
- package/template/scripts/gen-settings.sh +14 -0
- package/template/scripts/lib/classes.sh +89 -0
- package/template/scripts/lib/git-base.sh +23 -0
- package/template/scripts/lib/harness-conf.sh +48 -0
- package/template/scripts/lib/json.mjs +160 -0
- package/template/scripts/pr-metrics.sh +80 -0
- package/template/scripts/protect-branch.sh +53 -0
- package/template/scripts/{% if acceptance_check %}check-acceptance.sh{% endif %} +47 -0
- package/template/scripts/{% if fail_without_change %}fail-without-change.sh{% endif %} +88 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# create-afe-project
|
|
2
|
+
|
|
3
|
+
## 1.0.0
|
|
4
|
+
|
|
5
|
+
### Major Changes
|
|
6
|
+
|
|
7
|
+
- The template moves from Copier to the npm package `create-afe-project` (ADR-0002), on the
|
|
8
|
+
owner's instruction of 2026-10-31, to drop the Python toolchain for users; the first release on
|
|
9
|
+
npm, under the MIT license.
|
|
10
|
+
- `npx create-afe-project@latest <directory>` (or `npm create afe-project@latest`) creates a
|
|
11
|
+
project with a wizard that asks the questions of the former `copier.yml`; `--defaults`,
|
|
12
|
+
`--data key=value`, and `--data-file` answer without a terminal. The questions are short and
|
|
13
|
+
plain, and the message after create numbers the next steps.
|
|
14
|
+
- Create makes the initial commit on `main` (`Template: create the project with
|
|
15
|
+
create-afe-project <version>`), the one direct commit that `docs/contributing.md` allows, so
|
|
16
|
+
`/afe-init` starts on a clean working tree. It commits only in a new directory or an empty
|
|
17
|
+
clone, never in a non-empty directory written with `--force`; `--no-git` skips it.
|
|
18
|
+
- `npx create-afe-project@latest update` replaces the template-owned files, keeps the project
|
|
19
|
+
block of `AGENTS.md`, creates missing seeded files and never changes existing ones, removes
|
|
20
|
+
files the template no longer owns, runs the migrations between the versions, and regenerates
|
|
21
|
+
the generated files. It refuses a dirty working tree (`--allow-dirty`) and a downgrade, and
|
|
22
|
+
lists every replaced local edit of a template-owned file.
|
|
23
|
+
- The answers file is `.afe-answers.json` with the template version in `_version`; a project
|
|
24
|
+
generated by Copier converts its `.copier-answers.yml` on its first update. The path classes
|
|
25
|
+
(`scripts/lib/classes.sh`), the protect hook, and the size warning of
|
|
26
|
+
`scripts/check-decisions.sh` know both names.
|
|
27
|
+
- `docs/contributing.md`, section 5, `docs/documentation-rules.md`, section 9, and the
|
|
28
|
+
`update-template` skill describe the update with `create-afe-project`; there are no conflict
|
|
29
|
+
markers to resolve any more. `README.md` is seeded: copy its "Project template" and "Checks"
|
|
30
|
+
sections by hand.
|
|
31
|
+
- A generated project needs only Git, bash, and Node.js: jq and lychee are gone.
|
|
32
|
+
- The hooks, `scripts/gen-settings.sh`, and `scripts/pr-metrics.sh` read and write JSON with the
|
|
33
|
+
new `scripts/lib/json.mjs`; the protect hook now blocks when Node.js is missing.
|
|
34
|
+
- `scripts/check-links.mjs` replaces lychee: offline, every relative link and image of the
|
|
35
|
+
Markdown files points at an existing file, and every anchor at a heading or an HTML id of its
|
|
36
|
+
target. `scripts/check-docs.sh` and the `docs` workflow run it; `lychee.toml` is removed.
|
|
37
|
+
- The `docs` workflow also runs on `workflow_dispatch`, so a workflow can start it for a pull
|
|
38
|
+
request opened with `GITHUB_TOKEN`.
|
|
39
|
+
- A second pass over the AFE guide, on the owner's decisions of 2026-10-31; no observed failure.
|
|
40
|
+
- `afe-init` skill (new, run by the owner only): interviews the owner about the product, the
|
|
41
|
+
stack, and the stage; records requirements, an accepted stack ADR, and a proposed
|
|
42
|
+
architecture; scaffolds the code with the stack's own generator; wires format, lint, types,
|
|
43
|
+
unit and end-to-end tests into `scripts/checks.d/` and `.claude/harness.conf`; and proves
|
|
44
|
+
that every gate fails when it should. Three pull requests, one change each.
|
|
45
|
+
- The check after every edit: `.claude/hooks/post-edit-check.sh` (new, PostToolUse) runs
|
|
46
|
+
`CHECK_EDIT` of `.claude/harness.conf` on the changed file, limited by `CHECK_EDIT_GLOBS`,
|
|
47
|
+
and sends a failure back to the agent. `.claude/harness.conf` is seeded: an existing project
|
|
48
|
+
adds the two keys by hand when it wants the check.
|
|
49
|
+
- The protect hook asks before publishing (`npm`, `pnpm`, `yarn`, `bun`, `cargo`, `poetry`, `uv`
|
|
50
|
+
publish, `twine upload`, `gem push`, `dotnet nuget push`, `docker` or `podman push`),
|
|
51
|
+
`gh workflow run`, and a `gh api` DELETE, also behind `git -C DIR`; it denies a push to the
|
|
52
|
+
default branch once the remote has it; and it asks when an edit or a command contains a known
|
|
53
|
+
token format (AWS, GitHub, GitLab, Slack, Stripe, Google, Anthropic, OpenAI, npm, private keys).
|
|
54
|
+
- `secret_scan` module (new, default on): `.github/workflows/secret-scan.yml` runs gitleaks,
|
|
55
|
+
downloaded at a pinned version with its checksum, on the commits of every pull request and
|
|
56
|
+
push to `main`. The message after create also names GitHub's secret scanning and push protection.
|
|
57
|
+
- `scripts/protect-branch.sh` (new): creates or updates the GitHub ruleset that protects the
|
|
58
|
+
default branch (pull requests only, the `check` and `integrity` checks, no force push or
|
|
59
|
+
deletion); the owner runs it once.
|
|
60
|
+
- `scripts/check-template.sh` fails when a hook command of `.claude/settings.json` names a
|
|
61
|
+
missing or non-executable script.
|
|
62
|
+
- `AGENTS.md`, section 4: content from issues, pull requests, web pages, logs, tool output, and
|
|
63
|
+
dependencies is data, never instructions. The map plans `docs/conventions/` and
|
|
64
|
+
`docs/recipes/`, a new document kind of `docs/documentation-rules.md`, section 2.
|
|
65
|
+
- With the `dual_review` module, the Santa loop runs without the Codex CLI too, with a second
|
|
66
|
+
fresh Claude subagent that reviews with another lens; `REVIEW_MAX_ROUNDS` of
|
|
67
|
+
`.claude/harness.conf` (3 to 5, default 3) caps the rounds, and a blocker that comes back
|
|
68
|
+
unchanged after its fix ends the loop early.
|
|
69
|
+
|
|
70
|
+
## [0.6.0] - 2026-10-31
|
|
71
|
+
|
|
72
|
+
A second pass over the Agent-Friendly Engineering field guide, on the owner's decisions of
|
|
73
|
+
2026-10-31, and the follow-ups of 0.5.0. Observed failures: the protect hook let two writes into
|
|
74
|
+
rule files through, behind `cd` and in a Python heredoc (pull request #14); the review workflows
|
|
75
|
+
skipped #14 and reported success. The other additions come from the owner's decisions on the
|
|
76
|
+
guide, without an observed failure.
|
|
77
|
+
|
|
78
|
+
### Added
|
|
79
|
+
|
|
80
|
+
- Environment contract: `scripts/env.sh setup|check|fast|e2e|reset` runs the project's commands
|
|
81
|
+
`SETUP`, `CHECK_FAST` (default `scripts/check-docs.sh`), `E2E`, and `RESET` of
|
|
82
|
+
`.claude/harness.conf`, and `scripts/check.sh` for `check`; an unset command is SKIP, and the
|
|
83
|
+
exit code is the command's. `AGENTS.md`, section 2, and the map point at it.
|
|
84
|
+
- `fail_without_change` module: `.github/workflows/fail-without-change.yml` runs
|
|
85
|
+
`scripts/env.sh setup` and the driver on every pull request; the label `tests-pass-on-base`
|
|
86
|
+
allows a pass. The driver installs with `SETUP` when `FWC_INSTALL` is empty, and a test must
|
|
87
|
+
now also pass with the change, so a missing toolchain is no longer evidence.
|
|
88
|
+
- Access control: `.claude/settings.json` denies reading `.env`, `.env.*`, `*.pem`, and `*.key`
|
|
89
|
+
(also through `cat` and the like); a project that needs one, such as `.env.example`, takes the
|
|
90
|
+
rule out with `"remove": {"permissions": {"deny": ["Read(**/.env.*)"]}}` in
|
|
91
|
+
`.claude/settings.project.json`, which `scripts/gen-settings.sh` now supports.
|
|
92
|
+
- Metrics: the measure "Regression of" (`none` or `#N`), required by readiness;
|
|
93
|
+
`scripts/pr-metrics.sh` adds the regression rate, the hours to merge, and the median and
|
|
94
|
+
maximum of each measure.
|
|
95
|
+
- A small diff: readiness warns, without failing, above `DIFF_WARN_LINES` (default 400) changed
|
|
96
|
+
lines, generated files left out.
|
|
97
|
+
- `contracts/*` is class high by default in `.claude/path-classes`.
|
|
98
|
+
|
|
99
|
+
### Changed
|
|
100
|
+
|
|
101
|
+
- Review before the pull request runs without the `dual_review` module too: one pass by a fresh
|
|
102
|
+
Claude subagent, which `create-pr` runs, for classes normal, gate, and high; the module adds
|
|
103
|
+
the Codex CLI and the Santa loop. `review-code` always checks that "Checks" names it.
|
|
104
|
+
- `.claude/hooks/protect-docs.sh`: a target behind `cd DIR` or `git -C DIR` resolves against
|
|
105
|
+
that directory; the file names in an interpreter's heredoc are targets; the body of another
|
|
106
|
+
heredoc is not read as commands.
|
|
107
|
+
- `docs/contributing.md`: section 1, a session that stops unfinished leaves a checkpoint
|
|
108
|
+
(commits pushed, progress and blockers in the plan or the description), and GitHub deletes
|
|
109
|
+
merged branches; section 5, shorter; section 6, a defect fix gives the evidence pack.
|
|
110
|
+
- `docs/documentation-rules.md`, section 2: acceptance criteria as Given, When, Then with their
|
|
111
|
+
checks; architecture holds the system map with domain ownership and dependency rules.
|
|
112
|
+
`docs/testing-rules.md`: the project names the levels of its verification ladder.
|
|
113
|
+
|
|
114
|
+
### Seeded files: what an existing project does by hand
|
|
115
|
+
|
|
116
|
+
- `.claude/harness.conf`: add `SETUP=`, `CHECK_FAST=scripts/check-docs.sh` (or the project's
|
|
117
|
+
fast check), `E2E=`, `RESET=`, and `DIFF_WARN_LINES=400`.
|
|
118
|
+
- `.claude/path-classes`: add `high contracts/*` when the project has contracts.
|
|
119
|
+
- `docs/README.md`: the row "Environment commands" names `scripts/env.sh`; the planned rows of
|
|
120
|
+
architecture and operations name the system map, domain ownership, and dependency rules, and
|
|
121
|
+
logs, traces, metrics, and scenario replay.
|
|
122
|
+
- On GitHub, turn on "Automatically delete head branches" in the repository settings.
|
|
123
|
+
|
|
124
|
+
## [0.5.0] - 2026-10-31
|
|
125
|
+
|
|
126
|
+
The process follows the Agent-Friendly Engineering principles: the owner sets outcomes and
|
|
127
|
+
risks, agents report evidence, checks enforce, and governance follows risk and reversibility.
|
|
128
|
+
Recurring failure addressed: in `xandronak/brain`, pull requests #14, #15, and #18 each needed
|
|
129
|
+
three or more AI review rounds that never converged, because every round found new edge cases;
|
|
130
|
+
and each owner decision needed a separate confirmation. Additions without an observed failure,
|
|
131
|
+
from the owner's decisions on the AFE field guide (2026-10-30): the invariants register, the
|
|
132
|
+
environment commands, access control for irreversible actions, and the size budget. Open pull
|
|
133
|
+
requests of an existing project need the new description sections before readiness passes.
|
|
134
|
+
|
|
135
|
+
### Added
|
|
136
|
+
|
|
137
|
+
- Path classes (`docs/documentation-rules.md`, section 8): low, normal, gate, high, approval, by
|
|
138
|
+
built-in rules and the new seeded `.claude/path-classes` (`<class> <glob>` lines), with
|
|
139
|
+
defaults for several ecosystems. Each class decides approval before the edit (approval: the
|
|
140
|
+
protect hook asks), the listing in the pull request (gate: "Gate files"), and the review
|
|
141
|
+
before it (none, one reviewer, or the Santa loop for high). `scripts/lib/classes.sh` and
|
|
142
|
+
`scripts/check-decisions.sh --classes` print the class of each changed path and the review it
|
|
143
|
+
needs. `AGENTS.md`, section 4, follows the classes.
|
|
144
|
+
- Loops (`docs/contributing.md`, sections 3 and 6): the Ralph loop on `scripts/check.sh` for
|
|
145
|
+
every change, capped by `RALPH_MAX_ITERATIONS` (default 5) in the new seeded
|
|
146
|
+
`.claude/harness.conf`; the Santa loop for class high only, with a Claude subagent and the
|
|
147
|
+
Codex CLI until neither finds a blocker, and after the third round the open blockers go to the
|
|
148
|
+
owner. Other classes get one pass; only the fix of a blocker is checked again.
|
|
149
|
+
- Definition of done in `docs/contributing.md`, section 3, which `AGENTS.md`, section 6, points
|
|
150
|
+
at; it replaces the definition-of-done line of `docs/documentation-rules.md`, section 6.
|
|
151
|
+
- Modules `acceptance_check` (`scripts/check-acceptance.sh`: every identifier of the Acceptance
|
|
152
|
+
section appears in a test file of `TEST_GLOBS`; run by readiness) and `fail_without_change`
|
|
153
|
+
(`scripts/fail-without-change.sh`: each new or changed test fails on the base, in a temporary
|
|
154
|
+
worktree, with the project's own `FWC_INSTALL` and `FWC_TEST`, an optional `FWC_CLASSIFIER`,
|
|
155
|
+
and `--allow-pass-on-base` for the label `tests-pass-on-base`). Both off by default.
|
|
156
|
+
- `scripts/check-decisions.sh --ready` also fails on: no "Acceptance and test plan"; an
|
|
157
|
+
Acceptance item that is neither "None" with a reason nor names an existing path in backticks;
|
|
158
|
+
an added `Decided by the owner, YYYY-MM-DD` marker in a Markdown file that "Owner decisions"
|
|
159
|
+
does not name; a touched gate file that "Gate files" does not name; Metrics tables outside
|
|
160
|
+
their forms, answers that do not add up, a blocker recorded as a limit, or a missing measure.
|
|
161
|
+
- `scripts/pr-metrics.sh`: sums the Metrics tables of merged pull requests with `gh`, names the
|
|
162
|
+
sensors without a finding, and warns when `--limit` cuts the period. `docs/maintaining.md`,
|
|
163
|
+
section 6 (this repository): at each release a rule or check that never fired is proposed for
|
|
164
|
+
removal, and a new one names the recurring failure it addresses.
|
|
165
|
+
- Access control: `.claude/settings.json` is now generated by `scripts/gen-settings.sh` from the
|
|
166
|
+
template-owned `.claude/settings.template.json` and the new seeded
|
|
167
|
+
`.claude/settings.project.json`, where the project adds its own permission rules; the template
|
|
168
|
+
denies force pushes and remote branch deletions in the forms its rules spell out.
|
|
169
|
+
`scripts/check-template.sh` fails on a stale `.claude/settings.json`.
|
|
170
|
+
- `.claude/hooks/protect-docs.sh`: asks for class approval paths (`approval` lines of
|
|
171
|
+
`.claude/path-classes`, `.claude/settings.project.json`, `.mcp.json`, the generated settings),
|
|
172
|
+
and for the irreversible commands it names: `git push` that forces, deletes, mirrors, prunes,
|
|
173
|
+
or pushes tags (`--tags`, `refs/tags/...`, `v<digit>...`), `gh pr merge`, `gh release create`
|
|
174
|
+
and `delete`, `gh repo delete`.
|
|
175
|
+
- Line budgets checked by `scripts/check-template.sh`: `AGENTS.md` 90 template lines,
|
|
176
|
+
`docs/documentation-rules.md` 200, `docs/contributing.md` 200, `docs/testing-rules.md` 80. The
|
|
177
|
+
four rule documents together are shorter than in 0.4.1.
|
|
178
|
+
- The invariants register `docs/invariants.md` as a planned document kind; its invariants are
|
|
179
|
+
criteria of the Santa loop. Environment commands in the map, pointed at from `AGENTS.md`. One
|
|
180
|
+
git worktree per parallel session (`docs/contributing.md`, section 1).
|
|
181
|
+
|
|
182
|
+
### Changed
|
|
183
|
+
|
|
184
|
+
- `docs/contributing.md`, section 3: description sections Summary, Acceptance and test plan,
|
|
185
|
+
Checks, Assumptions and open questions, Owner decisions, Gate files, Metrics (two fixed
|
|
186
|
+
tables), Notes for the owner. The new label `limit:` records a suggestion the branch does not
|
|
187
|
+
fix. A failing check keeps its command and output. The owner's merge confirms the listed
|
|
188
|
+
markers; readiness waits for no confirming comment and no second round.
|
|
189
|
+
- `docs/contributing.md`, section 6: AI review is a sensor; classes `blocker` and `suggestion`;
|
|
190
|
+
each finding is answered once; a suggestion never drives a loop. The `docs-review` and
|
|
191
|
+
`code-review` workflows run once, when a pull request opens or leaves draft; a push or a reopen
|
|
192
|
+
does not run them again.
|
|
193
|
+
- `docs/testing-rules.md`: the agent derives the test plan from the identifiers, as a report; a
|
|
194
|
+
refactoring keeps the tests; a behaviour change changes the requirement first, then the test
|
|
195
|
+
with the same identifier; gate configurations are class gate; the threat model of development
|
|
196
|
+
gates only decides which bypass is a blocker.
|
|
197
|
+
- Skills: `dual-review` reviews by class; `create-pr` runs the Ralph loop, writes the new
|
|
198
|
+
sections, waits for the review runs once, and has a fixed blocker checked once by a fresh
|
|
199
|
+
subagent; `review-code` and `docs-review` use the two classes and no longer judge whether a
|
|
200
|
+
marker matches the owner's words.
|
|
201
|
+
|
|
202
|
+
### Removed
|
|
203
|
+
|
|
204
|
+
- The `should`/`nit` classes and their example table, the brief rule for later rounds, the
|
|
205
|
+
escalation after three rounds outside the Santa loop, "Owner decisions to confirm" and its
|
|
206
|
+
confirming comment, the template-update exemption of 0.4.1 (now class low), and the checklist
|
|
207
|
+
of `docs/contributing.md`, section 4, which is now one paragraph.
|
|
208
|
+
- `.claude/protected-paths` is no longer seeded; the hook and the class checks still read its
|
|
209
|
+
glob lines as class approval.
|
|
210
|
+
|
|
211
|
+
### Seeded files: what an existing project does by hand
|
|
212
|
+
|
|
213
|
+
- An update creates `.claude/path-classes`, `.claude/harness.conf`, and
|
|
214
|
+
`.claude/settings.project.json` with the defaults, and deletes `.claude/protected-paths`; a
|
|
215
|
+
`_migrations` entry of `copier.yml` appends its glob lines to `.claude/path-classes` as
|
|
216
|
+
`approval <glob>`. Check them by hand: gate configuration, such as test runner and linter
|
|
217
|
+
files, becomes `gate <glob>`. Add the project's own high paths
|
|
218
|
+
(brain: policy, limits, accounting). Set `TEST_GLOBS`, `FWC_TEST`, and `FWC_INSTALL` in
|
|
219
|
+
`.claude/harness.conf` before turning on the new modules (`copier update --data
|
|
220
|
+
acceptance_check=true --data fail_without_change=true`).
|
|
221
|
+
- `.claude/settings.json` becomes generated: a project that edited it moves its own rules into
|
|
222
|
+
`.claude/settings.project.json` and runs `scripts/gen-settings.sh`.
|
|
223
|
+
- `docs/README.md`: add the row "Environment commands: set up, check, fast check, end-to-end
|
|
224
|
+
tests, reset" (check: `scripts/check.sh`; the others the project's commands or "not
|
|
225
|
+
decided"), the planned row "Invariants" (`docs/invariants.md`), and in the rows of the agent
|
|
226
|
+
rules, the documentation rules, and checks and enforcement the new terms: autonomy by risk,
|
|
227
|
+
when a change is done, path classes and access, `.claude/path-classes`,
|
|
228
|
+
`.claude/harness.conf`, `.claude/settings.project.json`, `scripts/pr-metrics.sh`.
|
|
229
|
+
|
|
230
|
+
## [0.4.1] - 2026-10-30
|
|
231
|
+
|
|
232
|
+
### Changed
|
|
233
|
+
|
|
234
|
+
- `docs/contributing.md`, sections 3, 4, and 6 (with `dual_review`): a template update that
|
|
235
|
+
changes only template-owned and generated files is exempt from the dual review; its
|
|
236
|
+
description says "Dual review: not run: template update to X.Y.Z". The `create-pr`,
|
|
237
|
+
`dual-review`, and `review-code` skills apply the exemption: `review-code` takes that line in
|
|
238
|
+
place of a verdict.
|
|
239
|
+
|
|
240
|
+
## [0.4.0] - 2026-10-30
|
|
241
|
+
|
|
242
|
+
### Changed
|
|
243
|
+
|
|
244
|
+
- `docs/testing-rules.md`, section 4: a threat model of development gates. Gates catch honest
|
|
245
|
+
mistakes and shortcuts; deliberate evasion is left to the review of the diff; product
|
|
246
|
+
invariants are not development gates. The protected-paths bullet now names the forms the
|
|
247
|
+
protect hook catches and what is left to the review, instead of claiming that no agent loosens
|
|
248
|
+
a gate.
|
|
249
|
+
- `docs/documentation-rules.md`, section 7: the merge-readiness row names what
|
|
250
|
+
`scripts/check-decisions.sh --ready` checks and what is left to the owner.
|
|
251
|
+
- `docs/contributing.md`, section 6: a finding that only deliberate evasion can exploit to bypass
|
|
252
|
+
a development gate is a `nit`, a bypass of a product invariant keeps its severity, and a table
|
|
253
|
+
of `should` and `nit` examples calibrates every reviewer. The Tests criterion includes the test
|
|
254
|
+
plan. With `dual_review`, later rounds add the owner's decisions on the branch to the brief, and
|
|
255
|
+
nothing else.
|
|
256
|
+
- `docs/contributing.md`, section 1: "one logical change" means one mechanism with its tests and
|
|
257
|
+
owner documents, with examples.
|
|
258
|
+
- `docs/contributing.md`, section 3: the description gains the sections "Test plan" (always,
|
|
259
|
+
written before the implementation) and "Owner decisions to confirm" (each `Decided by the
|
|
260
|
+
owner` marker added on a chat instruction, confirmed by the owner with one comment); a pull
|
|
261
|
+
request is ready to merge only after that confirmation. `scripts/check-decisions.sh --ready`
|
|
262
|
+
does not check the confirmation.
|
|
263
|
+
- `docs/documentation-rules.md`, sections 3 and 7: a statement about a check names the forms it
|
|
264
|
+
catches and what is left to the review; an absolute claim needs a test for each form it covers.
|
|
265
|
+
- `create-pr` skill: writes the two new sections and reports unconfirmed owner decisions as
|
|
266
|
+
waiting on the owner. `review-code` skill: compares the code and tests with the test plan.
|
|
267
|
+
`dual-review` skill: an author's self-check before the first round, the severity examples and
|
|
268
|
+
the test plan in the brief, and the owner's decisions from the second round.
|
|
269
|
+
|
|
270
|
+
### Fixed
|
|
271
|
+
|
|
272
|
+
- `.claude/hooks/protect-docs.sh`: judges a target path by the git repository that holds it when
|
|
273
|
+
that repository has `.template/owned.txt`, so an edit in a sibling git worktree, or in another
|
|
274
|
+
generated project, asks the owner like an edit in the session's own checkout. Other paths
|
|
275
|
+
inside the session's project are judged by the project as before (no git yet, a nested
|
|
276
|
+
repository); paths elsewhere stay unguarded. A relative path of a shell command resolves
|
|
277
|
+
against the hook input's `cwd`.
|
|
278
|
+
- `.claude/hooks/protect-docs.sh`: folds `.` and `..` in the part of a target path that does not
|
|
279
|
+
exist yet before the match, so a write to `newdir/../AGENTS.md` or `docs/new/../README.md` asks
|
|
280
|
+
the owner, and a path whose `..` leaves the repository no longer matches a protected glob.
|
|
281
|
+
|
|
282
|
+
## [0.3.1] - 2026-10-30
|
|
283
|
+
|
|
284
|
+
### Changed
|
|
285
|
+
|
|
286
|
+
- `docs/contributing.md`, section 6: defines the severities `blocker`, `should`, and `nit`, and
|
|
287
|
+
that a review fails on a `blocker` or `should` only; a reviewer who hesitates picks `nit`. The
|
|
288
|
+
`review-code`, `docs-review`, and `dual-review` skills apply these definitions, and a `nit` no
|
|
289
|
+
longer fails a round of the dual review.
|
|
290
|
+
- `review-code` and `docs-review` skills: in a pull request run they read changed files of
|
|
291
|
+
`.claude/`, `CLAUDE.md`, and `.mcp.json` from the diff and `.claude-pr/`, because
|
|
292
|
+
`anthropics/claude-code-action` restores those paths from the base branch.
|
|
293
|
+
|
|
294
|
+
## [0.3.0] - 2026-10-30
|
|
295
|
+
|
|
296
|
+
### Added
|
|
297
|
+
|
|
298
|
+
- Testing rules (`docs/testing-rules.md`), template-owned: what a test is for, how it proves
|
|
299
|
+
behaviour, tests and the change they cover, and the gates no agent loosens. `AGENTS.md`,
|
|
300
|
+
section 2, points to it; `docs/documentation-rules.md`, sections 2, 6, and 7, list it.
|
|
301
|
+
- Review of pull requests (`docs/contributing.md`, section 6): a rubric that every reviewer
|
|
302
|
+
applies, the project's own criteria in an owner document that the map names under "Review
|
|
303
|
+
criteria", and the rule that a defect found after the merge names what keeps the next one out.
|
|
304
|
+
- Module `code_review` (question `code_review`, default on): the `code-review` workflow
|
|
305
|
+
(`.github/workflows/code-review.yml`) and the `review-code` skill
|
|
306
|
+
(`.claude/skills/review-code/SKILL.md`) review pull requests that change code, contracts,
|
|
307
|
+
checks, or workflows against that rubric with Claude Code, with the same secret and app as
|
|
308
|
+
`docs-review`, and install no plugin.
|
|
309
|
+
- Module `dual_review` (question `dual_review`, default off): the `dual-review` skill
|
|
310
|
+
(`.claude/skills/dual-review/SKILL.md`) reviews a branch before its pull request with a Claude
|
|
311
|
+
subagent and the Codex CLI in a read-only sandbox, after a passing `scripts/check.sh`, for at
|
|
312
|
+
most three rounds, without commits; its verdict goes under "Checks" in the description
|
|
313
|
+
(`docs/contributing.md`, sections 3 and 4).
|
|
314
|
+
|
|
315
|
+
### Changed
|
|
316
|
+
|
|
317
|
+
- `create-pr` skill: waits for and answers the `code-review` run next to `docs-review`, and with
|
|
318
|
+
the `dual_review` module runs the dual review when the branch has no verdict for its tree.
|
|
319
|
+
- `docs/contributing.md`, section 3: every review comment is answered before the merge, from
|
|
320
|
+
either review workflow.
|
|
321
|
+
- Linter configuration (`.markdownlint-cli2.jsonc`): in `CHANGELOG.md`, headings need to be
|
|
322
|
+
unique among siblings only, so that each version can have its own Added and Changed.
|
|
323
|
+
- Seeded `docs/README.md`: rows for the testing rules and the review of pull requests, and the
|
|
324
|
+
planned "Review criteria" section. An existing project copies these rows by hand.
|
|
325
|
+
|
|
326
|
+
## [0.2.0] - 2026-10-29
|
|
327
|
+
|
|
328
|
+
### Changed
|
|
329
|
+
|
|
330
|
+
- `create-pr` skill (`.claude/skills/create-pr/SKILL.md`), with the `docs_review` module: after
|
|
331
|
+
opening the pull request it waits for the `docs-review` run, answers every comment (a fix in
|
|
332
|
+
its own commit, a decline with a reason, or a question for the owner), records the outcome in
|
|
333
|
+
the description, and reports it; a draft or a run that does not finish is reported instead of
|
|
334
|
+
waited for. `docs/contributing.md`, section 4, names the new step.
|
|
335
|
+
|
|
336
|
+
## [0.1.0] - 2026-10-29
|
|
337
|
+
|
|
338
|
+
### Added
|
|
339
|
+
|
|
340
|
+
- Agent rules (`AGENTS.md` with one project block, `CLAUDE.md`), documentation rules with file
|
|
341
|
+
ownership (`docs/documentation-rules.md`), contribution and template update rules
|
|
342
|
+
(`docs/contributing.md`), and the seeded documentation map (`docs/README.md`).
|
|
343
|
+
- Short decision records: `docs/decisions/adr-template.md` and the generated index
|
|
344
|
+
`docs/decisions/README.md` (`scripts/gen-decisions-index.sh`).
|
|
345
|
+
- Checks behind one entry point, `scripts/check.sh`: documentation (markdownlint-cli2, lychee),
|
|
346
|
+
decision records (integrity, next number, index, merge readiness), template integrity
|
|
347
|
+
(`.template/owned.sha256`), and project checks from `scripts/checks.d/`.
|
|
348
|
+
- Claude Code hooks (protect, Stop checks, project Stop hooks from `.claude/hooks/project/stop/`)
|
|
349
|
+
and skills (`create-pr`, `update-template`, and `docs-review` as the `docs_review` module).
|
|
350
|
+
- CI workflows `docs` (with Node.js set up), `decisions`, and `docs-review`, with the runner chosen
|
|
351
|
+
by a question and overridable by the repository variable `CI_RUNS_ON`.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dev-oleksandrv and the contributors of xandronak/agent-docs-template
|
|
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
CHANGED
|
@@ -1,3 +1,78 @@
|
|
|
1
|
-
#
|
|
1
|
+
# create-afe-project
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An npm package that creates agent-friendly repositories and keeps them up to date. It gives a new
|
|
4
|
+
project its documentation rules, short decision records with a generated index, contribution and
|
|
5
|
+
pull request rules, checks that run the same way locally, in Claude Code hooks, and in CI, and the
|
|
6
|
+
Claude Code skills that apply them. It implements the pillars of
|
|
7
|
+
[Agent-Friendly Engineering](https://github.com/dev-oleksandrv/afe/blob/main/GUIDE.md). Repository:
|
|
8
|
+
`dev-oleksandrv/create-afe-project`; it started as a fork of the Copier template
|
|
9
|
+
`xandronak/agent-docs-template`.
|
|
10
|
+
|
|
11
|
+
## What a generated project gets
|
|
12
|
+
|
|
13
|
+
| Part | Files |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| Agent rules | `AGENTS.md` with one project block, `CLAUDE.md` |
|
|
16
|
+
| Testing rules: what a test is for and must prove | `docs/testing-rules.md` |
|
|
17
|
+
| Documentation rules, statuses, and file ownership | `docs/documentation-rules.md`, `docs/README.md` |
|
|
18
|
+
| Branches, commits, pull requests, template updates, review of pull requests | `docs/contributing.md` |
|
|
19
|
+
| Decision records | `docs/decisions/adr-template.md`, a generated `docs/decisions/README.md` |
|
|
20
|
+
| Checks and environment | `scripts/check.sh` and the scripts it runs, the link check `scripts/check-links.mjs` included; `scripts/env.sh` for the environment commands; `scripts/protect-branch.sh` for the GitHub ruleset of `main`; optional `scripts/check-acceptance.sh` and `scripts/fail-without-change.sh` |
|
|
21
|
+
| Claude Code hooks, permissions, and skills | `.claude/settings.json` (generated): deny rules for secrets and destructive pushes; `.claude/hooks/`: the protect hook (asks before protected edits, publishing, and a known token format; denies a push to `main`), the check after every edit, and the Stop hooks; `.claude/skills/`: `afe-init` (sets up the code, its stack, and its checks with the owner), `create-pr`, `update-template`, optional `docs-review`, `review-code`, and `dual-review` |
|
|
22
|
+
| CI | `.github/workflows/` (`docs`, `decisions`, optional `secret-scan`, `docs-review`, `code-review`, and `fail-without-change`) |
|
|
23
|
+
|
|
24
|
+
Every file has one owner: the template, the project, or a generator. The rules are in
|
|
25
|
+
[`template/docs/documentation-rules.md.jinja`](template/docs/documentation-rules.md.jinja),
|
|
26
|
+
section 9.
|
|
27
|
+
|
|
28
|
+
## Requirements
|
|
29
|
+
|
|
30
|
+
Node.js 20 or later with npm, Git, and bash. A generated project needs nothing more: its hooks
|
|
31
|
+
and checks, the link check included, run on Node.js.
|
|
32
|
+
|
|
33
|
+
## Create a project
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm create afe-project@latest <directory>
|
|
37
|
+
# or
|
|
38
|
+
npx create-afe-project@latest <directory>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
The wizard asks for the project name, a one-sentence description, the GitHub repository, the CI
|
|
42
|
+
runner (GitHub-hosted, or a self-hosted Linux runner), whether pull requests get the Claude
|
|
43
|
+
documentation review and code review, whether the review before a pull request adds the Santa
|
|
44
|
+
loop (with the Codex CLI when it is installed, otherwise with two Claude subagents), whether CI
|
|
45
|
+
scans every change for secrets with gitleaks, and whether to add the Acceptance check and the
|
|
46
|
+
fail-without-change driver. It then writes the generated files and prints the next
|
|
47
|
+
steps. Without a terminal, or with `--defaults`, it takes answers from `--data key=value` and
|
|
48
|
+
`--data-file answers.json`, then the defaults:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx create-afe-project@latest acme --defaults --data project_name=acme \
|
|
52
|
+
--data 'project_description=A sample project.' --data github_repo=acme/acme
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
`npx create-afe-project --help` lists every option.
|
|
56
|
+
|
|
57
|
+
## Update a project
|
|
58
|
+
|
|
59
|
+
In the project, the `update-template` skill does it, following the project's
|
|
60
|
+
`docs/contributing.md`, section 5: a branch from a clean `main`, then
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
npx create-afe-project@latest update --defaults
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
It replaces the template-owned files, keeps the project block of `AGENTS.md`, creates missing
|
|
67
|
+
seeded files and never changes existing ones, runs the migrations between the two versions, and
|
|
68
|
+
regenerates the generated files; then the checks and a pull request. A project generated by the
|
|
69
|
+
Copier template converts its `.copier-answers.yml` to `.afe-answers.json` on its first update.
|
|
70
|
+
|
|
71
|
+
## Versions
|
|
72
|
+
|
|
73
|
+
Releases are npm versions, tagged `vMAJOR.MINOR.PATCH` in Git and described in [`CHANGELOG.md`](CHANGELOG.md).
|
|
74
|
+
How versions are chosen and released: [`docs/maintaining.md`](docs/maintaining.md).
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
[MIT](LICENSE).
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Command line of create-afe-project: create a project, or update one to this package's template.
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
import { parseArgs } from 'node:util';
|
|
6
|
+
import * as p from '@clack/prompts';
|
|
7
|
+
import { UsageError } from '../src/answers.js';
|
|
8
|
+
import { VERSION, create, update } from '../src/project.js';
|
|
9
|
+
|
|
10
|
+
const HELP = `create-afe-project ${VERSION}
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
npm create afe-project@latest [directory] [-- options]
|
|
14
|
+
npx create-afe-project@latest [directory] [options] create a project
|
|
15
|
+
npx create-afe-project@latest update [options] update the project in the current directory
|
|
16
|
+
|
|
17
|
+
Options:
|
|
18
|
+
--defaults do not ask: take --data, then the recorded answers, then the defaults
|
|
19
|
+
--data key=value answer a question; repeatable
|
|
20
|
+
--data-file <file> answers from a JSON file; --data wins over it
|
|
21
|
+
--force create: write into a directory that is not empty
|
|
22
|
+
--no-git create: do not make the initial Git commit on main
|
|
23
|
+
--allow-dirty update: run with uncommitted changes
|
|
24
|
+
--quiet print only errors and the result
|
|
25
|
+
-h, --help print this help
|
|
26
|
+
-v, --version print the version
|
|
27
|
+
`;
|
|
28
|
+
|
|
29
|
+
function given(values) {
|
|
30
|
+
const data = values['data-file'] ? JSON.parse(readFileSync(values['data-file'], 'utf8')) : {};
|
|
31
|
+
for (const pair of values.data ?? []) {
|
|
32
|
+
const i = pair.indexOf('=');
|
|
33
|
+
if (i < 1) throw new UsageError(`--data expects key=value, got ${pair}`);
|
|
34
|
+
data[pair.slice(0, i)] = pair.slice(i + 1);
|
|
35
|
+
}
|
|
36
|
+
return Object.fromEntries(Object.entries(data).filter(([k]) => !k.startsWith('_')));
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function main() {
|
|
40
|
+
const { values, positionals } = parseArgs({
|
|
41
|
+
allowPositionals: true,
|
|
42
|
+
options: {
|
|
43
|
+
defaults: { type: 'boolean' },
|
|
44
|
+
data: { type: 'string', multiple: true },
|
|
45
|
+
'data-file': { type: 'string' },
|
|
46
|
+
force: { type: 'boolean' },
|
|
47
|
+
'no-git': { type: 'boolean' },
|
|
48
|
+
'allow-dirty': { type: 'boolean' },
|
|
49
|
+
quiet: { type: 'boolean' },
|
|
50
|
+
help: { type: 'boolean', short: 'h' },
|
|
51
|
+
version: { type: 'boolean', short: 'v' },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
if (values.help) return void process.stdout.write(HELP);
|
|
55
|
+
if (values.version) return void process.stdout.write(`${VERSION}\n`);
|
|
56
|
+
|
|
57
|
+
const interactive = Boolean(process.stdin.isTTY && process.stdout.isTTY) && !values.defaults;
|
|
58
|
+
const quiet = Boolean(values.quiet);
|
|
59
|
+
const common = { given: given(values), useDefaults: Boolean(values.defaults), interactive, quiet };
|
|
60
|
+
if (interactive) p.intro(`create-afe-project ${VERSION}`);
|
|
61
|
+
|
|
62
|
+
if (positionals[0] === 'update') {
|
|
63
|
+
if (positionals.length > 1) throw new UsageError('update takes no directory; run it in the project');
|
|
64
|
+
const r = await update(process.cwd(), { ...common, allowDirty: Boolean(values['allow-dirty']) });
|
|
65
|
+
const lines = [`Updated the template from ${r.from ?? 'an unrecorded version'} to ${r.to}.`];
|
|
66
|
+
if (r.legacy) lines.push('Converted .copier-answers.yml to .afe-answers.json.');
|
|
67
|
+
if (r.migrations.length) lines.push(`Migrations run: ${r.migrations.join(', ')}.`);
|
|
68
|
+
if (r.removed.length) lines.push(`Removed, no longer template-owned: ${r.removed.join(', ')}.`);
|
|
69
|
+
if (r.seeded.length) lines.push(`Created missing seeded files: ${r.seeded.join(', ')}.`);
|
|
70
|
+
if (r.unowned.length) lines.push(`Created files without an owner class (a template defect): ${r.unowned.join(', ')}.`);
|
|
71
|
+
if (r.edited.length) {
|
|
72
|
+
lines.push(`Replaced local edits of template-owned files; review them in git diff: ${r.edited.join(', ')}.`);
|
|
73
|
+
}
|
|
74
|
+
lines.push('Next: scripts/check.sh, then a pull request (docs/contributing.md, section 5).');
|
|
75
|
+
return void (interactive ? p.outro(lines.join('\n')) : console.log(lines.join('\n')));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (positionals.length > 1) throw new UsageError('expected at most one directory');
|
|
79
|
+
let dir = positionals[0];
|
|
80
|
+
if (!dir) {
|
|
81
|
+
if (!interactive) throw new UsageError('name the directory to create the project in');
|
|
82
|
+
dir = await p.text({ message: 'Where should the project go? (a new or empty directory)', placeholder: 'my-project', validate: (v) => (v?.trim() ? undefined : 'Required') });
|
|
83
|
+
if (p.isCancel(dir)) {
|
|
84
|
+
p.cancel('Cancelled; nothing was written.');
|
|
85
|
+
process.exit(130);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
if (interactive) {
|
|
89
|
+
p.note(
|
|
90
|
+
'A few questions about the project, then yes/no questions that turn optional checks on.\n' +
|
|
91
|
+
'Press Enter to keep a default. To change an answer later, run\n' +
|
|
92
|
+
'npx create-afe-project@latest update in the project.',
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
const spinner = interactive && !quiet ? p.spinner() : null;
|
|
96
|
+
let spinning = false;
|
|
97
|
+
const { message } = await create(resolve(dir), {
|
|
98
|
+
...common,
|
|
99
|
+
force: Boolean(values.force),
|
|
100
|
+
git: !values['no-git'],
|
|
101
|
+
quiet: quiet || interactive,
|
|
102
|
+
// Start the spinner once: a second start() leaves its first timer running, and the process
|
|
103
|
+
// never exits.
|
|
104
|
+
log: (msg) => {
|
|
105
|
+
if (!spinner) return;
|
|
106
|
+
if (spinning) spinner.message(msg);
|
|
107
|
+
else spinner.start(msg);
|
|
108
|
+
spinning = true;
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
spinner?.stop('Generated files written');
|
|
112
|
+
if (interactive) p.outro(message);
|
|
113
|
+
else console.log(message);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
main().catch((error) => {
|
|
117
|
+
if (error instanceof UsageError || error?.code?.startsWith?.('ERR_PARSE_ARGS')) {
|
|
118
|
+
console.error(`create-afe-project: ${error.message}\nRun create-afe-project --help for usage.`);
|
|
119
|
+
process.exit(2);
|
|
120
|
+
}
|
|
121
|
+
console.error(`create-afe-project: ${error.message}`);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,45 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-afe-project",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Create and update agent-friendly repositories: documentation rules, decision records, checks, and Claude Code hooks and skills.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-afe-project": "bin/create-afe-project.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/",
|
|
12
|
+
"src/",
|
|
13
|
+
"template/",
|
|
14
|
+
"CHANGELOG.md"
|
|
15
|
+
],
|
|
16
|
+
"scripts": {
|
|
17
|
+
"test": "node --test test/*.test.js",
|
|
18
|
+
"changeset": "changeset",
|
|
19
|
+
"version-packages": "changeset version && npm install --package-lock-only --ignore-scripts && scripts/sync-self.sh"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=20"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+https://github.com/dev-oleksandrv/create-afe-project.git"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"create",
|
|
30
|
+
"scaffold",
|
|
31
|
+
"template",
|
|
32
|
+
"agents",
|
|
33
|
+
"claude-code",
|
|
34
|
+
"afe"
|
|
35
|
+
],
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@clack/prompts": "^1.8.1",
|
|
38
|
+
"nunjucks": "^3.2.4",
|
|
39
|
+
"yaml": "^2.9.1"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@changesets/changelog-github": "1.0.1",
|
|
43
|
+
"@changesets/cli": "3.0.3"
|
|
44
|
+
}
|
|
45
|
+
}
|