- Craftsmanship
- DevEx
What changed in AI Craftsman Superpowers 4.13
Version 4.13.0 of the plugin, for Claude Code, Codex, Grok and Hermes: 19 recorded changes across 1 releases, taken from the CHANGELOG rather than rewritten.
Alexandre Mallet5 min read
Version 4.13.0 is out. It carries 19 recorded changes across 1 release, and the plugin now ships 22 skills, 12 agents and 7 packs.
Every entry below is copied from the CHANGELOG in the repository rather than rewritten for this page. A release note that says something the CHANGELOG does not is a release note nobody can check.
4.13.0 (2026-10-19)
JavaScript gets the craftsman rules (.js, .jsx, .mjs, .cjs, native JavaScript and jQuery included), SEC004 refuses unescaped values reaching an HTML sink in TypeScript and JavaScript, the instinct review pane ships as the craftsman-cockpit companion mod (ADR-0031), and the hooks follow Claude Code's recent changes: background test runs, the Task tools, a write gate that fails (CR-218 to CR-220, CR-226, CR-231).
Upgrading can refuse a JavaScript file that 4.12.3 wrote without a word. To phase the rules in on an existing codebase, set them to warn for a directory in its .craft-rules.yml.
Fixed
- A test suite run in the background never counted as verification
evidence: Claude Code 2.1.277 removed TaskOutput, the only event that carried its result. On 2.1.302 the run ends as a task notification and UserPromptSubmit fires on it, so post-bash-test-verify.sh now also listens there (async) and reads <task-id>, <status> and the exit code, tied to the Bash that started it by task id. Captured, not documented for shell tasks: see tests/fixtures/hosts/PROVENANCE.md (CR-218).
/craftsman:team,/craftsman:planand theteam-leadagent required
TaskCreate/TaskUpdate/TaskList, which Claude Code no longer offers on Opus 4.8, Sonnet 5, Fable 5 and newer without CLAUDE_CODE_ENABLE_TODO_TOOLS=1. Each now says what to do without the Task tools: coordinate through messages and keep the ledger in the reports, as the agent teams documentation prescribes (CR-219).
- A write gate that timed out, was killed or could not start let the write
through. pre-write-check.sh and config-protection.sh now declare onFailure: "block" (Claude Code 2.1.295); older builds ignore the key (run on 2.1.294). pre-push-verify.sh stays advisory (CR-220).
- The PHP001 auto-fix wrote a file PHP refuses to compile when code shared
the opening line: <?php echo 1; came back with declare(strict_types=1); below it ("strict_types declaration must be the very first statement"). The declare now goes right after the tag and that code moves below it; a first line that is not a real opening tag (<?phpx) is refused instead of rewritten. php -l judges the result (CR-226).
- On Grok,
instincts approverefused.grok/skills, the one directory Grok
reads skills from: instinct_skills.py kept its own list of host directories with Claude Code's and Codex's only. The destinations now come from hooks/host-capabilities.json, which declares user_skills_dir for Claude Code and Codex; global promotion on a host that declares none (Grok) is refused instead of guessed.
- The suite's shared assertions could give the wrong verdict on a long text:
echo "$text" | grep -q under pipefail reports the writer's SIGPIPE when grep stops at the first match, so assert_contains failed on a text that held the needle (macOS CI) and assert_not_contains passed on one that held the forbidden text. Measured on a 1 MB text: 100 wrong verdicts out of 100, none with a here-string, which they read now (tests/core/test-assert-helpers.sh).
Added
- JavaScript gets the craftsman rules:
.js,.jsx,.mjsand.cjs,
native JavaScript and jQuery included. A src/domain/order.js importing ../infrastructure/db was written with no rule at all while the same file as .ts was refused. The javascript language of the react pack now runs LAYER001, LAYER004, SEC002 and SEC003 through the same function bodies as TypeScript, so the two cannot disagree, plus ESLint at Level 2, the protected linter configs and the test runners (mocha added). The TypeScript-only rules (TS001 to TS003) and SEC001 (secrets, repository security rather than code quality) stay out of it (CR-231).
- SEC004, TypeScript and JavaScript: an HTML sink fed by a value the code did
not write as a literal (innerHTML, outerHTML, document.write, insertAdjacentHTML, jQuery .html(), dangerouslySetInnerHTML, and interpolated or concatenated markup passed to .append() and its siblings). DOMPurify.sanitize(...) is accepted. Unlike SEC001 to SEC003 it is ignorable with a stated craftsman-ignore: SEC004, because "a variable reaches a sink" is a heuristic.
- ADR-0031: function-hook mods are a companion surface for Claude Code, never
a gate. A mod lives in mods/<name>/ as its own plugin, reads and writes through bin/craftsman-helper only, and registers no tool that could reach a decision reserved for a person.
craftsman-cockpitmod:/instinctsopens a pane listing the project's
candidate instincts with their evidence, in Wilson-bound order, with Approve and Reject buttons wired to instincts approve|reject (#45). Install: /plugin install craftsman-cockpit@ai-craftsman-superpowers.
- The instinct pane explains each candidate: the rule's wording, pack and
default severity, the acceptance rate with refusals split between craftsman-ignore and config, the last fix date, what Approve and Reject do, and a preview of the exact skill Approve writes.
- A learned skill whose corrections recorded no context carries the rule's
own wording as its pattern instead of "see the rule definition".
craftsman-helper instincts review(hooks/lib/instincts_review.py):
the review queue as JSON (candidates with evidence, approved instincts), refreshed like candidates; repository text passes the same single-line filter a generated skill uses.
tests/mods/test-mods.sh: the ADR-0031 rules on every mod, each proved
able to fail on a fixture, plus claude plugin validate and claude plugin test when a claude binary is present.
Changed
- LAYER001 and LAYER004 also read
require(...)andimport(...), not only
ESM from. A TypeScript domain file that reached infrastructure through require was let through before and is now refused.
/craftsman:metricsstep 9 readsinstincts reviewand presents each
candidate from its fields (wording, severity, refusal split, last fix, evidence, the exact skill Approve writes), the same data as the cockpit pane, on every host. Repository text in the queue is quoted as data.
instincts approve,reviewandpromotetake the skills directory as
an optional argument: left out, it is the current host's, so the skill no longer spells a directory per host.
scripts/native-manifests.pykeeps only the root plugin in the Grok
catalogue: no other host loads a mod.
- A mod's version lives in its marketplace entry only, which
scripts/bump-version.sh already carries.
Upgrading
The same engine runs on every host; update it the way that host installs plugins:
# Claude Code
claude plugin update craftsman@ai-craftsman-superpowers
# Codex (then review the handlers in /hooks)
codex plugin marketplace upgrade
# Grok (re-exports the gate as well)
bash <your clone>/bin/craftsman-grok-install
# Hermes
git -C ~/.hermes/plugins/craftsman pullThe full history, including every patch summarised here, is in CHANGELOG.md.