Test changes to your agent instructions before you trust them.
Behavior Diff shows whether a change to CLAUDE.md, AGENTS.md, or a skill
changes what an agent does. It runs the same task with and without your change,
then gives you a before-and-after report.
A rule can sound clear and still change nothing. It can also fix one case but cause a new problem somewhere else. Behavior Diff lets you review evidence before you commit the rule.
Agent instruction files shape decisions, tool use, and final answers. Text review can show whether a rule sounds clear. It cannot show what the agent will do.
Behavior Diff runs the change as a controlled experiment. You see whether the rule changes the process or result before you share it.
- Whether the agent reached the situation that the rule targets.
- Where the before and after runs took different paths.
- Which commands, tools, and evidence each run used.
- Whether the final answers changed.
- Whether the change was consistent across repeated runs.
Behavior Diff does not label a rule as good or bad. You compare the evidence with the behavior that you want.
Use Behavior Diff when you:
- Add a rule after an agent made the wrong choice.
- Change a shared
CLAUDE.mdorAGENTS.mdfile. - Edit a skill trigger or workflow instruction.
- Remove or simplify a rule and want to find regressions.
- Want evidence before your team adopts an instruction change.
Behavior Diff installs as a plugin on Claude Code and Codex. The commands below install the public marketplace release.
Pi and OMP are trial stacks, not plugin hosts in this change. Run their headless trials from a Behavior Diff source checkout and pass an exact model.
| Surface | Claude Code | Codex | Pi | OMP |
|---|---|---|---|---|
| Marketplace plugin install | Yes | Yes | No | No |
| Headless trial stack | Yes | Yes | Yes, with --model |
Yes, with --model |
| Live trial dispatch | Parallel subagents | Fresh sequential contexts or headless | No built-in dispatch. Use headless. | One parallel task batch |
claude plugin marketplace add spacedock-dev/marketplace
claude plugin install behavior-diff@spacedockRestart Claude Code after installation.
codex plugin marketplace add spacedock-dev/marketplace
codex plugin add behavior-diff@spacedockEnable hooks in ~/.codex/config.toml:
[features]
hooks = trueStart one interactive Codex session after installation. Approve each Behavior
Diff hook when Codex asks. Codex does not ask for hook approval during
codex exec.
Codex uses a cached copy of each plugin. Run the install command again after a Behavior Diff update:
codex plugin add behavior-diff@spacedockUse the shipped behavior-rehearse skill
for a guided review of an instruction change or PR through a practical adoption
recommendation. It owns the journey; the underlying behavior-diff skill owns
comparison preparation and assessment, and the existing runner executes trials.
In Claude Code:
/behavior-diff:behavior-rehearse Review my AGENTS.md change and recommend whether to adopt it.
In Codex:
$behavior-rehearse Review my AGENTS.md change and recommend whether to adopt it.
Supply the change or PR and any context you permit the agent to inspect. The agent reviews the change, follows the comparison through completion, and leads its first final answer with what to do and why. Decision-changing risks stay visible; detailed evidence and methodology stay in linked evidence. It reuses existing authority and asks once for missing bounded run approval. Paid model calls and external effects still require their own applicable authority; a recommendation never authorizes commit, push, merge, release, or publication.
For a comparison without the guided review journey, keep an instruction edit uncommitted and ask:
Run behavior diff on my AGENTS.md change.
Or invoke /behavior-diff:behavior-diff in Claude Code or $behavior-diff in
Codex. Explicit PR or historical Git inputs are also supported; they do not
require an uncommitted edit.
Behavior Diff finds the changed instruction file and works out what the change is meant to do and what it must preserve. From that intent, the agent designs a neutral task and, when needed, coherent ordinary and edge-case test data, plus private criteria for each case. It reuses suitable project data when it can and asks you only when a needed requirement cannot be found another way. It checks the environment, freezes the task and data, runs the comparison, and opens the report. It then explains, separately from the automatic report, which cases were reached and whether the evidence supports the intent.
This coverage is bounded to the designed cases. It is not an exhaustive test, and it does not promise to find unknown side effects.
Some tasks need files that your project does not contain, such as sample inputs. Git-based trials start from your last commit, so untracked or uncommitted files in your checkout never reach them. The skill designs or selects these files; a helper only delivers them to every trial:
- A private helper,
prepare_shared.py, copies your project base, the reviewed data directory, and the selected Before and After instructions into a new private stage outside your project. Your checkout is not changed. - The helper records a freeze of the stage. It checks the freeze again immediately before launch, and it stops when a file changed.
- The skill runs the normal runner from the stage. Both sides receive the same data, and only the selected instruction differs.
The helper accepts one instruction file and plain files only. It rejects
symbolic links, special files, submodules, unsafe paths, inputs over
BEHAVIOR_DIFF_COPY_CAP_KB (default 200 MiB), and Git attributes that change
archived files. Purpose files, source metadata, and evaluator notes stay out of
the stage. The helper does not scan data for secrets, so review every shared
file first. The freeze detects changes, but it is not a sandbox. Reports for a
staged run stay in the stage under home/runs/; keep the stage after the run.
The skill reference
contains the complete commands and limits.
Scenario execution and decision extraction use separate model defaults:
| Host | Scenario trials | Decision extraction |
|---|---|---|
| Claude Code | opus |
sonnet |
| Codex | sol |
luna |
sol and luna are Behavior Diff selectors, not native Codex aliases.
The runner reads codex debug models and selects the newest visible stable
gpt-<version>-sol or gpt-<version>-luna by numeric version. It resolves the
trial selector once before launching trials. All Before and After trials use
that exact ID, and the report displays it. Extraction resolves its own selector
and records that model separately.
Use --model <exact-id> to pin a trial version without catalog discovery.
--extract-agent and --extract-model override extraction. An explicit
extraction host wins; otherwise a sol or luna extraction selector selects
Codex. With no overrides, Claude and Codex extraction stay on the trial host.
They do not silently switch hosts when extraction fails.
A missing, malformed, or empty family catalog stops trial selection before
any trials start. An extraction discovery failure leaves the trial evidence
available without a decision diff. Use a Codex CLI that supports
codex debug models, or provide an explicit model ID.
Standalone decisions.py, without a selected host, tries Codex/Luna and can
fall back to Claude/Sonnet if Codex is absent or its model call fails.
Discovery errors stop extraction; explicitly selected hosts never switch.
Live Claude and Codex trials use the same model roles. If the host cannot select the trial model, the skill uses the headless runner instead. Live extraction stays in-session and is skipped if its model cannot be selected. Pi and OMP headless trials still require exact model IDs; OMP live trials retain the parent session's model.
Family selectors can resolve to newer versions on later runs. Use explicit IDs when comparisons across runs must retain the same model version.
The runner prints a unique run directory and ready-to-copy status commands at startup. Keep that directory to check the same comparison from another terminal or agent session. Multiple comparisons can run at once without sharing status.
Using the scripts bundled with the installed skill:
python3 /path/to/behavior-diff/scripts/status.py /path/to/run
python3 /path/to/behavior-diff/scripts/status.py /path/to/run --json
python3 /path/to/behavior-diff/scripts/status.py /path/to/run --watch
python3 /path/to/behavior-diff/scripts/status.py --list --activeListing uses ${BEHAVIOR_DIFF_HOME:-~/.behavior-diff}. It identifies each run
rather than choosing the latest one. Active listing also retains surviving or
uncertain trial and assessment processes after their controller stops. Watch shows
lifecycle changes; closing it leaves the run running. The agent can continue other
work and check status when needed instead of repeatedly polling.
Progress separates finished trials, assessment availability, and report availability. “Finished” does not mean “passed,” and a report may be available without an assessment. No output does not mean stuck. When local process identity cannot be checked, status stays explicitly uncertain. Older runs without progress metadata still have their reports.
The skill prepares a reviewed scenario record alongside purpose before launching trials. It describes the task, why the selected data tests the change assumption, the necessary conditions, the limits, and separate observable checks for each goal.
behavior-diff.sh --agent claude --file SKILL.md --task "<task>" \
--purpose-file <private-purpose.json> --scenario-file <private-scenario.json>--scenario-file requires purpose. The runner validates both before any model call
and excludes them from both trial copies. Only the sanitized scenario record goes
to assessment and the report; the private preparation notes do not. See the
record contract
for its fields and privacy boundary.
The assessor must evaluate every frozen check without changing its definition. Reading a PR description and checking the implementation are separate checks; one cannot stand in for the other. Each source-consistency check also names its required recorded sources. These sources get priority within the existing evidence budget; an unrelated readable file cannot substitute for them.
Invalid evidence rejects only the affected check, which stays Not assessed with its reason. Other validated findings remain visible. Missing, duplicate or rewritten check definitions still reject the whole assessment. Partial coverage never becomes an all-pass result. Runs without a scenario record show missing setup information explicitly and identify any criteria written by the assessor after the trials.
Behavior Diff applies installed Humanizer prose guidance while generating report narrative in the existing decision-extraction call. If Humanizer is unavailable, it uses concise, natural technical prose without installing or downloading a skill. This adds no model call and does not change trial execution. Report assembly and rendering stay deterministic.
Humanizer edits prose only. Counts, trial memberships, evidence qualifiers, citations and links, exact quotes, code, and source excerpts stay intact. The host skill also invokes Humanizer when available for its own result summary, with the same plain-language fallback. It does not post-edit the HTML or other saved report artifacts.
On Claude Code and Codex, the headless and live skills can use TypeSafe's Jev
for evidence ranking, finding classification, criterion support, or hypothesis
evaluation. Set TYPESAFE_API_KEY in the host process environment, never in
task text or a committed file. TYPESAFE_DEFAULT_MODEL defaults to jev-latest.
Only the official https://api.typesafe.ai endpoint is supported; a different
TYPESAFE_BASE_URL safely skips assistance.
Configuration is not consent. Before a new use scope, the skill asks approval for TypeSafe, the payload category, purpose, request/state count, and cost ceiling. Missing configuration, denied approval, or provider failure leaves the existing assessment available. No useful semantic opportunity means no call.
Jev supplies advice, not proof, a verdict, or permission. The skill checks important conclusions against primary evidence and briefly names Jev's actual contribution or skip reason in conversation. Extraction and saved reports do not change. See the shared contract and approval-bound manual verification.
When the skill replays a past change in an isolated fixture, the Before and
After files come from two commits of an original repository. The skill can then
pass caller-verified provenance to the runner with --source-file:
behavior-diff.sh --agent claude --file SKILL.md --task "<task>" \
--purpose-file <private-purpose.json> --source-file <private-source.json>{
"repository_url": "https://github.com/owner/repo",
"before_commit": "<full 40- or 64-hex commit>",
"after_commit": "<full 40- or 64-hex commit>",
"pull_requests": [
{
"number": 123,
"title": "Title",
"url": "https://github.com/owner/repo/pull/123",
"applies_to": "after"
}
]
}The report header then shows the repository, related PR or MR, and linked short
Before/After hashes. repository_url is the HTTPS web URL of a GitHub or
GitLab repository, including nested GitLab groups, with no credentials, port,
query, or fragment. forge (github or gitlab) is optional for github.com
and gitlab.com and required for a self-hosted host. pull_requests is
optional; each applies_to is before, after, or both, and each URL must
be the repository's /pull/<number> or /-/merge_requests/<number> page.
Unknown fields are rejected.
The caller is responsible for this provenance. The runner validates its shape
and URLs before any trial starts, then freezes the normalized value in the run's
config.json. It does not infer a repository from the sandbox remote, look up
commits or PRs, or accept abbreviated commits. The skill includes a PR or MR only
when host tooling such as gh or glab associates it with an exact commit, and
omits the whole file for an uncommitted local edit. The source file never enters
trial copies, the task, or the extraction prompt. Outside CI, runs without
--source-file keep the local-edit report header.
In GitHub Actions and GitLab CI, the runner automatically adds repository and workflow PR/MR links to the header. No source file or API call is needed:
- GitHub:
GITHUB_ACTIONS=true,GITHUB_SERVER_URL, andGITHUB_REPOSITORYidentify the repository. For PR events and PR issue comments, the runner reads the matching request fromGITHUB_EVENT_PATH. - GitLab:
GITLAB_CI=true,CI_PROJECT_URL, andCI_PROJECT_PATHidentify the project. MR variables supply the IID, title, and owning project URL/path; fork MRs link to their owning project rather than the fork.
These links describe the workflow context, not verified historical source
revisions. Before/After labels still describe the actual comparison inputs;
CI SHA variables never replace them. Explicit --source-file wins entirely,
including when it points to a different repository.
The runner freezes only validated link metadata in config.json; offline
regeneration retains it without reading the current environment. Missing or
invalid request data produces a repository-only header. Invalid repository
data or conflicting CI providers produce no CI context. The runner does not
save the complete environment, event payload, or credential-bearing clone URL.
A run compares the instruction versions. A trial is one agent execution on one side. Each run creates a local HTML report with six tabs:
-
Summary follows one five-step reading sequence: what we found; expected versus observed behavior; how we tested it; supporting evidence; and next action. Validated checks distinguish unmet After requirements, an already-correct baseline, preservation, improvement in these trials, and inconclusive evidence. The same mistake on both sides can still leave an After requirement unmet. Missing or rejected assessments never become a no-gap result. Recorded task, model, trial counts and evidence limits explain the test; private preparation rationale is not invented when it was not saved in report inputs. Repository/PR links, compared revisions and model remain visible in a compact header. Full task, reading help and detailed limits are expandable.
-
Understand the change explains the same assessment conclusion. Original model interpretation is labeled separately, not promoted to a competing verdict. Detailed checks link their recorded sources, output excerpts and trial outcomes. Attention findings retain consequences, applicability and uncertainty; Not relevant here hides a finding's body for this report session only.
-
Instruction changes shows the saved aim, filename, line counts, and complete instruction diff. Likely aim marks an inferred interpretation; Supplied expectation marks an explicit expectation. Missing explanations stay unavailable. Section or line-range links select a diff block, highlight its changed lines, and scroll to it without hiding the rest of the diff. Related edits are interpretations, not causal proof.
-
Behavior diff shows an ordered, two-lane comparison. Before and After behaviors align at each comparison in the model-extracted order, with all trial counts visible. Mixed behaviors stay within each comparison, not in connected branches.
Amber marks changed comparisons, teal marks unchanged or matching proportions, and gray marks unavailable comparisons. The info popup beside the heading separates comparison status, decision role, and evidence source. Blue identifies actions, violet the primary result, and indigo answer details; teal identifies recorded-command sources and amber final-answer sources. Labels and colors do not mean success or failure.
Open a comparison to inspect its question, source, notes, related edits, and supporting Trial 1 / Trial 2 / Trial 3 links. Each is a separately spaced link to a complete Before/After trial group; links wrap on narrow screens. The report states when individual-trial attribution is unavailable. Expand all and Collapse all control comparison disclosures. The comparison order is not an execution path.
-
Flow diff groups only identical complete recorded command sequences, retaining counts and links to every contributing trial. Different paths remain separate. A table also compares command-category combinations. Without captured command evidence, the tab explains why flow is unavailable; it does not infer commands from answers or self-reported actions.
-
Trial evidence aligns Before on the left and After on the right within each numbered group, including on mobile. What changed gives a short takeaway, one sentence per side, and a caveat only when needed. These model-written summaries describe that group's records, not aggregate counts. Full final answers remain visible below. Shared supporting-detail and command disclosures open both sides together; Show both and Hide both control a whole group. Missing records remain explicit. Trial numbers align records for reading, not paired execution: Before and After trials are independent.
Printing includes all tabs and disclosure content, with legends below their headings. The screen's disclosure states are restored afterward.
Start with the instruction edit and the prominent comparisons. Final result still means the primary result identified by the model, not the highest-ranked comparison. Final answer is the recorded answer text. Action comparisons come from recorded commands or self-reported actions; Answer detail comparisons come from the final answer. Wording differences alone do not establish an action change.
In Summary and Behavior diff, counts such as 3 of 3 trials refer to trials,
not repeated actions within one trial. For new extractions, the model assigns
named trials to behaviors; code derives counts from complete, unique membership
on each side. Those assignments remain in decisions.json for auditing.
This validates bookkeeping, not whether a trial was classified correctly.
Separate row counts do not show a complete sequence within one trial.
Changed compares extracted behavior proportions. Unchanged is shown for
complete, unanimous same-behavior evidence; matching proportions without that
evidence are labeled Same proportions. Unavailable means extracted
states cannot support a comparison. A consistent change requires a different
unanimous behavior on each side, at least two trials per side, and complete trial
evidence. This is an observed
pattern, not statistical significance. Single-trial, blocked, missing, and mixed
evidence is not promoted as a consistent change.
In Flow diff, progression preserves command order and repeated commands. Before and After trials are independent. Empty records and blocked trials remain visible. Recorded commands do not prove successful execution.
The command-category table groups each trial into one category combination. Category order is not execution order. Matching categories can contain different commands or files, so matching patterns do not establish unchanged behavior.
Follow View behavior comparisons to Behavior diff, or inspect the trial records for original commands and answers. Markdown retains the five sections, story, counts, complete instruction diff, and grouped trial evidence without illustrations.
The existing extraction call identifies the primary result, possible explanations, and related instruction-diff hunks. It first recovers observed choices, then interprets their relationship to the supplied edit. Related edit links are labeled as model interpretation, not causal proof or knowledge of author intent. The same call supplies optional plain-language Summary text: a takeaway, short scenario, Before/After descriptions, and supported implications or cautions. The writing instructions require concrete actor/action/object contrasts, parallel Before/After descriptions, and a clear distinction between changed decisions or actions and changed explanations, citations, or presentation. The decisive contrast belongs in the headline and cards, not only in an additional finding. It also interprets the edit's likely aim, citing instruction-diff hunks rather than inferring intent from trial outcomes. Edit goal shows one sentence with an Inferred badge and an edit link; the info popup explains the source and its limits. Supplied expected behavior takes precedence and is labeled Supplied expectation, not attributed to the author. Without either source, the aim is marked unavailable; the instruction diff remains accessible. These observations do not establish that a goal was met. Equivalent meanings should use identical choice labels. Summary counts come from the decision rows, not a second estimate. Code validates references and choice coverage; it cannot prove that model-written explanations are true. With complete evidence, a validated narrative can lead with any row whose choice proportions change, even if it is mixed or is not the primary result. Selecting that row does not change the primary-result identity. Evidence ranking is the fallback when narrative is missing or unsupported; unchanged or matching-proportion rows must still qualify under that ranking. Mixed results keep their full counts and cautions. Structural validation does not prove a narrative's interpretation. The renderer owns HTML, colors, and a fixed set of SVG illustrations. A named unchanged targeted behavior applies only to the observed scenario. Missing links do not mean the edit had no effect. A changed result is not an automatic success or failure. Before and After use neutral borders. PASS and FAIL colors indicate grades against the supplied expectation, not a judgment that After is better. Instruction diff colors still mark added and removed lines.
Mixed results show the choices and their trial counts. Missing, blocked, or incomplete evidence produces an insufficient-evidence result. Without an identified primary result, the report labels its comparisons as reported answers. It does not guess the final result.
Expected behavior is labeled as supplied, or explicitly unavailable. The evidence limits state trial counts, provenance, and grading limits. Self-reported actions remain distinct from captured tool calls.
The structured report-data.json uses schema version 19, including per-group
decisions.trial_summaries, assessment-derived summary.state, summary.meaning,
summary.checks and summary.next_action, sourced instruction intent,
saved content.task, optional narrative, nullable metadata.source and
metadata.ci_context, and edit_hunks. decisions.target_rejection explains
a rejected whole assessment without dropping underlying evidence. Individual
target_assessment.criteria[].rejection values retain check-local diagnostics,
with empty outcome arrays rather than invented uncertain results. The optional
decisions.purpose_summary gives the Summary a short, labeled paraphrase of
the frozen goals; Instruction changes retains their complete text and provenance.
decisions.scenario_record carries the validated setup, frozen checks and required
source groups from run configuration. The Summary explains the test rationale and
conditions even when the automatic assessment is unavailable. These expectations
are not trial evidence.
The task comes from the run's task.md, or the capsule's copy
when absent from the run. A scenario description never replaces missing task text.
Regenerate reports from their original run artifacts;
older report-data files are not accepted. render.py needs the run directory,
capsule directory, recorded model label, and original configuration. Rendering
does not run trials or call a model.
Old decisions.json observations can be re-rendered with the new layout.
Without validated target checks, the Summary states that assessment is unavailable;
observed comparisons remain accessible. Missing narrative, trial summaries, aim
interpretations, and edit mappings remain unavailable. Trial summaries are produced
in the existing extraction call; rendering never invents a trial's summary.
To obtain them, explicitly rerun extraction on saved evidence after approving
its model cost; no new trials are needed. Rendering never triggers extraction.
Without a valid purpose summary, a single short recorded goal can appear verbatim.
Long or multiple goals get a brief pointer to Instruction changes instead;
rendering does not truncate or invent a summary.
The extractor stores the exact instruction_diff with its mappings. External
--emit-prompt also saves decisions.prompt.json so --ingest retains the emitted
diff's provenance. Invalid or stale mappings and inferred aims are omitted
without discarding observed choices. Rendering never invents replacements.
If both sides follow the same path, the task can miss the situation that the rule targets. Use a task that starts closer to the decision that you want to change.
Behavior Diff runs each side in a separate copy of the project. The after side contains only the instruction change that you selected. Other uncommitted files do not enter the experiment. Reviewed shared trial data, when used, enters both sides identically.
Reports stay on your machine under:
${BEHAVIOR_DIFF_HOME:-~/.behavior-diff}/runs/
A run with shared trial data keeps its reports in its
private stage under home/runs/.
A report can quote code and agent output from your project. Review the report before you share it.
Behavior Diff creates two copies of the same project state:
- The before copy uses the committed instruction file.
- The after copy adds only your uncommitted instruction change.
It gives both copies the same task and starts fresh agent sessions.
The runner records tool calls, commands, evidence, decisions, and final answers. It converts those traces into a common flow format, compares the two sides, and builds the HTML report. It does not use a model to declare a winner.
The plugin also watches edits to CLAUDE.md, AGENTS.md, and SKILL.md.
After you finish the current task, the agent can use that task to run Behavior
Diff on the instruction change.
See Technical architecture for the execution flow, component boundaries, and report-generation pipeline.
From a repository checkout, use Python 3.10 or newer to build a local gallery:
python3 tests/report-demo.py --serve --port 8767Open the printed URL. The server listens only on 127.0.0.1. Press Ctrl+C
to stop it and remove its temporary files. If the port is busy, use --port 0
to select an available port.
To build reports without a server:
python3 tests/report-demo.pyThis command prints a local file URL and keeps the temporary directory. Remove that directory when you no longer need the reports.
The examples cover changed and unchanged results, action changes, answer details, mixed results, blocked trials, missing comparisons, and self-reported evidence. They include a mixed primary-result headline competing with a unanimous secondary action, a non-primary headline competing with a changed outcome, added command categories, and mixed command patterns. Each example links to HTML and Markdown reports.
The gallery and deterministic report checks share tests/report_fixtures.py.
They use the real decision-ingest and report-render commands with authored
synthetic inputs. No plugin installation, credentials, or model calls are needed.
These examples verify reporting, not model behavior or instruction effectiveness.
For live agent journeys, see e2e/README.md.
Each command builds fresh reports outside the repository. After changing the report code or fixtures, run the command again to see the change.
From this checkout, ask your coding agent:
Run a Behavior Diff human evaluation.
The local
run-behavior-diff-human-evaluation
skill prepares five blind, four-option questions using randomly sampled skill
changes from DataRecce/recce-team. Every new evaluation pins the current
upstream main and records a fresh random seed. It uses this checkout's current
Behavior Diff code, including uncommitted changes—not the installed plugin.
The skill requires private-repository access through authenticated gh and fresh
approval for 30 Claude Code trials plus extraction. Trial execution is a
read-only local replay; it does not post to GitHub or change Linear issues.
Both Claude Code and Codex maintainer sessions can invoke the workflow; its
trial stack is explicitly Claude Code.
The localhost quiz hides instruction diffs, stated intent, and commit metadata until submission. It preserves generated summary wording, collects confidence and insufficient-evidence feedback, saves the first complete submission, then reveals the correct answers and full reports. To analyze a completed session, ask the agent to analyze the human evaluation results.
All private artifacts remain under ~/.behavior-diff/human-evaluations/, outside
the checkout. The workflow is manual only; CI runs synthetic helper tests, never
live evaluations. Five cases are diagnostic evidence, not an overall accuracy
estimate. See the skill's protocol
for sampling eligibility, preparation, consent, and scoring.
Use the repo-local
elwp — Explain with pictures skill
to turn a plan, architecture, or user journey into a plain-language HTML page.
It follows the illustrated handoff page:
physical analogies, responsibility cards, an interactive journey, tradeoffs,
and explicit evidence limits. It uses anatomy guidance when available and
verifies the actual page in a browser.
Example: “Use elwp to explain this plan with pictures and a clickable user journey.” This is a local maintainer workflow, not plugin payload.
- Update both plugin manifests to the same
X.Y.Zversion. - Merge the version change to
mainand wait for CI. - Create a GitHub Release with tag
vX.Y.Z, targetingmain. - Publish it as a stable release, not a prerelease.
- Confirm the Release workflow pins the marketplace entry to
vX.Y.Z.
The release workflow rejects tags that do not match both plugin manifests or
do not point to a commit on main. Drafts and prereleases do not update the
stable marketplace.
plugin/contains the installable plugin, skills, hooks, and runner.e2e/contains synthetic scenarios for manual product checks.tests/contains deterministic checks and a synthetic report gallery.e2e/README.mdexplains the demo and live-check fixtures.AGENTS.mdandCODING_GUIDELINES.mdcontain contributor guidance.