Project Calavera
is an open-source CLI tool that scaffolds linters, formatters, AI tooling such
as agent skills, hooks, and subagents, and other common
project infrastructure for web projects. It works standalone for vanilla
JavaScript, TypeScript, and library projects, and it works as a complement to
framework scaffolding tools like Vite+ and vp create, giving any project a
consistent, repeatable setup through a single recipe file.
See docs/vite-plus.md for the litmus test and a full
statement of what Calavera adds to a vp create project and what it leaves to
Vite+.
Use Calavera after a project already exists, whether it came from vp create,
Vite, another scaffold tool, or a manually maintained repository. To start a new
Vite+ project and bootstrap it in one command, run
npm create project-calavera -- --new from the parent folder instead of steps 1
and 2. Vite+ asks its own questions and writes the scaffold; see
--new
for details.
After --new or --init, Calavera prints the next steps. The project needs a
recipe before Calavera changes anything, so the block offers the agent prompt or
the hosted Composer, with the save location and the commands for the project's
package manager. After --new, from the parent folder, it reads:
Your project needs a recipe before Calavera changes anything.
Either: open /home/me/code/my-app in your agent and use the prompt above.
Or: compose one at https://calavera.schalkneethling.com/ and save
calavera.config.json into /home/me/code/my-app, then:
cd /home/me/code/my-app
npm create project-calavera apply -- --dry-run
npm create project-calavera apply
--init prints the same block without the cd line; --init --json returns it
as a nextSteps array.
If you composed a recipe first, pass it with --config before --new:
npm create project-calavera -- --config ~/Downloads/calavera.config.json --new.
Calavera validates the recipe before vp create runs, copies it into the
scaffolded project as calavera.config.json, and prints the preview and apply
commands for it. It does not apply the recipe.
- Open the project directory.
- Run
npm create project-calavera -- --init. - Choose exactly one project-local MCP host when prompted: Claude Code, Codex, Cursor, OpenCode, or skip/manual.
- Restart or reload the agent session if your MCP host does not discover new tools dynamically.
- Confirm the Calavera MCP tools are exposed:
inspect_project,list_profiles,list_integrations,list_ai_artifacts,compose_recipe,validate_recipe,explain_recipe,dry_run_apply, andapply_recipe. - Start the agent from the project root.
- Agent prompt:
Use Calavera for this project. First verify that the Calavera MCP tools are available. If they are not available, stop and help me configure the MCP server before composing or applying anything. Once the tools are available, inspect the current project for existing tooling and possible config conflicts, list the available profiles, integrations, and AI artifacts, compose a recipe, validate and explain it, show me the dry-run result, and apply it only after I approve.
Find the equivalent commands for your package manager in the agent-first command table.
| Package manager | Bootstrap agent guidance | Preview apply | Apply recipe |
|---|---|---|---|
| npm | npm create project-calavera -- --init |
npm create project-calavera apply -- --dry-run |
npm create project-calavera apply |
| pnpm | pnpm dlx create-project-calavera --init |
pnpm dlx create-project-calavera apply --dry-run |
pnpm dlx create-project-calavera apply |
| Yarn | yarn dlx create-project-calavera --init |
yarn dlx create-project-calavera apply --dry-run |
yarn dlx create-project-calavera apply |
| Bun | bunx create-project-calavera --init |
bunx create-project-calavera apply --dry-run |
bunx create-project-calavera apply |
npm create needs the -- separator before Calavera flags such as --init
and --dry-run. Do not use npm create project-calavera --init; npm treats
--init as its own option and Calavera falls back to the recipe CLI. Yarn
requires Yarn 2+ for dlx; Yarn 1.x users can use
npx --package create-project-calavera create-project-calavera --init.
Direct binary launchers such as npx --package do not need an extra -- before
Calavera flags: use
npx --package create-project-calavera create-project-calavera --help, not
npx --package create-project-calavera create-project-calavera -- --help.
MCP server registrations launch create-project-calavera-mcp directly and
should not add --help.
Agents should treat dry_run_apply as the approval boundary. They should show
the package manager, integrations, dependency packages and their install
command, inspection findings,
omitted script explanations, ownership notes, file changes, and AI artifact
changes before calling apply_recipe.
If MCP tools are not exposed, agents should configure or repair MCP setup first;
they should not inspect npm cache internals or import Calavera source files from
package cache paths as a substitute for MCP setup.
If the agent finds likely conflicts, it should pause and list whether each one is a hard stop or a migration decision the user can still approve. A dry run is the best next step when adoption is still possible and the user wants to see the impact.
Compose the recipe yourself with the interactive CLI:
npm create project-calavera init
npm create project-calavera apply -- --dry-run
npm create project-calavera applyinit composes calavera.config.json; -- --init bootstraps agent guidance.
Use the web UI when you prefer browser composition. Save or download
calavera.config.json, then run the displayed package-manager command from the
project folder that contains the saved file.
See
docs/agent-first-calavera-workflow.md
for agent, CLI, web UI, MCP/WebMCP, Vite+, other scaffold, and existing-project
examples.
Some starters declare Bun in devEngines.packageManager. npm 11 fails before
Calavera can run when npm create is used from one of those projects:
Invalid devEngines.packageManager
Invalid name "bun" does not match "npm" for "packageManager"
Use the package manager declared by the project instead:
bunx create-project-calavera applyThe same rule applies to manual MCP server registration. Use
bunx --package create-project-calavera@<version> create-project-calavera-mcp
instead of npx --package create-project-calavera@<version> create-project-calavera-mcp
when the agent harness launches Calavera from a Bun-managed project root. The
explicit version avoids Bun dropping the non-default create-project-calavera-mcp
bin during ad-hoc --package resolution and keeps every persistent MCP
registration from floating to a later package release.
If bunx reports error: bun is unable to write files to tempdir: PermissionDenied in a restricted agent or MCP sandbox, configure the MCP host to
set TMPDIR to an absolute writable directory. If Bun's package cache is also
blocked, set BUN_INSTALL_CACHE_DIR to an absolute writable cache directory for
that server registration.
If you intentionally want to launch through npm anyway, npm requires --force
to bypass its own devEngines preflight:
npm --force create project-calavera apply- Linting and formatting tools
- Stylelint and CSS quality plugins
- AI skills, hooks, and agents under
.agents/ package.jsonscripts- A repeatable
calavera.config.jsonrecipe
Editor extensions, global apps, shell setup, and machine-level configuration are
out of scope. Install the matching editor integrations for your development
environment of choice. Calavera does not scaffold a TypeScript configuration or
a type-check script; JavaScript and TypeScript type checking comes from
vp check in a vp-managed project.
- Default (
default): EditorConfig and Stylelint. In avp-managed project, JavaScript and TypeScript linting comes fromvp lint, formatting fromvp fmt, and type checking fromvp check; Calavera does not scaffold a linter, formatter, or TypeScript configuration for that language pair. - Minimal (
minimal): EditorConfig only
The Modern and Classic profiles were removed once their defaults became
identical (ADR-0011).
A calavera.config.json that names modern or classic fails validation with
a message naming default as the replacement.
explain_recipe, compose_recipe, and dry_run_apply report whether the
project is managed by Vite+. For a vp-managed project they state that
JavaScript and TypeScript linting, formatting, type-checking, and testing are
provided by Vite+, not by Calavera.
Calavera includes curated integration packs grouped by outcome:
- React Doctor
- Unused files, dependencies, and exports
- HTML validation
- CSS Baseline
- CSS property ordering
- CSS property type validation
- Environment variable schema and validation with Varlock
- GitHub repository governance, security settings, and drift checks
React Doctor is a deterministic scanner for React codebases that complements
vp lint with security, performance, correctness, accessibility, bundle-size,
and architecture diagnostics. The curated JavaScript and TypeScript rule packs
that once accompanied it are gone; a Vite+ project enables Oxlint plugins in the
lint block of vite.config.ts.
The optional Knip integration adds unused-file, dependency, and export analysis
to the generated quality script. Calavera writes a minimal knip.json that
keeps Knip's default project discovery and ignores .agents/**, because
Calavera-installed agent files are not imported by project code. When those defaults do not fit a
project, add targeted entry, project, or workspaces configuration as
described in the Knip configuration guide.
Calavera treats those changes as local edits and will refuse to overwrite or
remove them automatically on a later apply or clean.
The optional HTML Validate integration adds html-validate, writes
.htmlvalidate.json with the html-validate:recommended and
html-validate:document presets, and ignores node_modules/, dist/, and
coverage/ through .htmlvalidateignore. It also adds lint:html to the
generated quality script. The recommended preset already includes HTML
Validate's accessibility rules, so Calavera does not add a redundant separate
accessibility integration.
lint:html runs node scripts/lint-html.mjs "**/*.html", a Calavera-managed
wrapper around html-validate. html-validate exits with an error when no file
matches and has no option to allow empty input, so the wrapper passes when no
HTML file matches, and otherwise runs html-validate with the same patterns and
exit code. With an option, such as --stdin or --ext, it runs
html-validate directly. A real validation error still fails lint:html. In the same way,
lint:styles and lint:styles:fix pass --allow-empty-input to Stylelint, so
quality passes in a project without CSS files.
A project without static HTML files, such as one whose HTML a server or a
Worker renders, can leave lint:html out of quality with the quality
option. Calavera still generates lint:html, and a later apply keeps the
choice, because it lives in the recipe:
{
"integrations": ["html-validate"],
"integrationOptions": {
"html-validate": { "quality": false }
}
}When lint:html is the only script quality would run, Calavera does not
generate quality. Apply removes a quality script whose value an earlier
release wrote, such as npm run lint:html, and keeps any other value as your
own. The dry run shows both.
Validate the rendered HTML in your tests instead, with the HtmlValidate class
from the HTML Validate API, and
assert that the report is valid. validateString does not read
.htmlvalidate.json, so pass the configuration to the constructor:
import { readFile } from "node:fs/promises";
import { HtmlValidate } from "html-validate";
const config = JSON.parse(await readFile(".htmlvalidate.json", "utf8"));
const report = await new HtmlValidate(config).validateString(renderedHtml);HTML Validate follows HTML semantics and Calavera deliberately leaves its
doctype and void-element style rules at their honest defaults. Oxfmt, the
formatter vp fmt is built on, cannot currently be configured to preserve an
uppercase <!DOCTYPE html> or omit the slash it adds to void elements such as
<meta />. Calavera does not blanket-exclude HTML from vp fmt or weaken HTML
Validate to hide this conflict.
Projects selecting both tools should review the formatter/validator interaction
until Oxc issue #24645 is
resolved. See the HTML Validate preset documentation
for the rules included by each preset.
The CSS catalog includes stylelint-plugin-logical-css for logical CSS
property, value, and unit checks, plus
@schalkneethling/stylelint-plugin-css-property-type-validator as a curated
experimental integration.
Adding a new integration should be a catalog-first change. For example, a
Stylelint plugin entry can declare its package dependency, parent stylelint
integration, plugin name, and default rules in packages/cli/src/catalog.js; the CLI then
uses that metadata when generating .stylelintrc.json.
See
docs/contributing-calavera-integration-varlock.md
for a contributor walkthrough based on Theo Ephraim's Varlock integration.
The optional github-repository-controls integration generates a committed desired-state policy,
Dependabot configuration, a portable Node.js administration script, and setup documentation. A
recipe must identify the expected repository so the generated script can refuse to operate against
the wrong remote. The integration applies at the repository root, because GitHub reads .github/
only there: in a monorepo, a dry run or apply from a workspace member that selects it stops with a
hard stop that names the repository root, before any file is planned or written.
{
"integrations": ["github-repository-controls"],
"integrationOptions": {
"github-repository-controls": {
"repository": "octocat/example",
"requireCodeqlResults": true,
"requiredChecks": [],
"mergeMethods": ["squash"],
"codeqlLanguages": ["actions", "javascript-typescript"]
}
}
}requireCodeqlResults (default true) requires CodeQL results through the ruleset's code scanning
rule, not through a status check name, so you do not enter CodeQL in requiredChecks. Set it to
false so that Calavera does not manage the code scanning rule; a rule that already exists stays
until you delete it in the repository settings under Rules. requiredChecks (default []) lists
additional status check names. A required check is the exact name that a check reports on a pull
request, usually the workflow job name, and a name that no check reports blocks every merge. Leave
the list empty for a new project and add names after your first CI run, then re-apply the recipe. A
check added by hand to the managed ruleset is reported as drift and removed on the next apply;
require it in a separate ruleset that Calavera does not manage instead. See GitHub's
available rules for rulesets.
calavera apply only writes local files and package scripts. Run npm run repo:controls:check for
a read-only GitHub drift report, then run npm run repo:controls:apply separately after reviewing
the plan. The apply command requires confirmation unless you pass --yes explicitly, for example
npm run repo:controls:apply -- --yes. GitHub features that are unavailable for the repository or
plan are reported as unsupported rather than ordinary drift.
Newly generated policies use the extended CodeQL query suite (override with
codeqlQuerySuite: "default" in the recipe). Policy languages are required coverage; remote apply
preserves additional configured CodeQL languages. The managed default-branch ruleset requires CodeQL
results and blocks errors/warnings and medium-or-higher security alerts. The committed policy's
mainRuleset.codeScanning object exposes alertsThreshold and securityAlertsThreshold using
GitHub's threshold values. Set it to null to leave
scanning rules unmanaged; older policies without the field retain that behavior. Regenerating the
policy with calavera apply restores the generated thresholds.
The drift check also verifies branch targeting, active enforcement, no exclusions, and an explicitly empty bypass list. Remote apply repairs those shared protections while preserving unrelated rule types and other scanners. Code-scanning merge protection requires GitHub support and scan results for both the commit and target reference; enabling default setup alone does not guarantee a PR can merge.
The drift check reports a policy CodeQL language that GitHub does not detect as blocked, with the
reason. While default setup is not configured, it uses the languages GitHub reports for default
setup. When a configured setup gains a language, it reads the
repository languages API
or, for actions, which that API does not report, the .github/workflows directory on the default
branch. Remote apply runs the main ruleset first and CodeQL default setup last. A failed or
blocked change does not stop the others; only a change that requires a failed change is skipped.
An apply that does not fully succeed ends with a summary of the changes applied, failed (with the
error), and not attempted, with what to do about each, and exits with a non-zero code. Until CodeQL
default setup reports results, the generated ruleset blocks merges.
The CLI and the MCP server support Node.js ^24.11.0 || >=26.0.0. Vite+ 1.0.0
also supports Node.js 22.18 and later, but Calavera does not. On any other
Node.js version, both print the required range and exit with a non-zero code.
Create a recipe:
npm create project-calavera initThe interactive recipe composer lets you choose a profile, package manager,
integration packs, and bundled AI artifacts. By default it only writes
calavera.config.json.
Run init without selection flags for guided prompts that present the available
options. Use selection flags only for scripted or CI flows:
npm create project-calavera init -- --profile default --package-manager pnpm --tool stylelint-orderWrap labels that contain spaces in quotes, for example
--tool "CSS property ordering". Prefer ids such as stylelint-order in
scripts and CI so commands stay copy-pastable.
Apply a recipe:
npm create project-calavera applyInspect the current project:
npm create project-calavera doctorUpdate managed tooling from the recipe:
npm create project-calavera updateRemove stale managed files:
npm create project-calavera cleanInspect machine-readable output for agent workflows:
npm create project-calavera doctor --json
npm create project-calavera apply -- --dry-run --jsonBootstrap an existing project for agent-first Calavera usage without scaffolding app code:
npm create project-calavera -- --initnpm create needs the -- separator before Calavera flags. Do not use
npm create project-calavera --init; npm treats --init as its own option and
Calavera falls back to the recipe CLI. With other package managers, use
pnpm dlx create-project-calavera --init,
yarn dlx create-project-calavera --init, or
bunx create-project-calavera --init.
The Yarn command requires Yarn 2+ because Yarn 1.x does not support dlx; Yarn
1.x users can use npx --package create-project-calavera create-project-calavera --init
or install create-project-calavera globally.
The --init bootstrap installs the base Calavera skill, adds concise project
guidance, optionally writes one project-local MCP config, and prints a
recommended first prompt for the user to give their agent. It writes MCP setup
notes only when the user chooses skip/manual or project-local MCP config cannot
be written. When AGENTS.md already exists, interactive runs ask whether to
append marked Calavera guidance directly to that file or leave it unchanged and
write fallback guidance to AGENTS.calavera.md. Scripted runs keep the
fallback-only behavior unless --agents-md=append is passed.
Calavera also ships a standard MCP server for agent-native recipe composition:
npx --package create-project-calavera@<version> create-project-calavera-mcpDuring --init, Calavera can write one project-local MCP config for Claude
Code, Codex, Cursor, or OpenCode. It never writes global/user MCP config. It
writes .agents/calavera/mcp.md only when you choose skip or the selected
local config cannot be written.
Project-local config targets:
- Claude Code:
.mcp.json - Codex:
.codex/config.toml - Cursor:
.cursor/mcp.json - OpenCode:
opencode.json
Use the package manager declared by the target project's package.json.
When configuring MCP manually, choose the matching command and put the first
word in the MCP command field and the remaining words in args:
- npm:
npx --package create-project-calavera@<version> create-project-calavera-mcp - pnpm:
pnpm dlx --package create-project-calavera@<version> create-project-calavera-mcp - Yarn:
yarn dlx --package create-project-calavera@<version> create-project-calavera-mcp - Bun:
bunx --package create-project-calavera@<version> create-project-calavera-mcp
JSON-based MCP hosts use this shape:
{
"mcpServers": {
"calavera": {
"command": "npx",
"args": ["--package", "create-project-calavera@<version>", "create-project-calavera-mcp"]
}
}
}Codex uses TOML:
[mcp_servers.calavera]
command = "npx"
args = ["--package", "create-project-calavera@<version>", "create-project-calavera-mcp"]OpenCode stores local MCP servers under mcp:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"calavera": {
"type": "local",
"command": [
"npx",
"--package",
"create-project-calavera@<version>",
"create-project-calavera-mcp"
],
"enabled": true
}
}
}Project-local MCP servers run from the project root. Matching the project
package manager prevents package-manager preflight failures before Calavera can
start, such as npm 11 rejecting a Bun-managed project through
devEngines.packageManager.
When a restricted MCP host launches the Bun command, Bun may fail before
Calavera starts with error: bun is unable to write files to tempdir: PermissionDenied. Configure that MCP server environment with TMPDIR set to an
absolute writable directory, such as an absolute path to a project-local
.calavera/tmp directory.
If the package cache is also restricted, set BUN_INSTALL_CACHE_DIR to an
absolute writable directory such as an absolute path to
.calavera/bun-install-cache. Keep these as Bun-only recovery settings rather
than default MCP config.
Agent guidance should tell the harness to use Calavera when a user wants to
inspect available project tooling, compose calavera.config.json, preview a
Calavera apply run, or apply an approved recipe. An MCP client can use the tools
in this order:
inspect_projectlist_profileslist_integrationsdescribe_integrationlist_ai_artifactscompose_recipevalidate_recipeexplain_recipedry_run_applyapply_recipe
dry_run_apply returns structured JSON with the package manager, integrations,
dependency packages, the command that installs them, the Vite+ detection
report, project inspection findings,
omitted script explanations,
file ownership/action notes, and AI artifact changes that would be made. On a
project where the recipe was already applied and nothing has changed since,
every change has type: "unchanged". Agents
should present that dry-run summary to the user first. apply_recipe is
intentionally the approval boundary: call it only after the user explicitly
approves the proposed recipe and dry-run result.
--config calavera.config.json--profile default|minimal--package-manager npm|pnpm|yarn|bun; in a Vite+-managed project it does not change the dev dependency install command,vp add -D--integration <id-or-label>or--tool <id-or-label>for scripted composition; quote labels with spaces, or use ids/slugs in scripts and CI--ai-artifact <id-or-label-or-source>; use<artifact>@<target>for hook and agent targets, or omit this flag to select from the interactive option list--agents-md append|fallbackwith--initto script how existingAGENTS.mdfiles are handled--mcp-harness claude-code|codex|cursor|opencode|skipwith--initto script project-local MCP auto-config--applywithinitto preview and then confirm applying the composed recipe--dry-run--no-install--yes--json
Calavera keeps generated package scripts as ordinary tool commands. It can add
tooling, configuration, dependencies, and package scripts, but delta execution
belongs to tool-native options, project-specific scripts, Vite+/vp, or CI
workflow logic rather than a Calavera changed-file wrapper.
In a project Vite+ manages, apply installs the recipe's development
dependencies with vp add -D <packages>, using the project's own vite-plus, so
Vite+ runs the package manager version the project pins. There,
--package-manager and the MCP packageManager input do not change the
install command. Other projects keep their package manager's command, such as
pnpm add --save-dev. apply --dry-run names the command and how apply runs
it. See docs/vite-plus.md and
ADR-0012.
In a project Vite+ manages, the generated quality script runs vp check and
vp test --passWithNoTests before Calavera's own scripts, for example
vp check && vp test --passWithNoTests && pnpm lint:styles && pnpm knip. At a
workspace root, the test step is vp run -r test, which runs each member's
test script, and leaves the step out when no package defines test. Other
projects keep a quality script without vp. Calavera writes no script that
repeats a vp command on its own, and does not add Playwright or other test
suites to quality. The Stylelint scripts are lint:styles and
lint:styles:fix. In a project that has .calavera/state.json from an earlier
apply, a later apply renames a lint or lint:fix script whose value is
exactly one Calavera wrote with Stylelint; it keeps any other value as your own,
and never overwrites a lint:styles of your own. Without that state file,
lint and lint:fix are not renamed. See
ADR-0013.
See docs/vite-plus-and-delta-mode.md for
the Vite+ design boundary and delta workflow guidance.
A future @schalkneethling/create package may collapse Vite+ scaffolding,
Calavera recipe composition, Calavera apply, and project startup into a single
creation path. It should remain separate from Calavera's tooling-composition
responsibilities.
Calavera exposes agent-native recipe composition through the standard MCP server and browser-safe recipe composition through WebMCP, so coding agents can compose recipes directly instead of driving the human web UI.
See
docs/create-template-and-agent-composition.md
for the current boundary, research questions, and phase-two handoff plan.
Generated recipes reference the public draft 2020-12 schema at
https://calavera.schalkneethling.com/calavera.config.schema.json.
The maintained schema lives at apps/composer/public/calavera.config.schema.json so it is
published with the web composer.
Calavera can install bundled AI skills, hooks, and agents from the optional
ai section in calavera.config.json. The ai key is a composed list of AI
artifacts, whether it was written by hand or generated by the CLI, Web UI, or an
agent workflow.
Define the exact artifact items to include:
{
"ai": [
{ "type": "skill", "src": "skills/frontend-engineering" },
{
"type": "hook",
"src": "hooks/block-dangerous-commands",
"target": "claude-code"
}
]
}Skills install into .agents/skills/. Hook and agent items can set target to
choose their .agents/hooks/<target>/ or .agents/agents/<target>/ directory.
The current bundled hooks and agents come from claude-toolkit and default to
claude-code.
When a recipe installs a skill, Calavera also creates or updates
.coderabbit.yaml so CodeRabbit excludes .claude/skills/**,
.agents/skills/**, and pnpm-lock.yaml. This avoids spending downstream
review tokens on vendored skill documentation whose findings belong upstream.
Existing CodeRabbit settings and path filters are preserved. The file remains
project-owned rather than Calavera-managed, so clean does not remove these
review preferences.
Set an agent item's target to codex when you want Calavera to generate a
Codex custom-agent TOML file under .codex/agents/ instead of preserving the
source Markdown under .agents/agents/<target>/.
Calavera owns the managed AI files it writes, including canonical .agents/
artifacts and Codex-adapted .codex/agents/ files. Other vendor tools may need
their own settings, symlinks, or import step before they consume those files. See
docs/ai-adapter-guidance.md for Claude Code,
Codex, and other agent-tool guidance.
Calavera's bundled skills are grouped for discovery on
skills.sh. Use
the directory page, badge, or skills CLI listing flow to inspect available
skills before choosing what belongs in a project.
For Calavera-managed projects, prefer selecting bundled skills through
calavera.config.json, the interactive AI artifact prompt, or scripted
--ai-artifact flags. That keeps installed skills tracked in
.calavera/state.json, covered by dry runs, and protected by Calavera's
overwrite checks.
Direct installs with npx skills add schalkneethling/create-project-calavera
can be useful for one-off discovery or non-Calavera workflows, but those files
are managed by the skills CLI rather than Calavera. Do not mix direct installs
and Calavera-managed installs for the same destination unless you intentionally
want Calavera to treat the existing files as local, unmanaged content.
The skills of the Claude Code plugins below are not listed there, because they work only inside their plugin.
This repository is also a Claude Code plugin marketplace named calavera. The
plugins are in plugins/. Add the marketplace once, then install a
plugin from it:
claude plugin marketplace add schalkneethling/create-project-calavera
claude plugin install dependency-review@calavera| Plugin | What it does |
|---|---|
dependency-review |
Reviews Dependabot updates for what matters to the current project, with a dependency usage map and a WORKAROUND marker convention for workarounds. |
Calavera does not version the plugins. Claude Code uses the latest commit of
this repository as the version of every plugin, so any commit to the repository
counts as an update, even one that does not change the plugin. Claude Code turns
auto-update off by default for this marketplace. To take an update, run
claude plugin marketplace update calavera, then
claude plugin update <plugin>@calavera, and restart Claude Code. You can also
turn on auto-update for the calavera marketplace under /plugin,
Marketplaces.
Adding the marketplace clones this whole repository into Claude Code's plugin
folder.
Calavera writes nothing into your project for plugins. calavera apply does not
install or enable them.
The recipe composer runs as a small Vite app:
The hosted Composer reads the version currently published under the npm
latest tag and only offers integrations supported by that CLI release. New
integrations can therefore land and deploy without producing recipes that the
published CLI cannot apply. If the npm registry is unavailable, the Composer
falls back to the last known-safe v2.2 integration catalog.
npm run web:devNote: You can also access the UI via https://calavera.schalkneethling.com
Open the printed local URL, choose your packs, then either:
- save
calavera.config.jsondirectly with the browser file picker, or - download
calavera.config.json.
Both options are shown by default so users can choose the flow they are most
comfortable with. After saving the file, run the displayed next commands from
the project folder that contains calavera.config.json. The optional bootstrap
command prepares agent guidance; the dry-run command previews local changes; the
apply command writes approved changes.
When the browser exposes WebMCP, the composer registers a browser parity surface for the MCP recipe composition workflow:
list_profileslist_integrationsdescribe_integrationlist_ai_artifactslist_baseline_targetsdescribe_baseline_targetsearch_baseline_featuresrecommend_baseline_targetcompose_recipevalidate_recipeexplain_recipedownload_recipe
WebMCP uses the same shared recipe composition model as the standard MCP server,
but it cannot inspect, dry-run, or apply files in a local project workspace from
the browser. Use download_recipe to save calavera.config.json, then apply it
with the CLI or standard MCP server from the project root.
Build the composer with:
npm run web:buildThe independently deployable Baseline Target Explorer explains Widely, Newly, and fixed-year targets, shows the matching Chrome, Edge, Firefox, and Safari versions, and recommends the earliest fixed target for selected CSS features.
Recipes keep integrations as string IDs and carry optional integration-specific settings separately:
{
"integrations": ["stylelint-baseline"],
"integrationOptions": {
"stylelint-baseline": {
"available": 2025,
"severity": "warning"
}
}
}available accepts "widely", "newly", or a supported fixed year. severity accepts "warning" or "error". Options are rejected unless their integration is selected, and existing recipes without integrationOptions retain their previous Stylelint behavior.
Build the Explorer independently with:
pnpm --filter @calavera/baseline-explorer buildNew recipes select package-backed skills, hooks, and agents by stable ID:
{
"ai": [
{ "id": "skill-project-goal" },
{ "id": "agent-technical-devils-advocate", "target": "codex" }
]
}Legacy { "type", "src", "target" } entries remain readable during the compatibility window. Migrate and manage exact versions with:
create-project-calavera artifacts migrate
create-project-calavera artifacts install
create-project-calavera artifacts status
create-project-calavera artifacts status --check-updates
create-project-calavera artifacts doctor
create-project-calavera artifacts update skill-project-goal
create-project-calavera artifacts update --all --tag nextInstallation resolves npm packages into .calavera/packages and a verified npm cache without changing consumer package.json or node_modules. The independently versioned artifact packages are not runtime dependencies of the CLI or artifact core, so they do not enter a consumer dependency graph or lockfile through Calavera itself. .calavera/artifacts.lock.json records exact versions, integrity, destinations, and payload hashes; apply and apply_recipe reuse those exact locked versions. When the recipe selects an artifact that has no lock entry, apply installs it first, as artifacts install would: apply --dry-run and dry_run_apply report each artifact they would resolve and lock, with its version, and change nothing; apply and apply_recipe lock and install only those artifacts, then apply the rest of the recipe. Before that install commits, apply checks every selected artifact against the project. If an artifact output would overwrite a local edit or a file Calavera does not manage, or the install fails for any other reason, apply stops with an error that names artifacts install. When the install stops before its transaction commits, or a partly committed transaction rolls back, the artifact lock, artifact outputs, and Calavera state stay as they were. If the rollback itself fails, the error reports both failures, the project may be partly changed, and the next apply, apply_recipe, or artifacts command retries the rollback; a dry run refuses to run until it has. Registry cache entries can remain in an existing .calavera/cache/npm. Only artifacts update advances a version. Status is offline unless --check-updates is explicit. Run artifacts doctor to verify installed outputs, managed state, and local edits without checking the registry. The existing managed-state hashes continue to block overwriting local edits.
The optional Calavera menu-bar app monitors only project directories that you explicitly register. It reads recipes, artifact locks, and state without changing them; checks npm and GitHub on launch, every six hours, or when you select Check now; and deduplicates notifications by component and target version.
For project updates, the app always copies the exact command and never executes it. Opening a terminal is opt-in: save your preferred terminal application's macOS name in the app to open it at the registered directory, or leave the preference blank for copy-only behavior. App updates open a stable GitHub release, and self-updating is intentionally outside v1.
Local development requires Node.js, pnpm, Rust through rustup, and Xcode:
pnpm --filter @calavera/menu-bar devTags matching menu-bar-v* run the independent macOS release workflow, which builds a universal signed, notarized, and stapled DMG through the protected publish environment.
Calavera publishes to npm from GitHub releases with npm trusted publishing. The
repository workflow is .github/workflows/publish.yml, and npm should be
configured with that workflow as a trusted publisher for
create-project-calavera and each public workspace package, including
@schalkneethling/calavera-baseline-core.
The complete independent-package, static-app, artifact-channel, recovery, and macOS rehearsal is documented in docs/release-and-update-journey.md. For the concrete, step-by-step commands to run once a Changesets version PR is open and ready to release, see docs/release-runbook.md.
Before the first trusted publish:
- enable 2FA on npm and GitHub;
- remove any
NPM_TOKENrepository secret; - create a GitHub environment named
publishand restrict it tomain; - configure npm trusted publishing for this repository, workflow, and environment.
To validate the package locally, first install
uv. It provisions
the locked Python environment used by SkillSpector and the workflow audit.
pnpm workflow:check runs uvx zizmor@1.25.2 --offline, so prime that exact
version in uv's cache once while online before using the offline check. The
pnpm check quality gate includes the repository's own Knip analysis.
uv sync --frozen
uvx zizmor@1.25.2 --version
pnpm browsers:install
pnpm check
pnpm web:build
pnpm publish:check
pnpm pack --dry-run
pnpm workflow:checkFor the 2.0.0 release, create tag v2.0.0 from main, draft a GitHub release
for that tag, and use CHANGELOG.md as the starting release
notes. Publishing the GitHub release triggers the trusted-publishing workflow.
The publish workflow checks the project, builds the web composer, packs the package, audits the workflow with zizmor, then publishes the packed tarball with npm provenance.