All releases follow CalVer — YYYY.0M.MICRO. The marketplace and all plugins ship in lockstep: every release re-tags every plugin with the same version.
Maintenance release: retires the two multi-CLI wrapper plugins (code-review-external, premortem-multiple) that shelled out to external codex / opencode binaries. The single-perspective premortem plugin is unaffected and stays. This release also folds in django-run-site, added during the 2026.07.1 catalog bump that never shipped as a lockstep release.
code-review-externalplugin — removed in full: the wrapper skill pluscode-review-codex,code-review-opencode,code-review-claude, and the sharedstandard-review-prompt.md/target-detection.md/write-directive.md/tmux-runner.mdfiles. For GitHub PR review use the official/code-review:code-reviewskill; for a local diff,/code-review.premortem-multipleplugin — removed in full: the wrapper skill pluspremortem-codex,premortem-opencode,premortem-claude, and the sharedstandard-premortem-prompt.md/write-directive.md/tmux-runner.mdfiles.- Both entries dropped from
marketplace.json; all references removed fromREADME.md(plugin tables, the Decision-making and Code-review skill-graph diagrams, the/plugin installlines, the usage bullets, and thecode-review-external — argument formstable).
django-run-siteplugin — reference skill for a local Django dev stack managed byrun-site/django-dev-helpers: recognizing a run-site project, locating the.run-site-configsidecar and.dev_helpers_*dotfiles, reading web/Postgres/Redis/SQLite endpoints and ports, the autologin recipe, and therun-siteCLI surface. (Introduced in the 2026.07.1 catalog bump; ships in a lockstep release here for the first time.)
- Lockstep version bump: the marketplace and all 11 remaining plugins move to 2026.07.2.
New plugin release: long-file-splitter adds a repo-wide audit for source files that have grown past a configurable line threshold (default 600 LoC), with per-file split proposals that name concrete new modules, the symbols that move into each, and the strategy for preserving the public API. Proposal-first by design — the skill does not auto-refactor; an opt-in guided execution phase performs the moves one file at a time, one commit per logical extraction, with the test suite re-run between commits.
- Phase 1 — Scan. Default extensions cover
.py,.pyi,.js/.jsx/.mjs/.cjs,.ts/.tsx,.html/.htm,.vue,.svelte. Discovery usesrg --files+wc -l+awkagainst a long exclusion list (node_modules,.venv,venv,dist,build,.next,.tox,.pytest_cache,.mypy_cache,.ruff_cache,htmlcov,coverage,vendor,third_party,bower_components,*.min.*,*.bundle.js, lockfiles). Threshold is configurable per invocation. - Mega-constant detection (Python). An AST pass surfaces top-level assignments whose literal spans ≥100 lines — catching files that are under the LoC threshold but still problematic because one
dict/list/ multi-linestrdominates the file (e.g., a 400-line module that's 70% oneCHOICESdict). Each finding reports the symbol name, line range, span, and share of the file. - Generated-file detection. Reads the first ~30 lines of each candidate looking for
Generated by Django,DO NOT EDIT,Generated by the protocol buffer compiler,autogenerated by,@generated,AUTOGENERATED. Marks matchesSKIP — generated. Django migrations are a tagged subcase: technically generated, but the right move when too long is usuallysquashmigrations, not a manual split — flagged with that note rather than silently skipped. - Phase 2 — Classification into one of 6 categories. A grab-bag utility module (many small unrelated units), B god-class / god-component (one or a few large units), C mega-constant (one literal ≥40% of the file), D many-section HTML template, E mixed (two of the above at once), F SKIP — cohesive (long but justifiably so: tokenizer, state machine, snapshot fixture). The skip path is first-class — the skill is encouraged to refuse a split rather than fabricate one.
- Phase 3 — Cohesion analysis. Per-category heuristics for deciding what groups with what: name-prefix clusters (
parse_*,format_*,slugify_*), import affinity (which functions reach for which third-party libraries), data-type signatures, call-site clustering, lifecycle phases for god-classes (__init__/load_*/run/cleanup), repetition for HTML (<div class="card">appearing 14 times → a partial + loop), and an explicit rule that pure data (no callables, no imports, no f-strings) belongs in.json/.yaml/.toml, not Python. - Phase 4 — Proposal output. Writes a single markdown report to
/tmp/long-file-split-proposal-<ts>.mdwith a fixed template: punch list at the top, then per-file sections with structural summary, archaeology (why it grew), cohesion analysis, the actual split table (new file / symbols moved / approximate lines / one-sentence rationale), explicit public-API preservation strategy (re-export shim vs. updating call sites vs. both with a deprecation cycle), risks with mitigations, and a suggested commit sequence. Estimates use AST spans rather than guesses. - Phase 5 — Opt-in guided execution. Triggered only when the user explicitly asks to execute a specific file's split. Pre-flight gates: clean working tree (refuses if dirty), green test suite (refuses if red), branch creation. Per-row procedure: move symbols → run tests → commit with a focused message → next row. Tests-red anywhere in the sequence aborts and reports rather than attempting to repair in-flow. Final pass runs static checks (
ruff,mypy,tsc --noEmit,eslint) but fixes only warnings caused by the split itself. - Iron Laws. Proposal before action; no speculative refactors (the layout change must not be mixed with renames, signature changes, or bug fixes noticed in passing); preserve external API (every split picks an explicit strategy); one file per execution session; skip honestly when length is justified.
- Per-language quick reference. Python-specific guidance for Django
views.py/models.py/admin.py/serializers.pysplits (includingMeta.app_labelrequirement when models move into subpackages), JavaScript/TypeScript barrel files and component-folder layouts, hook extraction for React, and partial /{% include %}/ component patterns for Django / Jinja / React / Vue / Svelte HTML. Each section ends with a concrete "avoid" — e.g., don't multiply 1 file into 20 trivial files; the tooling overhead eats the win. - Common mistakes section. Splitting on length alone, premature multiplication, breaking API silently, mixing categories per commit, ignoring circular imports, refactoring "while you're there", skipping the test run between commits.
- New plugin entry in
marketplace.jsonand a new "Code quality & refactoring" section inREADME.md, plus install + usage entries for the new skill. - Lockstep version bump: every plugin and the marketplace move to 2026.05.8.
readme-guardian quality pass. Frontmatter description, badge handling, and the Django × Python matrix are all reworked to remove drift hazards and bring the skill closer in line with superpowers:writing-skills guidance.
- Description rewritten to triggering conditions only. Previous description summarized the workflow ("converts RST to Markdown, ensures proper badges..., short description, rationale, features list..."), which writing-skills warns becomes a shortcut Claude follows instead of reading the body. New description names only the situations that should trigger the skill (missing badges/install/version-support/rationale/features, RST README, post-
python-upgrade-package, pre-publish). - Django × Python matrix extracted to canonical reference file. New
django-python-matrix.mdsibling file is the single owner of (Django, Python) compatibility data — snapshot date, upstream URLs (Django FAQ + downloads page), the matrix itself, and a step-by-step regeneration procedure. SKILL.md no longer inlines the table; it points to the reference and enforces a 90-day freshness gate before emission. Other skills that referenced the inline matrix (e.g.,python-upgrade-packageStep 2b) now have a single file to point at instead of a section in SKILL.md. - Badge identifier derivation rules added (new Step 0f). Previously the target template carried literal
OWNER,REPO,WORKFLOW, andPACKAGEplaceholders with no instruction for how to resolve them. New section walks each one to its source (pyproject.toml[project].name,[project.urls].Repository/git remote,.github/workflows/test workflow filter), with fallbacks. Includes acurl https://pypi.org/pypi/${PACKAGE}/jsonpresence check that gates which badge set to emit. - Two badge variants for PyPI vs non-PyPI packages. Was previously a single set of shields routed through
img.shields.io/pypi/..., which renders as "invalid" badges for packages not published to PyPI. Variant A keeps the existing PyPI shields; Variant B swaps ingithub/license/OWNER/REPO, a static Python-versions badge, and dropspypi/ventirely. Agent picks based on the Step 0f presence check. - Django-mode skip note moved out of the README target's code fence. A blockquote ("Skip this subsection entirely for Django packages...") had been added inside the fenced
markdownblock that represents the emitted README — risk of it being copied into a user's output. Now an HTML comment outside the fence + comment-style<!-- only if … -->markers on the matrix headings, so the agent's instructions don't leak into rendered output. Also dropped the awkward empty-corner cell in the Python-only matrix table. - Step 5 commit is now opt-in. Title changed from "Apply and Commit" to "Apply (and commit only on request)". Explicit "do not commit on your own initiative" instruction, with the commit-message template kept but conditional on the user asking. RST cleanup also clarified:
git rmif tracked. - Version-support analysis row updated. Step 2 checklist now distinguishes Django-mode (Django × Python only) from non-Django (Python only) and adds a
DUPLICATEDstatus so the analysis flags READMEs that emit both tables. - Common Mistakes row added for the duplicate-matrix pitfall in Django projects, and a Content generation rule (#5) forbidding a standalone Python matrix when Django is detected.
The compatibility data lives in exactly one place (django-python-matrix.md); skills that emit a per-project matrix derive from that file, never inline a copy. Freshness check is mandatory before emission — a stale matrix in a user's README is a failure mode, not a minor inaccuracy.
New plugin release: django-extract-app adds a guided workflow for extracting a Django app embedded in a monolithic project into a standalone reusable package. Designed to chain into the existing readme-guardian + oss-github-publisher pipeline so the extracted package ships with the same level of polish as a greenfield OSS project.
-
django-extract-app— the main extraction skill. 10-step procedure, one commit per step in the new package's repo:- Reconnaissance — locates the app inside the monolith, confirms it's a real Django app (
apps.py/INSTALLED_APPSmembership / settings module detection), inventories source files (models / views / admin / signals / commands / templatetags / templates / static / migrations / existing tests). - Extractability audit — eight independent checks, each producing OK / WARN / BLOCK: cross-app FKs + dynamic
apps.get_modelrefs, cross-app imports,settings.Xusages (becomes the package's settings contract), migrationdependencies=[...]cross-app deps,reverse()+{% url %}cross-app coupling, template{% extends %}/{% include %}cross-app,@receiver(..., sender=other_app.X)signals,admin.site.registerof cross-app models. ≥1 BLOCK pauses and asks the user to abort or knowingly continue. - Decisions (via
AskUserQuestion, one at a time) — OSS vs internal package, PyPI distribution name (suggestsdjango-<foo>), importable name, target package path, git history strategy (cleaninitorgit filter-repo --subdirectory-filterwith preflight check), DB engine in tests (auto-detects Postgres-specific features likeArrayField,JSONFieldPG ops,django.contrib.postgres,pg_trgmand recommendspytest-testcontainers-django; defaults to SQLite otherwise), example/demo project (default Yes for apps with views/urls/admin/templates), license choice. - Repo bootstrap —
mkdir+git init(orgit filter-repoon a clone of the monolith), copies app source intosrc/<importable>/, first commit"Initial extraction from <monolith> @ <sha>". pyproject.toml+ uv — detects third-party imports vs stdlib/Django/same-package, generates a complete[project]block (Django × Python matrix fromreadme-guardian's canonical table — 5.2 LTS + 6.0 as of 2026-05-08),[tool.setuptools.packages.find]forsrc/layout,[tool.pytest.ini_options]withDJANGO_SETTINGS_MODULE = "tests.settings", runsuv sync --all-extras.- Test scaffolding with TDD stubs — generates
tests/settings.py(SQLite or Postgres-via-testcontainers fixture),conftest.py, optionaltests/urls.py, and per-construct test stubs (test_models.py,test_views.py,test_admin.py,test_signals.py,test_commands.py,test_templatetags.py,test_apps.py) — every stubpytest.skip("TODO: ...")so failure-to-fill-in is visible. Existing tests from the monolith are migrated with import paths rewritten (from <monolith>.<app>.X→from <importable>.X); cross-app imports get flagged as TODO comments rather than auto-resolved. - GitHub Actions —
.github/workflows/tests.ymlwithinclude:-style Django × Python matrix (5.2 LTS / 6.0 × Python 3.10–3.14, intersected withreadme-guardian's canonical compatibility table), separate lint job (ruff check + format, non-blocking), optionalexample-checkjob for the demo project (manage.py check+migrate --run-syncdb). Postgres mode adds adocker infosmoke step (testcontainers manages its own container). - Tooling —
.pre-commit-config.yaml(ruff lint E/F/W + ruff-format +pyupgrade --py310-plusderived fromrequires-python+django-upgrade --target-version 5.2derived from Django floor),LICENSE(MIT default),.gitignore(Python + Django + uv),README.mdstarter (install /INSTALLED_APPS/ URLs / requirements / settings contract / dev setup),CHANGELOG.mdin Keep-a-Changelog format. - Optional example/demo project —
example/withmanage.py+ minimalsettings.py(SQLite + admin) +urls.pywiring the package's URLs. Doubles as a CI smoke test for the package. - Local verification + chaining — runs
uv sync && uv run pytest && uv run pre-commit run --all-files && uv build && uv run --with twine twine check dist/*, surfaces any failure to the user (no silent auto-fix). Then asks (default Yes) whether to chain into/readme-guardian:readme-guardianand/oss-github-publisher:oss-github-publisher, both invoked via theSkilltool in the new package's directory. Final report enumerates commits, audit findings, verification results, and next-steps (push to GitHub, publish to PyPI, run the cleanup sub-skill).
- Reconnaissance — locates the app inside the monolith, confirms it's a real Django app (
-
django-extract-app-cleanup— phase-2 sub-skill, invoked separately after the package is published or installed editable. Wires the new package back into the monolith and removes the original app directory, in two commits with three verifications:- Wiring — adds the package as a dependency via one of four strategies (
AskUserQuestion): PyPI released (uv sync-immediately), PyPI placeholder (added with TODO, no install until publish), editable local install (uv add --editable <path>), or git URL with explicit@ref. Verifies the package imports andmanage.py checkpasses BEFORE removing the original app — so removal can't strand the monolith if wiring is broken. - Removal — before deletion, runs a migration safety check: compares the AppConfig label between monolith and installed package, and diffs the migration filename sets in
<monolith>/<app>/migrations/vs the installed package's<importable>/migrations/. If either mismatches, stops without deleting. Otherwisegit rm -r <app>/, then re-verifies all three:manage.py check,makemigrations --check --dry-run(the critical drift detector — if this finds anything, the source-of-truth has diverged and the user must resolve manually, not paper over with a fresh migration the package won't have), and the monolith's full test suite.
- Wiring — adds the package as a dependency via one of four strategies (
- New plugin entry in
marketplace.jsonandREADME.md(plugin table, Python project lifecycle skill graph with extraction sub-graph, install + usage sections, cross-references). - Cross-reference:
django-extract-appreads the canonical Django × Python compatibility matrix fromreadme-guardian's SKILL.md — same single source of truth aspython-upgrade-package, no duplicated copies of the table.
- Never modify the monolith in the main skill. Read-only access only. Wiring + removal happens in the separate cleanup sub-skill, with a clean working-tree precondition.
- One commit per step in the new repo. Every step is independently revertible.
- Every decision goes through
AskUserQuestion. No silent defaults for naming, location, history strategy, DB engine, license, or example project. - Audit BLOCKers stop the workflow. A blocking issue triggers an explicit abort/continue prompt — never silently shipping a known-broken package.
Security hardening release. Three iterative codex self-reviews of the repo surfaced 9 distinct sandbox/secret-handling issues in code-review-opencode (and adjacent skills). Every finding was reproduced empirically before fixing — git diff --no-index /etc/hosts /dev/null, git log --output=PATH, malicious-filename command injection via xargs -I {}, and nested-.env pathspec leakage all confirmed live. Round 3 returned with no new findings against the previously-fixed surfaces, so this release closes the audit. Also folds in stale Django version data from a parallel review.
- Bash
cat/find/grep/rg/head/tail/wcwildcards removed. The previous policy pairedread.*.env: denywithbash."cat *": "allow", so the model couldcat .envstraight through the bash channel and bypass the read-tool path policy. Replaced withread/glob/grepopencode tools (which respect path policy) for any file access. git *wildcards removed. Blanket"git *": "allow"accepted destructive verbs likegit checkout HEAD~5 -- /etc/passwd,git clean -fdx,git reset --hard,git config user.email evil@x. Whitelist now lists only explicit read-only verbs.git diffandgit diff *removed entirely.git diff --no-index FILE1 FILE2reads any file the user can read, fully bypassingexternal_directory: deny. Verified empirically:git diff --no-index /etc/hosts /dev/nulldumps/etc/hostscontent. Glob can't express "any flag except--no-index", so the verb is dropped — diff foruncommitted/commitmodes is now pre-computed in the wrapper instead.git log *andgit show *removed. Both verbs accept--output=PATH, which writes a file (verified:git log --output=/tmp/x -1creates/tmp/x). That bypasses theedittool policy via the bash channel.git logandgit showare still allowed without arguments (HEAD-only, no flag injection surface).git branch *andgit tag *removed. Wildcards accepted mutating forms —git branch -D foo,git tag -d v1,git branch new,git tag new— which modify.git/. No-args forms (list-only) are still allowed.- Command injection in untracked-file pre-compute. The previous
git ls-files --others ... | xargs -I {} sh -c '... cat -- "{}"'template literal-substituted filenames into thesh -ctemplate, so a malicious filename like$(touch /tmp/INJECTED)executed the substitution before reachingsh. Verified live: old pattern created/tmp/INJECTED, new pattern (NUL-delimited bashwhile read -d ''loop) does not. The new loop also doesn'tcatcontent at all — opencode now reads each file via its ownreadtool under the path-deny policy. .envpathspec was anchored to repo root only.:(exclude).envand:(exclude).env.*excluded./envonly;sub/.envandsub/.env.localslipped through intogit diff HEAD. Replaced with:(exclude,glob).env,:(exclude,glob)**/.env,:(exclude,glob).env.*,:(exclude,glob)**/.env.*. Verified: with the old formsub/.envcontent leaked into the diff; new form catches all four nesting variants.- Tracked-diff exclusion extended to all secret families. Was filtering
.env*only; now mirrors the fullreaddenylist (*.pem,*.key,id_rsa*,id_dsa*,id_ed25519*,id_ecdsa*,*.p12,*.pfx,*.keystore,*.jks,credentials.json,*credentials*.json,service-account*.json,.npmrc,.pypirc,.netrc) — root + every nested directory. Smoke-tested with 16 secret files across 3 directory levels: all filtered, only the benign tracked change remains. - Read-tool denylist was root-only. Patterns like
id_rsa,.npmrc,service-account*.jsonmatched only the repo root because opencode pattern matching does not cross/with a single*.secrets/id_rsaandpackages/app/.npmrcwere going through. Every secret pattern is now duplicated — once without**/(root) and once with**/(any depth).
github-build-fixer— short-poll loop now actually waits. Step 6'sfor _ in 1..6; do gh run list ...; donehad no delay, so it fired 6 queries in well under a second and returned "No run found" before GitHub had time to register the workflow run. Addedsleep 5between iterations and clarified the Step 1 sleep prohibition: it covers the long CI watch (usegh run watchinstead), not the short post-push materialization wait.readme-guardian— Django × Python compatibility matrix updated to 2026-05-08. Snapshot was missing Django 6.0 and treated 4.2 LTS as still in extended support (which expired Apr 2026). Verified againstdjangoproject.com/download/and thedev/faq/install/page: only 5.2 LTS (Python 3.10–3.14) and 6.0 (Python 3.12–3.14) are upstream-supported as of 2026-05-08; 4.2/5.0/5.1 are EOL. Table updated and dated; explicit "currently supported" callout added so consumers know which rows to filter to.python-upgrade-package— Django matrix examples and badges propagated. Sample CI matrix (Step 4.3), classifiers list (Step 1.2), Django badge example (Step 4.5), and the "drop EOL versions" guidance (Step 4.2b) all updated to drop 4.2/5.0/5.1 and add 6.0. The canonical table still lives inreadme-guardian— this skill only mirrors the examples.python-upgrade-package— Djangoconftest.pyexample fixed. The Step 5.5 sample assigneddjango.conf.settings.DJANGO_SETTINGS_MODULE = "..."on theLazySettingsproxy, which silently does nothing useful and would surface asImproperlyConfiguredon the nextdjango.setup(). Replaced withos.environ.setdefault("DJANGO_SETTINGS_MODULE", ...)and demoted the snippet — thepyproject.toml[tool.pytest.ini_options]form is now presented as the preferred path.
Patch release: closes two MEDIUM findings from a code-review-opencode self-review of the repo. Fixes a real .env exfiltration risk in the opencode review wrapper and propagates the tmux observability/stuck-detection pattern from code-review-external into the premortem-multiple family.
code-review-opencode—.envno longer leaks into prompts inuncommittedmode. The pre-computedDIFF(git diff HEAD+catof every untracked file) ran in the main agent before the opencode restrictive config existed, so any local.env/.env.localwas being read into the prompt body sent to the opencode API regardless of the in-session permission deny. Replaced withgit diff HEAD -- ':(exclude).env' ':(exclude).env.*'plus agrep -Ev '(^|/)\.env($|\.)'filter on the untracked file list.
premortem-codex— migrated to tmux pattern. Codex now runs inside a detachedpm-codex-{TS}tmux session (analogous tocr-codex-{TS}incode-review-external). Pane output captured viatmux pipe-paneto/tmp/premortem-codex-{TS}.log; codex still writes the final markdown report to/tmp/premortem-codex-{TS}.mdvia itswritetool (artifact-file pattern preserved). Switched invocation fromcodex exec ... > $RUN_LOG 2>&1(raw pipe) tocodex exec --skip-git-repo-check --sandbox workspace-write ... </dev/nullinside the runner.premortem-opencode— migrated to tmux pattern. Opencode now runs inside a detachedpm-opencode-{TS}tmux session. Restrictive project-local.opencode/opencode.jsonsetup + cleanup trap kept intact, with one fix: the trap now also callstmux kill-sessionso a Ctrl-C in the parent agent cleans up both the session and the config. Added--print-logsso the bootstrap stage is visible (and stuck-detectable) instead of buffered into silence. Combined config-setup + tmux-launch + 90 s stuck-detector + hard 600 s deadline live in one bash command (trap fires after polling, never before).premortem-multiplewrapper — surfacestmux attachcommands. After dispatching the three background tasks, the wrapper printstmux attach -t pm-codex-{TS}andtmux attach -t pm-opencode-{TS}so users can watch either reviewer live. The Claude subagent stays on theAgenttool (no tmux) — it has its own task lifecycle and doesn't need pane observability.
- New shared file
plugins/premortem-multiple/shared/tmux-runner.md— premortem-flavored variant of thecode-review-externaltmux runner pattern (different naming:pm-{tool}-{TS}sessions,/tmp/premortem-{tool}-{TS}.{md,log}files). Referenced by both leaf skills.
tmux≥ 3.0 in$PATHforpremortem-codexandpremortem-opencode(preflightwhich tmux; abort with install hint if missing). Same requirement ascode-review-external.
Patch release: code-review-external family rewritten to dispatch every reviewer (codex / opencode / claude) inside its own attachable tmux session, with a stuck-detector that aborts after 90 s of no log growth instead of hanging for 15+ min on a wedged provider.
code-review-externalfamily — all four skills (code-review-codex,code-review-opencode,code-review-claude,code-review-external) now run their underlying CLI inside a detached tmux session namedcr-{tool}-{TS}. Users cantmux attach -t cr-{tool}-{TS}at any point to watch a reviewer live. Pane output is captured to/tmp/code-review-{tool}-{TS}.logviatmux pipe-panewhile the reviewer writes its final markdown to/tmp/code-review-{tool}-{TS}.md(artifact-file pattern preserved).code-review-claude— switched fromAgent-tool subagent dispatch to a headlessclaude -pprocess inside tmux. Uses--permission-mode auto,--add-dir /tmp,--add-dir <project>,--allowedTools "Read Grep Glob Bash Write Edit". Three reviewers now share identical lifecycle (tmux session) instead of mixing tmux + Agent.code-review-externalwrapper — replacedBash run_in_background+TaskOutput x3orchestration with a single bash command that creates three tmux sessions, prints three attach commands up-front, and runs one combined polling loop (tmux has-session× 3, per-session stuck detector, hard 600 s deadline). Simpler model, nopkill, deterministic kill viatmux kill-session.code-review-codex— switched fromcodex reviewtocodex exec --skip-git-repo-check --sandbox workspace-write. The oldcodex reviewlacks--skip-git-repo-checkand crashed in non-git directories withNot inside a trusted directory;codex execworks in both git and non-git contexts.
- New shared file
plugins/code-review-external/shared/tmux-runner.md— universal tmux launch + polling pattern referenced by all four leaf/wrapper skills (naming convention,printf %q-based runner script,tmux pipe-panecapture, stuck-detector loop, combined-poll variant for the wrapper). --print-logsflag added to opencode invocations so the bootstrap stage is visible in the pane (and inRUN_LOG) instead of buffered into silence — makes auth/network hangs diagnosable in real time.
- Opencode reviews on machines where the model API is slow or wedged no longer wait 15+ min in silence — stuck detector kills the tmux session after 90 s of zero log growth and reports last log lines to the user.
- Codex reviews of design docs in fresh / non-git directories (e.g.
SPEC.mdin a brand-new project folder) no longer crash withNot inside a trusted directory and --skip-git-repo-check was not specified.
tmux≥ 3.0 in$PATHfor allcode-review-externalskills (preflightwhich tmux; abort with install hint if missing). Install:brew install tmux/apt install tmux.
Major release: one new plugin, big rewrites across python-upgrade-package and oss-github-publisher, DRY refactor across the multi-CLI families, HTML reports for premortem-multiple, and a setuptools.build_meta build-backend bug fix that quietly broke every previous run of python-upgrade-package.
Plugins included in this release:
code-review-external— parallel external code review (codex + opencode + Claude subagent)github-build-fixer— diagnoses and fixes failing GitHub Actions CI buildsoss-github-publisher— pre-flight audit before publishing a repo as open sourcepremortem— Klein-style premortem on plans, launches, hires, pricing, or strategypremortem-multiple— three parallel premortems with meta-synthesispython-upgrade-package— modernizes legacy Python packagespython2-cleanup← NEW — removes Py2 compatibility cruft from a Py3 codebasereadme-guardian— analyzes and improves Python project READMEs
- New plugin
python2-cleanup— 12 categories (__future__,six,unicode()/basestring/xrange/long/unichr, dict iter/view methods,dict.has_key(),python_2_unicode_compatible,u''prefix, customs2u/u2s/compat.pyhelpers,__metaclass__/with_metaclass/add_metaclass, stdlib renames, dunder renames, optionalsuper()simplification). Ripgrep-first detection, one commit per category, tests after every change. Iron Law: touch only Py2 cruft, never reformat. oss-github-publisherrewritten with 10 new audit areas:- D.2 extended secret regex set: Stripe (
sk_live_/rk_live_/sk_test_), Twilio (SK/ACSIDs), HuggingFace, DigitalOcean, Heroku HRKU, Mailchimp, Mailgun, Shopify (shpat/shpss/shpca), Square, Facebook EAACE, Google ya29 + refresh tokens, JWT, database connection URLs (postgres/mysql/mongodb/redis/amqp/mssql/cockroachdb). - D.7 hardcoded internal URLs / hostnames (
.internal,.intra,.corp, staging-/qa-/dev- patterns, internal SaaS instances, AWS ELB DNS, private IP ranges). - D.8 TODO/FIXME comments with internal ticket references (JIRA-style, GitHub-style, Asana/Linear/Trello).
- D.9 IDE / editor configs tracked (
.idea/.vscode/.history/.fleet/.nova/sublime-workspace) with per-path decision table; cross-content scan for embedded/Users/<name>/paths. - D.10 GPG/SSH key material and config (private keys → FAIL, host keys → FAIL, public keys/known_hosts → WARN).
- D.11 OS / IDE turds (
.DS_Store,Thumbs.db,desktop.ini, etc.). - Section E (new) — GitHub Actions security: SHA-pinning third-party actions (post tj-actions Mar 2025 incident),
pull_request_targetmisuse, deprecated actions (upload-artifact@v3etc.), permissions blocks, secrets in logs,run-nameinjection. - Section F (new) — PyPI name availability check (
curl https://pypi.org/pypi/<name>/json, normalisation rules). - Section G (new) — PyPI metadata audit ([project.urls], classifiers,
Development Status, three-way license consistency, no deprecated[tool.setuptools]entries). - Section H (new) — README content audit (length, Installation/Usage sections, no lorem ipsum, code blocks present, badges resolve).
- D.2 extended secret regex set: Stripe (
python-upgrade-packageStep 1: build smoke-test —uv build+twine checkbefore commit, catches broken metadata before it hits PyPI.python-upgrade-packageStep 1:[project.urls],keywords, andclassifiersblocks added to thepyproject.tomltemplate, with extraction rules and a "no fabricated placeholders" rule.python-upgrade-packageStep 1: full enumeration ofrequirements*.txtvariants (requirements/,*-requirements.txt,requirements-{test,docs,dev,prod}.txt) withfinddiscovery and per-variant routing into[project.dependencies]vs[project.optional-dependencies]extras.python-upgrade-packageStep 3: pyupgrade + django-upgrade hooks in.pre-commit-config.yaml, with--py-plusderived fromrequires-pythonfloor and--target-versionderived from the project's lowest Django.python-upgrade-packageStep 4: dynamic test matrix derivation — Python versions fromrequires-python, Django × Python pairs from canonical compatibility matrix (now sourced fromreadme-guardian).include:-style YAML for Django projects with explicit(python, django)pairs.python-upgrade-packageStep 6: Makefile substitution table — 21 concrete substitutions (e.g.,python setup.py install→uv sync,flake8→uv run ruff check,python setup.py sdist bdist_wheel→uv build) plus a list of what NOT to auto-substitute.premortem-multipleHTML visual report (parity with singlepremortem): dark theme, synthesis above the fold, per-agent accent colors (codex cyan / opencode green / claude purple), consensus / divergence / contradiction sections with pill-badges showing which agents converged. Saved alongside markdown synthesis and transcript.code-review-externalfamily: free-form mode (5th detection mode) — when argument doesn't match file/dir/commit, treat as a free-form hint passed verbatim to all three reviewers (e.g., "całe repo", "security audit src/auth/").- README: skill graph with three Mermaid diagrams (Python project lifecycle / decision-making / code review), recommended sequence ("python-upgrade-package → python2-cleanup → readme-guardian → oss-github-publisher → publish"), cross-references between skills.
code-review-externalfamily: DRY refactor. Extracted 3 shared files (shared/standard-review-prompt.md,shared/target-detection.md,shared/write-directive.md). The 4 leaf SKILL.md files reference these instead of duplicating ~80 lines × 3. Editing review criteria is now a single-file change. Net: −161 lines.premortem-multiplefamily: same DRY refactor. Extracted 2 shared files (shared/standard-premortem-prompt.md,shared/write-directive.md). Net: −77 lines.- All external review and premortem skills: switched from
tee-pipeline to artifact-file pattern. Each tool (codex / opencode / claude subagent) writes its final review or premortem directly to a designated$OUTfile via its ownwritetool; verbose stdout / stderr go to a separate.logfile. The wrapper reads only the clean$OUTfiles (1–3 KB of markdown each, instead of 50+ KB of banners and reasoning). - opencode skills (review + premortem): temporary project-local
.opencode/opencode.jsonconfig with explicit allow / deny rules (read repo, bash limited togit/ls/find/cat/etc., write only to/tmp/code-review-*or/tmp/premortem-*), restored via trap onEXIT/INT/TERM. Avoids--dangerously-skip-permissionsand prevents 60+ minute hangs on permission asks in non-TTY mode. code-review-claudeandpremortem-claude: switched from "subagent returns text + main agent Writes" to "subagent writes directly to$OUTvia Write tool" — now consistent with codex / opencode and with wrapper expectations.- Django × Python compatibility matrix: now lives canonically in
readme-guardian(single source of truth across the plugin family).python-upgrade-packagereads from there instead of maintaining a parallel copy. Thereadme-guardiansnapshot was also updated to match the canonical version (added Django 5.2 LTS, fixed two factual errors that mismarked Django 5.0 support). - README: plugins regrouped under three purpose categories (Python project lifecycle / Decision-making / Code review).
python-upgrade-packageBUG:pyproject.tomltemplate specifiedbuild-backend = "setuptools.backends._legacy:_Backend", which is not a real backend identifier. Every project modernised by previous versions of this skill ended up with apyproject.tomlthat fails to build. Replaced withsetuptools.build_meta(the canonical default) in both spots where it appeared (Step 1 template + Step 2 setuptools-scm template). The Step 1 build smoke-test added in this release would have caught this — and now does.python-upgrade-packagerufftarget-versionwas hardcoded"py310"despite the skill's own "DO NOT hardcode" rule for the CI matrix. Now derived fromrequires-pythonfloor, with an explicit derivation table mirroring Step 4.2a.python-upgrade-packagelint-job example useduv python install 3.13literal — replaced withHIGHEST_PYplaceholder so the workflow run fails loudly if not replaced (rather than silently using a wrong matrix-misaligned version).github-build-fixerStep 6 usedsleep 5aftergit pushto "wait for GitHub to register the push" — both a Bash antipattern blocked by the harness and unnecessary (gh run watchpolls). Replaced with a SHA-based poll loop (up to 30 s, exits early when the run for HEAD's SHA appears) and an explicit Bashtimeout: 1800000directive (30 min) ongh run watch— previously the default 2-min Bash timeout would kill the watch on any CI run longer than 2 minutes.code-review-codexdropped--uncommitted/--commit <SHA>flags — codex (≥ 0.129) rejects those when[PROMPT]is given (the argument '--uncommitted' cannot be used with '[PROMPT]'). Codex now runsgit diff/git showitself via its bash tool, instructed by the prompt body, which also lets the artifact-file write directive co-exist with the target-specifying invocation.
Initial CalVer cut. Versioning scheme moved from SemVer (1.0.0) to CalVer (YYYY.0M.MICRO).
Plugins included in this release:
code-review-external— parallel external code review (codex + opencode + Claude subagent)github-build-fixer— diagnoses and fixes failing GitHub Actions CI buildsoss-github-publisher— pre-flight audit before publishing a repo as open sourcepremortem— Klein-style premortem on plans, launches, hires, pricing, or strategypython-upgrade-package— modernizes legacy Python packagesreadme-guardian— analyzes and improves Python project READMEs
- New
premortemplugin (migrated from a personal~/.claude/skills/premortem.mdto a full plugin layout). - Top-level
versionfield in.claude-plugin/marketplace.json. - This
CHANGELOG.md. scripts/bump-version.sh— helper to advance everyversionfield across the repo to the next CalVer.
- All
plugin.jsonand marketplace entries:1.0.0→2026.05.0. README.mdtagline expanded to cover code review and decision-making workflows.