Repository navigation
Releases
@monte3l/groundwork: v1.2.0
1.2.0 (2026-11-05)
Features
Bug Fixes
- deps: bump transitive zod to 4.6.7 for GHSA-mrhx-c7xc-m3w5 (c65c739)
- packs: pin claude-code-action to v1.0.268 and record the 2026-11-04 guidance refresh (cc28704)
- packs: pin claude-code-action to v1.0.268 and record the 2026-11-04 guidance refresh (d7b9287)
@monte3l/groundwork: v1.1.1
1.1.1 (2026-10-23)
Bug Fixes
- baseline: correct mod and fork wording in guard notes (2ad9935)
- baseline: correct the mod and fork wording in the emitted guard notes (896a712)
- deps: bump vitest to 5.0.5 for @vitest/mocker advisories (e9cb0fd)
- packs: cap claude.yml at 20 turns, fix stale changeset rules (#270) (c8e4d07)
- packs: pin claude-code-action to v1.0.258 in the claude-github pack (1bab275)
@monte3l/groundwork@1.1.0
Minor Changes
-
#253
f47c0f3Thanks @enri3l! - pack(frontend): new optionalfrontendpack for a project that builds UI, with a read-onlyui-revieweragent and anew-componentskill. The agent does a static accessibility review of changed components, markup and styles against WCAG 2.2 at level AA (the animation criterion is AAA and is only ever a recommendation) and reports anything that needs a browser, a measurement or assistive technology asNOT CHECKEDinstead of guessing. It has onlyRead,GrepandGlob, so the dispatch prompt must name the files to review. The skill ships no framework templates: it mirrors an existing sibling component's conventions and routes the writing throughtest-author,code-implementerandui-reviewer./customizerecommends the pack for thefrontendkind only; install it with--pack frontendor from/customize. -
#254
87d8422Thanks @enri3l! - pack(service): new optionalservicepack for a project that serves an API, with a read-onlyperformance-analyzeragent and anapi-docskill. The agent does a static review of changed server code for blocking calls (the Node.js event-loop guide's list, applied only when the project runs Node), per-request cost and unbounded work, and reports anything that needs profiling or a load test asNOT CHECKEDinstead of guessing. It has onlyRead,GrepandGlob, so the dispatch prompt must name the files to review. The skill writes an OpenAPI description from the routes the code actually defines, using a template inside the skill, marks anything it cannot confirm asTODOand unverified, and adds no dependency./customizerecommends the pack for theservicekind only; install it with--pack serviceor from/customize.
Patch Changes
-
#258
010e0fdThanks @enri3l! - pack(frontend, service): tighten the two review agents' static-review rules after a paid eval caught each breaking one.ui-reviewerno longer quotes a contrast ratio against a background the files never set (it must not assume white or any default, and reports the pair to measure asNOT CHECKED).performance-analyzerno longer describes a cost as slow, fast or large or gives a latency formula; it says what grows (round trips, bytes buffered, how long the event loop is blocked) and leaves how much toNOT CHECKED. -
#246
40f2907Thanks @enri3l! - pack(claude-github): pinanthropics/claude-code-actionat v1.0.254 inclaude.ymlandclaude-pr-review.yml. The release only moves the bundled Claude Code from 2.1.303 to 2.1.304. A project that already installed the pack keeps its own pin. -
#250
cc6d620Thanks @enri3l! - The baseline'spermissions.denynow also blocks readingcredentials.jsonandsecrets.yamlat any depth, and editingpnpm-lock.yaml,package-lock.json,yarn.lockand the repository's.git/directory. The edit rules areEdit(...)rules, which Claude Code applies to every built-in file-editing tool, so the package manager and git stay the only writers of those files. A subprocess such aspnpm installstill rewrites the lock file,grep -ror a script that opens a denied file is not covered, and in a linked worktree.gitis a file the.git/rule does not match. A fresh project gets the entries. An adopted project with its own.claude/settings.jsonsees this as asettings.jsonconflict in/customize(keep, take or merge), and one without it gets the staged file; the CLI never edits an existingsettings.json. -
#244
b03b131Thanks @enri3l! - pack(harness-extras):guard-readonly-bashnow judges a read-only agent's Bash command against an allowlist of read verbs instead of a denylist of mutating ones, because the denylist let real writes through. An off-list verb now blocks (awk,python,gh,curl,make,tar,ln,install,patch,rsync, a shell without-c, a verb built through expansion), as does an off-list git subcommand (fetch,archive,submodule update) or write flag (git diff --output,git grep -O),node -eor-p,sed -ni,sed --in-pl,sedscripts that usewore,sed -f,sort -o,uniq in out,find -fprint,find -execof an off-list command, and a command substitution that hides one (echo $(rm x)). The allowlist assumes the baseline's toolchain (pnpm,npm,eslint,prettier,tsc,vitest,knip,publint,attw): an adopted project onyarn,make,jestorbiomeshould run its checks through apackage.jsonscript, since a read-only agent can no longer call those verbs directly. A script file run throughnode,pnpm <script>ornpm run <script>is still not inspected, so the guard raises the bar and proves nothing. A project that already installedharness-extraskeeps its copy of the hook untouched. -
#256
0efd47cThanks @enri3l! - feat(baseline): scope what the baseline's skills may do. Seven core skills and six pack skills gainallowed-tools(read-only pre-approvals with no wildcard ongit, and nogh api),disallowed-tools(Write,Edit,NotebookEditon the three github-pack skills that only report or act throughgh) andargument-hint.allowed-toolsonly skips the prompt and does not restrict, so every grant is a command that cannot write.starting-workalso gains a read-only environment preflight that reports a Node version mismatch, a missingnode_modulesand missing git hooks, and never installs anything. -
#244
b03b131Thanks @enri3l! - pack(quality): thetype-design-analyzeragent no longer says the read-only Bash guard blocks every shell write route, since the guard is an allowlist that still does not inspect a script file run throughnodeor a package script. A project that already installed thequalitypack keeps its copy of the agent untouched. -
#257
20af585Thanks @enri3l! - pack(worktrees): theworking-in-worktreesskill's.envcopy step no longer collides with the baseline'sRead(./.env)deny rules. It copies withcp -n, never reads or prints a file, and if Claude Code denies the copy it stops and asks the owner to copy the files themselves instead of working around the block.
@monte3l/groundwork@1.0.5
Patch Changes
-
#232
4fe7bffThanks @enri3l! - Refresh the emitted baseline and packs against current Claude Code and TypeScript guidance.templates/core/CLAUDE.mdis trimmed under the 200-line startup-warning target (the guard detail moved toagent-dispatch.md), the skill-description grader message now states the real limits,guard-worktree-onlyfails closed (onFailure: "block"), theclaude-githubpack'sclaude-code-actionpin moves to v1.0.253, and a few config comments (consistent-type-imports, Vitest coverage, attw) are corrected. A project that already installed theworktreespack should add"onFailure": "block"to itsguard-worktree-only.mjsregistration by hand, unless/customizeinstalls the pack again, which now adds the missing key. -
#238
acbd2b9Thanks @enri3l! - pack(claude-github): the Claude Code GitHub Action workflows (claude.ymlandclaude-pr-review.yml) move out of thegithubpack into a newclaude-githubpack, so thegh-CLI skills can be adopted without a workflow that needs an auth secret and spends API credits on every pull request.--pack githubno longer emits either workflow; pass--pack github --pack claude-githubfor the previous set./customizerecommendsclaude-githubfor no project kind by default. A project that already installedgithubkeeps its files untouched. -
#240
359c4d6Thanks @enri3l! - pack(licensing): the SPDX/REUSE license-header gate (check-license-headers.mjs, itslicense-headersverify step and theREUSE.tomltemplate) moves out of thepublishingpack into a new fresh-onlylicensingpack, so a project can take the header gate without the npm release pipeline and the other way round.--pack publishingno longer emits the gate orREUSE.toml, and its one-time setup shrinks topnpm add -D @changesets/cli; pass--pack publishing --pack licensingfor the previous set, and run licensing'sgit add -A/--fixbackfill./customizerecommendslicensingforlibraryandcliprojects, likepublishing. A project that already installedpublishingkeeps its files untouched. -
#239
0fe23b9Thanks @enri3l! - pack(statusline): the Claude Code status line (statusLine,subagentStatusLineand their three scripts) moves out of theharness-extraspack into a newstatuslinepack, so a project that already has its own status line can take the compaction-handoff hooks and the read-only Bash guard without a settings collision.--pack harness-extrasno longer plants either settings key; pass--pack harness-extras --pack statuslinefor the previous set.statuslineis a live pack name again, so--pack statuslineinstalls it instead of printing a rename hint toharness-extras. A project that already installedharness-extraskeeps its files and settings untouched.
@monte3l/groundwork@1.0.4
Patch Changes
- #217
4c33e62Thanks @enri3l! - The publishing pack'stools/release/package-lock.jsonis now shipped in the tarball (escaped as_package-lock.json); previously npm-family packing stripped it, sonpm ci --ignore-scripts --prefix tools/releasehad no lockfile in a project bootstrapped with--pack publishing.
@monte3l/groundwork@1.0.3
@monte3l/groundwork@1.0.2
@monte3l/groundwork@1.0.1
Patch Changes
-
#190
40cca6cThanks @enri3l! - baseline: the emittedsettings.jsonnow blocks the call when one of its four invariant guards crashes or times out (guard-secret-writes,guard-hub-src-writes,guard-branch-isolation,guard-protected-pathscarry"onFailure": "block", Claude Code 2.1.295 or later) and denies reading.env,.env.*andsecrets/**.code-implementeris granted both themcp__context7__*and the plugin-namespacedmcp__plugin_context7_context7__*tool names. The baseline'sCLAUDE.mdandagent-dispatch.mdnow say that a spoke cannot nest becausedisallowedTools: Agentstops it (Claude Code otherwise allows three layers) and that a session in auto,acceptEditsor bypass mode overrides a spoke'spermissionMode.typescript-guidancerecords a project with no TypeScript toolchain aslast-verified=n/ainstead ofunset, treats a test runner, linter or type-test tool's own documentation (named in the project'sdevDependencies) as a source for that tool, andharness-guidancenotes how far back it read the changelog on a first sweep. Installing a pack now writes.claude/settings.jsonthe way Prettier prints it (a short array of strings stays on one line), so the emitted project's own format check keeps passing after the baseline gained apermissions.denyarray. -
#188
68f3ff7Thanks @enri3l! - adopt: a re-run now also deletes.groundwork/customization-report.md, the report/customizewrites at the end of an adopt run, and names it in the removed-files message. The adoption report's.gitignoreadvice now recommends tracking the two reports and ignoring the rest of.groundwork/. The/customizeskill copied into the project replaces the report sections it supersedes, keepsadoption-decisions.jsoncurrent and resumable, retargets installed skills and agents to the project's tooling, asks before treating a missing.groundwork/on a repository with commits as a fresh bootstrap, and points its re-run advice at the defaultlatesttag instead of@rc.
@monte3l/groundwork@1.0.0
Major Changes
-
#22
7afec0eThanks @enri3l! - First stable 1.0 release. The public API is frozen as of this release: CLI flags, modes, and exit codes; the.groundwork/inventory.jsonandadoption-report.mdfile formats; the.groundwork/packs/staging layout and pack names; theengines.nodefloor; and/customize's invocation name. See the README's "Versioning policy" section for the full list and what's explicitly excluded (the baseline's emitted contents, which follow current upstream guidance and can still change in a minor release).Only fixes land in the 1.0 series -- any further API change waits for 1.1. Users of the
0.xnexttag or a1.0.0-rcrelease must switch tolatest: SemVer prerelease ranges don't cross from0.1.0-next.Nor1.0.0-rc.Nto1.0.0automatically.
Minor Changes
-
#11
5c56af2Thanks @enri3l! - First public release.@monte3l/groundworkbootstraps a TypeScript + Claude Code project (fresh mode) or surveys an existing one read-only (adopt mode). It installs the/customizeskill (@monte3l/groundwork-plugin, distributed via themonte3lClaude Code plugin marketplace, not npm) into every project it touches. -
#16
7095714Thanks @enri3l! - Breaking (allowed pre-1.0; see the upcoming versioning policy): the CLI's argument parsing is now strict. An unrecognized flag, a--name/--packgiven with no value (or a value that looks like another flag), more than one positional argument, or--adopttogether with--freshnow fail fast with a usage error and exit code2, instead of being silently accepted or ignored. A genuine runtime error still exits1.--help/-hand--version/-vare now both documented in the usage text.The published package's
exportsmap no longer advertises a"."entry (normain/types) --@monte3l/groundworkis a CLI, not a library, and its only supported entry point is them3l-groundworkbinary. Importing it as a JS module was never documented and is no longer possible..groundwork/adoption-report.md's header now also states the inventory'sschemaVersionalongside the CLI version that generated it.
Patch Changes
-
#184
b32e689Thanks @enri3l! -1.0.0is the same code as1.0.0-rc.8, published on thelatestdist-tag. The package README now saysnpx @monte3l/groundworkwith no@rc. -
#142
8140d8bThanks @enri3l! - Adopt mode now recognises a Claude Code plugin repository. The inventory moves to schema 6 and recordssurvey.harness.pluginLayout(the.claude-plugin/plugin.jsonmanifest and which ofhooks/hooks.json,skills/,agents/,commands/and.mcp.jsonexist). The adoption report no longer prints "0 of 0 checks pass" or "100% over 0 checks" when nothing was gradable, says plugin components at the repository root are outside the harness grader's scope, and leaves fresh-only packs (publishing) out of the post-merge cap estimate./customizegains apluginproject kind, recommendsplugin-devfor it, names.claude/files by full path inCLAUDE.md, and grades the harness after Round 2. -
#93
aac52e3Thanks @enri3l! - Align the emitted baseline's devDependencies with the repo's own toolchain: vitest and @vitest/coverage-v8 move to ^5.0.2, and eslint, typescript-eslint, knip and the pnpmpackageManagerpin move to their current minors. TypeScript stays on ^6.0.3. -
#33
7aa6665Thanks @enri3l! - The emitted baseline's CI workflows now pin everyuses:by commit SHA (with a# vXcomment naming the tag) instead of a floating major tag, matching this repo's own SHA-pinning discipline:actions/checkout(v6 -> v7),pnpm/action-setup(v4 -> v6),actions/setup-node,actions/dependency-review-action(v4 -> v5), andactions/github-script. A new.github/dependabot.yml(github-actions ecosystem) keeps those pins from going stale. Theclaude-actionpack's workflow gets the same treatment (actions/checkoutv6 -> v7,anthropics/claude-code-actionv1 -> the exact patch this repo pins). -
#115
1d995faThanks @enri3l! - An unexpected CLI failure now prints its error name (TypeError: ...), and settingM3L_DEBUGto any non-empty value also prints its stack trace. Bidirectional-text control characters in error messages are escaped like other control characters. When adopt mode has to stage the/customizeskill at.groundwork/customize/, the adoption report's next step now says so, matching the console. -
#91
44d9063Thanks @enri3l! - Fresh mode now fails before writing anything when it can know the run will not work. Exit-code change: an unknown or fresh-incompatible--packnow exits 2 (a usage error, with the usage text) instead of exiting 1 after half-writing the target;--pack statuslinepoints atharness-extras, which it was folded into. Fresh mode on Windows is refused before anything is written, with exit 1 ("Windows is not supported yet (Linux and macOS only)"); adopt mode,--help,--versionand--list-packsstill work there. A failedgit initorpnpm installafter the project is written now exits 1 with one message that says the project was written and what to run by hand, and keeps the original error as its cause, instead of a raw stack trace. -
#30
4592b61Thanks @enri3l! - The CLI's invocation contract now rejects several previously-silent or wrongly-coded invocations as usage errors (exit code 2), matching the frozen "invalid or contradictory invocations fail fast" policy:- Adopt mode now rejects
--forceand--packoutright withCliUsageError, instead of throwing a plain runtime error (--force, exit 1) or silently ignoring the flag entirely (--pack). --adoptagainst a target directory that doesn't exist now fails with a clear usage error, instead of an uncaught filesystem exception.- A repeated
--name(or any future single-value flag) now fails fast, instead of silently keeping the last value. .groundwork/adoption-report.mdnow detects a git worktree or submodule (.gitas a file, not a directory) as an existing project to adopt, instead of misdetecting it as empty.- A malformed
package.jsonis now recorded once in the adoption report's undetermined list, instead of being silently dropped (or, in one intermediate state, reported twice). - The adoption report's caps table now shows Workflows and Scripts rows, and folds every listed pack's budget into the displayed post-merge total and over-cap warning, instead of omitting two of the five caps and excluding pack budgets from the total it displays.
- A pack whose
pack.jsonhas an internalnamenot matching its own directory, or a malformedbudget, now fails to load with a clear error instead of risking a staging collision or propagatingNaNinto the caps table. - Several smaller robustness fixes: a non-object
tsconfig.json/package.json(e.g. literallynull) no longer crashes conflict detection; the/customizeskill's staleness check now compares all four of its files, not justSKILL.md; a settings-merge collision check no longer misfires on two semantically-identical values that merely have their keys in a different order; re-staging a pack now clears files a newer version dropped.
- Adopt mode now rejects
-
#116
57307a7Thanks @enri3l! - Fresh mode now checks every destination of the baseline, any--packand the/customizeskill before writing anything, and refuses (writing nothing) when one sits under a symlink or a non-directory, or is a symlink or directory where a file goes (a symlink at a/customizeskill file is replaced, never written through), so--forceno longer writes through a symlinked.claude. The adopt survey records a file or directory it cannot read, or a dangling link or loop, underundeterminedinstead of aborting. The emittedguard-hub-src-writes.mjsnow also blocks writes to or removal of a parent ofsrc/ortests/,phpanddenowrite verbs andnode/pythondeletes and moves; it remains a conservative screen, not a proof. The emittedcheck-toolchainstep and a...