All notable changes to codeforerunner are documented here.
The format is loosely based on Keep a Changelog; this project follows Semantic Versioning.
--repoaccepted on every subcommand —forerunner check --repo <path>now works, as do the equivalent forms forinit,scan,doc,doctor,refreshandinstall. Previously onlymcp-serverredefined--repoas its own flag, and every other subcommand required the top-level position; the asymmetry is what the action's broken invocation grew out of. When given on both sides the subcommand's value wins. (#108,src/codeforerunner/cli.py,src/codeforerunner/installer.py)- Composite action smoke job —
ci.ymlruns the local action againsttests/fixtures/drifting-repo, once ungated (must pass) and once gated (must fail). Neither step can read the CLI's exit code, but the pair pins it: a failure to run (exit 2) fails the ungated step too, so only exit 1 satisfies both. (#108,.github/workflows/ci.yml,tests/fixtures/drifting-repo/)
- GitHub Action always failed on argument parsing —
action.ymlinvokedforerunner check --repo <path>, but--repois a top-level flag, so argparse exited 2 before any drift check ran. Withfail-on-drift: "true"the job failed 100% of the time and reported it as documentation drift; with"false"the trailing|| trueswallowed exit 2 and the job went green having checked nothing. The step now invokesforerunner --repo <path> checkonce and branches on its exit code: only exit 1 (drift found) is downgraded to a warning underfail-on-drift: false; every other non-zero code still fails the job. (#108,action.yml,tests/test_action_yml.py)
- Docs Index — glossary term in
CONTEXT.mddefining the## DocumentationREADME section that links every user-facing doc indocs/with one-line descriptions. The readme task is its sole writer; the check task flags README STALE on unlinked docs or dead index links;.forerunner/artifacts are never indexed. Groundwork for the README docs-index feature (#105). (#106,CONTEXT.md)
- Refresh Gate — the
/forerunner-refreshskill form now presents the staleness check report and asks once (multi-select, all options pre-selected) whichSTALE/MISSINGdocs to regenerate, instead of rewriting everything unprompted.UNVERIFIABLEdocs are reported but never offered. Passauto(or run in a harness that can't ask) to skip the gate and update the full stale set. The batch prompt form stays non-interactive for CI/AFK use. Summary output gains a "declined" category. Glossary term added toCONTEXT.md. (#102,skills/forerunner-refresh/SKILL.md,src/codeforerunner/prompts/tasks/refresh.md)
forerunner-gapsskill — surfaces STALE/MISSING documentation findings from.forerunner/check-report.mdand unresolvedgaps:fields from.forerunner/scan.yaml. For doc gaps, routes to/forerunner-refreshor specific task skills. For scan gaps, offers quick Q&A fill (patchesscan.yamlinline) or a fullgrill-with-docssession; falls back to Q&A ifgrill-with-docsis not installed. Registered in the Task Registry (scan_exempt: true) and installable via the skill installer. (skills/forerunner-gaps/SKILL.md,src/codeforerunner/prompts/tasks/gaps.md,src/codeforerunner/tasks.json)
- Agent detection silent failures —
shellEscapewas missing its closing single quote, causing allcommand:-based detections (claude,gemini,opencode,codex, etc.) to produce a shell syntax error and returnnot found. Only agents with amacapp:fallback (e.g. Cursor) were detected. (bin/install.js) - Global install installing locally —
installViaSkillsnever passed-gtonpx skills add, so the global/local choice had no effect for non-Claude/Gemini agents; both modes installed to the current directory. (bin/install.js) - Agent profile filter overridden by
--all—npx skills add --allexpands to--agent '*', silently overriding the per-provider-a <profile>argument. Replaced with explicit--agent <profile> --skill '*'. (bin/install.js) - Bundled skills ignored on
npxinstalls —fetchSkillfell back to HTTPS even thoughskills/ships in the npm package, becausedetectRepoRootrequiresplugins/which is not in the published files. Now checks__dirname/../skills/before the network. (bin/install.js)
- Interactive agent selection — when multiple agents are detected and stdin/stdout are TTYs, the installer prompts users to choose which agents to install to (numbered list, space-separated input, default: all). Skipped when
--only,--non-interactive, or only one agent is detected. (bin/install.js) - 12 new installer tests:
shellEscapecorrectness and shell round-trip,buildSkillsAddArgsunit tests for global-gflag and agent profile preservation, local install path targeting,--onlyvalidation,--non-interactivenon-blocking. (tests/install.test.js)
- npm package metadata: SPDX-style license declaration,
authorfield, and aSECURITY.mdpolicy. (package.json,SECURITY.md)
- Installer refactored so the Install Plan is the unit of work. (
bin/install.js) - Skill-parity refactored: the canonical↔copies body rule now lives in one module.
- Prompt-session bundle outcome now owned behind
resolve(). - Purged iCloud sync-conflict files and added a guard to block future ones.
0.4.5 — 2026-05-29
- Task Registry (
src/codeforerunner/tasks.json) — single source of truth for task identity, scan-exemption policy, the refresh sequence, and installable skill slugs. (#66) - Node installer (
bin/install.js) now reads installable skill slugs from the Task Registry instead of a hardcoded list, backed by a Node↔Python parity test and anode --testsuite wired into CI. (#70) - Scan-first gate persists across restarts via
.forerunner/session state and is enforced consistently across the CLI and MCP server. (#56, #68) arch-reviewtask and skill surface.
- npm publishing — the publish workflow now upgrades the npm CLI before publishing. Node 22 bundles npm 10.x, which lacks OIDC trusted-publishing support and silently falls back to anonymous publish (registry returns
404); OIDC trusted publishing requires npm ≥ 11.5.1. (.github/workflows/npm-publish.yml) - Socket badge version stays in sync on release. (#67)
- Installer shim pins corrected, with future-drift detection.
- Docker login credentials in the publish workflow. (#41)
package.jsonpaths and README install instructions. (#40)
- Retired
SPEC.md; GitHub Issues now own work tracking. CONTEXT.mdand agent docs: added npm release and GitHub Issues glossary terms.- CodeRabbit automatic review disabled.
- npmjs publishing is now OIDC trusted publishing (tokenless). The
NPM_TOKENsecret referenced in the 0.4.1 notes is no longer used or required; auth comes from thenpmenvironment'sid-token: writepermission. (#48)
0.4.4 — 2026-05-26
- Installer supports
--global/--localflags and refresh mode for updating existing installations. (bin/install.js) - GitHub Action published to marketplace — composite runner at
action.ymlfor CI-based forerunner runs. - Docker + Makefile sample for containerized usage.
- Dependabot configuration for automated dependency updates.
- Branch protection rules for
mainvia Rulesets API with admin bypass. - Published to GitHub Packages npm registry under
@derek-palmer/codeforerunner.
tomllibimport compatibility fix for Python < 3.11; canonical Windows argument quoting.- CodeQL scan findings: incomplete URL substring sanitization, workflow missing permissions, incomplete string escaping, clear-text logging of sensitive information.
- Configuration and documentation clarity improvements.
- GitHub Actions pinned to latest versions.
- H1 —
forerunner doctorno longer executes Python scripts from the target repo by default. Script-based checks (skill-body-parity,codex-marketplace) now emit[warn] skipping script validationunless--run-scriptsis passed explicitly. (doctor.py,cli.py) - H2 —
install.shandinstall.ps1now pin the npm package tocodeforerunner@0.4.1and the GitHub fallback togithub:derek-palmer/codeforerunner#v0.4.1, preventing arbitrary code execution incurl|bashone-liner installs. - H3 — Added comment in
providers/google.pydocumenting that the API key appears in the URL query string (Google REST API requirement; key may appear in proxy logs). - M2 — MCP server
tools/callvalidates that the toolnamecontains no path separators or..components, and checks the resolved path is insideprompts/tasks/before executing. (mcp_server.py) - M7 —
OllamaProviderandis_availablenow validate the base URL scheme (http/https) and reject169.254.*link-local addresses to prevent SSRF viaOLLAMA_HOST. (providers/ollama.py)
- M1 —
forerunner.config.yamland_STARTER_CONFIGindoctor.pyhadenabled_rulesat the YAML root instead of undertasks.check. This was a functional bug causing the field to be silently ignored. Both the dogfood config and the--fixtemplate are corrected. - M3 —
cmd_generateno longer swapssys.stdoutglobally (thread-unsafe). Bundle resolution now goes through_get_bundle()which returns a string directly. (cli.py) - M4 — All provider
urlopencalls now passtimeout=120to prevent indefinite hangs. (providers/anthropic.py,openai.py,google.py,ollama.py) - M5 —
install_all_skillsnow correctly setsany_error = Truewhen a source file is missing or a write fails, so install failures propagate to the return code. (installer.py) - M6 —
int()calls inconfig.pyare now wrapped in_to_int()which raisesConfigErrorwith a descriptive message instead of bareValueError. (config.py) - L1 — Replaced
assert span is not Noneinoverlay()withRuntimeError. (installer.py) - L2 — Removed unused
output_dir,context_max_files,context_max_lines_per_filefields fromForerunnerConfigand the YAML parser. (config.py) - L3 —
_load_script_modulenow uses a UUID-suffixed module name to prevent stale cached modules on repeated calls. (doctor.py) - L4 —
_description_forin MCP server now reads line-by-line instead of loading the entire file into memory. (mcp_server.py) - L5 —
format_reportuses direct dict access (counts['ok']) instead of redundant.get()calls. (doctor.py) - L6 — MCP server now enforces
initializeas the first call;tools/listandtools/callbeforeinitializereturn JSON-RPC error-32002 Server not initialized. (mcp_server.py) - L7 —
vscodeExtPresentandcursorExtPresentinbin/install.jsnow useincludes()instead ofnew RegExp(needle), preventing extension ID metacharacters from being interpreted as regex. (bin/install.js) - L8 — Added unit test
test_generate_stream_flag_yields_chunkscovering the--streambranch ofcmd_generate. (tests/test_cli.py) - L9 —
find_prompts_rootnow stops walking after 10 parent directories to avoid traversing to the filesystem root. (bundle.py)
- npm publish —
codeforerunnerpackage published to npmjs.com alongside the existing PyPI release.npx codeforerunnerandnpx codeforerunner-installboth run the multi-agent installer. - Root
package.jsonwithbin,files,engines,keywords,repositoryfields. .github/workflows/npm-publish.yml— publishes to npm with provenance (--provenance --access public) on everyv*.*.*tag push, usingNPM_TOKENsecret.install.shandinstall.ps1now probe the npm registry first (HEAD https://registry.npmjs.org/codeforerunner/latest) and fall back tonpx github:derek-palmer/codeforerunnerif npm is unavailable.
- Both
pyproject.tomlandpackage.jsonversions must be kept in sync on every release. Bump both files, commit as a singlechore: bump to vX.Y.Zcommit, then tag. - npm provenance requires the
npmGitHub Actions environment to be configured in the repo settings and anNPM_TOKENsecret withAutomationscope to be added.
- Multi-agent skill packaging — 12 per-task slash commands (
/forerunner-scan,/forerunner-readme,/forerunner-api-docs,/forerunner-audit,/forerunner-changelog,/forerunner-check,/forerunner-diagrams,/forerunner-flows,/forerunner-init,/forerunner-review,/forerunner-stack-docs,/forerunner-version-audit) for Claude Code, Codex, Gemini CLI, and 30+ other agent CLIs. bin/install.js— unified cross-platform installer modelled on caveman's pattern: 33-agent matrix with detection probes (command:,macapp:,vscode-ext:,cursor-ext:,jetbrains-plugin:,dir:,file:), three install mechanisms (claude plugin install,gemini extensions install,npx skills add), and full flag surface (--dry-run,--force,--only,--all,--minimal,--list,--no-color,--skip-skills,--uninstall).install.sh/install.ps1rewritten as thin Node.js shims: execnode bin/install.jslocally, fall back tonpx github:derek-palmer/codeforerunnerfor curl|bash installs.skills-lock.json— SHA-256 content hashes for all 13 skill files.- Agent autodiscovery files:
GEMINI.md(Gemini CLI),.codex/config.toml(Codex),.claude-plugin/marketplace.json(Claude Code marketplace). - Ollama auto-fallback —
forerunner generateprobeslocalhost:11434when no API key is configured; automatically switches to Ollama local mode if available. Explicit--providerorprovider:in config always takes precedence. Improved error message includes Ollama hint when no fallback is found. forerunner doctorsurfaces Ollama local-mode status: reports running/not-running when noforerunner.config.yamlis present.- 218 new tests (187 → 405 total) covering Ollama fallback paths, doctor Ollama checks, and skill installer logic.
- Default Anthropic model updated from
claude-opus-4-5toclaude-opus-4-7across CLI, MCP server, and provider defaults.
0.3.2 — 2026-05-24
- Inverse drift rules RI1, RI5, RI7: fire when docs positively reference a feature (CLI, pip package, MCP server) that is absent from the repo.
- Version-pin drift rule RV1: flags
codeforerunner==X.Y.Zpins in docs that differ from the currentpyproject.tomlversion; skipsCHANGELOG.md. forerunner doctor --fix: writes a starterforerunner.config.yaml(enabling R1–R5, R7, R8) when no config exists, then runs the normal health report.forerunner generate --stream: streams output token-by-token for all four providers (Anthropic SSE, OpenAI SSE, GooglestreamGenerateContent?alt=sse, Ollama NDJSON).action.ymlcomposite GitHub Action —uses: derek-palmer/codeforerunner@vX.Y.Zinstalls codeforerunner and runsforerunner check. No-op whenforerunner.config.yamlis absent.
- Test suite expanded from 145 to 174 tests: inverse rule and version-drift coverage, streaming provider coverage for all four backends,
doctor --fixintegration tests.
0.3.1 — 2026-05-24
forerunner.config.yamldogfood config at repo root; enables drift rules R1–R5, R7, R8.auditandchangelogtask prompts (prompts/tasks/audit.md,prompts/tasks/changelog.md).- PyPI
classifiersandkeywordsinpyproject.tomlfor discoverability. src/codeforerunner/bundle.py— sharedfind_prompts_root()+resolve_bundle()used by bothcli.pyandmcp_server.py; eliminates duplicated_repo_rootlogic.
forerunner mcp-servernow works afterpip installwithout requiring--repo: prompts bundled inside the package (src/codeforerunner/prompts/) and included viapackage-data.forerunner --versionand MCPserverInfo.versionnow read the installed package version dynamically instead of the hardcoded"0.2.0"string.- MCP advertised protocol version updated from
2024-11-05to2025-03-26. forerunner mcp-server --repo /pathnow works and appears in--help(previously onlyforerunner --repo /path mcp-serverworked).forerunner-checkCI no longer fails on every push: removed pre-checkouthashFiles()gate that always evaluated false (empty workspace beforeactions/checkout).
- Test suite expanded from 117 to 145 tests: HTTP/network error paths for all four providers, check edge cases, CLI exit codes.
0.3.0 — 2026-05-24
forerunner --versionflag (T34).forerunner doctorsubcommand — single-screen health report covering skill body parity, Codex marketplace validation, and installed-destination markers (T35).- Workflow-YAML parse test (
tests/test_workflows_yaml.py) — catches typos in.github/workflows/*.ymlwithout requiringactionlintlocally (T36). - This changelog (T37).
- Provider abstraction and
forerunner generate <task>command for configured model calls (T38). - Per-provider
api_key_envconfig override plusforerunner doctorkey checks (T39). - PyPI publish workflow (
.github/workflows/publish.yml) using OIDC trusted publishing onv*.*.*tags (T40). README.md"Install" section documentingpipx/pipinstall after the first PyPI release (T40).
- Direct model invocation is available through
forerunner generate;provider/modelconfig fields are active there.
Initial release-ready surface around the prompt pack.
- Python package and
forerunnerconsole script. - CLI subcommands:
init,scan,doc,check,mcp-server,install. forerunner init --full / --agents-onlyflags (T27).forerunner checkrules R1–R8 withforerunner.config.yamlschema,enabled_rulesallowlist, andignore_pathsglobs (T22, T25, T32).forerunner.config.yamlschema + loader (src/codeforerunner/config.py);ConfigErrorsurfaces field paths (T25).forerunner mcp-server— stdio JSON-RPC MCP server exposing one tool perprompts/tasks/*.md;tools/callenforces SPEC V2 scan-first per session (T23, T26).forerunner install <agent>— idempotent body-parity skill installer with managed-region markers and--checkdry-run (T18).forerunner install <agent> --marketplace— installsplugins/codex/marketplace.jsoninto~/.codex/marketplaces/codeforerunner.json(T24).forerunner doc <task>stderr warning whenforerunner.config.yamlis present andFORERUNNER_SCAN_DONEis unset (CLI parity with the MCP scan-first gate; T31).- Pre-commit hook (
.pre-commit-hooks.yaml) and GitHub Actions workflow (.github/workflows/forerunner-check.yml) wrappingforerunner check; both no-op withoutforerunner.config.yaml(T19). - GitHub Actions workflow (
.github/workflows/codex-marketplace-publish.yml) that validates the manifest, asserts tag/version parity, and uploads it on tagged release (T28). - Canonical skill source (
agent/codeforerunner.skill.md) with Codex (plugins/codeforerunner/) and Claude (.claude-plugin/,skills/codeforerunner/) distributions; body parity enforced byscripts/validate_skill_copies.py(T12–T14). - Prompt pack hardening (evidence rules, gaps convention) across
prompts/tasks/*.md(T8, T16). agent-configs/scaffolds for Claude, Cursor, Copilot, Cline, Windsurf (T3).docs/getting-started.md,docs/prompt-guide.md,docs/editor-agent-setup.md,docs/roadmap.md,docs/agent-distribution-design.md.
- Only runtime dep:
PyYAML>=6.0. initandscanare honest wrappers over the prompt pack; they emit bundled prompt text to stdout for the calling agent to act on.- Model invocation is out of scope;
provider/modelconfig fields are honored only by future wrappers.