All notable changes to crag are documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.6.8 — 2026-07-18
0.6.7 — 2026-07-18
0.6.6 — 2026-07-17
- Relicensed from MIT to Apache-2.0. All contributions are owned by
Alexandru Cioc (WhitehatD), so the relicense is legally clean. Adds a
NOTICEfile per Apache convention.package.jsonlicensefield updated. - README refreshed to the converged product story: crag is the reliability
layer for AI coding agents — the deterministic compiler plus an opt-in
verified-memory loop (
crag memory/crag distill/crag audit --memory). Added an ecosystem section (crag-engine, crag.nvim, crag-audit-action, app.crag.sh).
0.6.5 — 2026-07-17
0.6.4 — 2026-07-17
0.6.3 — 2026-07-17
0.6.2 — 2026-07-17
0.6.1 — 2026-07-03
0.6.0 — 2026-06-02
0.5.45 — 2026-05-16
0.5.44 — 2026-05-16
0.5.43 — 2026-05-16
0.5.42 — 2026-05-16
0.5.41 — 2026-05-16
0.5.40 — 2026-05-15
0.5.39 — 2026-05-15
0.5.38 — 2026-05-13
0.5.37 — 2026-05-07
0.5.36 — 2026-04-19
0.5.35 — 2026-04-19
0.5.34 — 2026-04-19
0.5.33 — 2026-04-19
0.5.32 — 2026-04-19
0.5.31 — 2026-04-19
0.5.30 — 2026-04-19
0.5.29 — 2026-04-19
0.5.28 — 2026-04-17
0.5.27 — 2026-04-17
0.5.26 — 2026-04-17
0.5.25 — 2026-04-17
0.5.24 — 2026-04-16
0.5.23 — 2026-04-15
0.5.22 — 2026-04-15
0.5.21 — 2026-04-15
0.5.20 — 2026-04-15
0.5.19 — 2026-04-15
0.5.18 — 2026-04-15
0.5.17 — 2026-04-14
0.5.16 — 2026-04-14
0.5.15 — 2026-04-14
0.5.14 — 2026-04-13
0.5.13 — 2026-04-13
- 5 false-positive drift detection bugs:
checkSubdirsonly scanned 1 level (missed nested workspace packages),node_modules/paths failed in shallow clones, nx-cloud CI orchestration not filtered as noise,make -jNparallelism flags not normalized, autotoolsMakefile.innot recognized by make verifier checkSubdirs→getWorkspaceDirs: 2-level scan with container detection- 15 new command patterns in
checkGateReality(uv,make,mix,bundle, etc.) isNoise: filternode_modules/,nx-cloud,make install/clean/-CnormalizeCmd: stripmake -jN, normalizepnpm/yarntonpm- README: corrected "99% drift" → "55% zero AI config" (verified on 100 repos, 3,620 gates)
- 5 new tests (593 → 598)
0.5.12 — 2026-04-13
- Stale test counts in README and docs (591/589 → 593)
0.5.11 — 2026-04-13
crag diff --ci: exits non-zero when CI has gates governance doesn't know aboutcrag diff --json: machine-readable output for programmatic usecompile --target githubnow generatesgovernance-guard.ymlalongsidegates.yml— triggers on CI config file changes, runscrag diff --ci- Same guard workflow generated for Forgejo target
isGateCommand()excludes crag's own meta-tooling commands
0.5.10 — 2026-04-13
- Forgejo / Gitea Actions support: analyze extracts from
.forgejo/workflows/and.gitea/workflows/, compile generates.forgejo/workflows/gates.ymlwith Forgejo action mirrors (code.forgejo.org) - New compile target:
crag compile --target forgejo(14 total targets)
0.5.9 — 2026-04-12
0.5.8 — 2026-04-11
0.5.7 — 2026-04-11
0.5.6 — 2026-04-11
0.5.5 — 2026-04-11
0.5.4 — 2026-04-11
0.5.3 — 2026-04-11
0.5.2 — 2026-04-11
0.5.1 — 2026-04-11
0.5.0 — 2026-04-11
crag upgrade --siblings— upgrade skills in all sibling repos in one passcrag checkupdate nudge — amber box shown when installed skills are behind the bundled versioncrag auditunmanaged CI — commands in workflow files without# crag:auto-startare shown as an informational footnote, not counted as issues
0.4.6 — 2026-04-11
0.4.5 — 2026-04-11
0.4.4 — 2026-04-10
0.4.3 — 2026-04-10
0.4.2 — 2026-04-10
0.4.1 — 2026-04-10
0.3.12 — 2026-04-10
0.3.11 — 2026-04-10
0.3.10 — 2026-04-10
0.3.9 — 2026-04-10
0.3.8 — 2026-04-10
0.3.7 — 2026-04-09
0.3.6 — 2026-04-09
0.3.5 — 2026-04-09
0.3.4 — 2026-04-08
0.3.3 — 2026-04-08
0.3.2 — 2026-04-08
0.3.1 — 2026-04-08
- Governance gates — removed 4 broken CI gates inferred from stale
ci.yml(npm run lint,npm run build,npx tsc --noEmit,node --check "$f"); recompiledgates.ymlto match. - Commit convention detection — extracted shared
detectCommitConvention()andclassifyGitCommitConvention()todrift-utils.js;diffanddoctorwere maintaining duplicate regex/threshold logic that could diverge. - "No governance.md" guard — unified across 4 commands via shared
requireGovernance()incli-errors.js(previously each command had its own wording). - Dead re-exports — removed backward-compat re-exports from
diff.js(extractRunCommands,isGateCommand) anddoctor.js(countFeatureBranches,detectBranchStrategy); tests now import from canonical modules. - ANSI color naming — standardized to single-letter convention (
G,R,Y,C,B,D,X) acrossanalyze.js,demo.js, anddoctor.js. - docs/commands.md — documented undocumented
--forceflag oncrag hook installand--dry-runon barecrag. - SECURITY.md — added
installcommand to in-scope list (writes to~/.claude/agents/outside project). - Deleted stale
ci.yml— untracked workflow referencing nonexistentnpm run lintandnpm run buildscripts.
preserve.jstests — 12 tests covering marker preservation, idempotency, edge cases (directory at path, missing end marker, legacy files).
0.3.0 — 2026-04-08
crag audit— drift detection across governance, compiled configs, and codebase reality. Three axes: (1) staleness — compiled configs older than governance.md, (2) reality — governance references tools that don't exist, (3) missing — AI tool directories present but no compiled config. JSON output via--json, auto-fix via--fix.crag hook— pre-commit hook management.crag hook installwires auto-recompile on governance change.crag hook install --drift-gatealso blocks commits when drift is detected.crag hook uninstallandcrag hook statusfor lifecycle management.crag auto(barecragcommand) — runsanalyze+compile --target allin one shot when invoked in a project directory. Auto-detects whether the current directory looks like a project.- Amazon Q compile target (
crag compile --target amazonq) — generates.amazonq/rules/governance.md. Replaces the previouscodytarget. - Per-path glob-scoped file splitting for Cursor, Windsurf, Copilot, and Continue generators when governance.md has path-scoped sections.
- Custom section preservation with
<!-- crag:custom -->markers — hand-written content survives recompilation (except frontmatter files). - 8 new project mining functions in
crag analyze: architecture type, key directories, testing profile, code style, import conventions, dependency policy, anti-patterns, framework conventions.
crag analyzeoutput expanded from ~20 lines to ~80 lines per project, covering architecture, testing, style, and framework conventions.- Replaced
codycompile target withamazonq(Cody wrote to a path no tool discovers; Amazon Q uses.amazonq/rules/). - Zed target now writes
.rulesat repo root (was.zed/rules.md). - Windsurf target now writes
.windsurf/rules/with YAML frontmatter.
[0.2.12] — 0.2.43 — 2026-04-05 through 2026-04-08
Auto-release bumps. No user-visible changes between [0.2.11] and [0.3.0];
consolidated here rather than keeping 32 empty version headers.
0.2.11 — 2026-04-05
Correctness
cli-args.js(new) — sharedvalidateFlags()with typo suggestions, wired intoanalyze,compile,diff,doctor,upgrade,workspace,check. Unknown flags were previously accepted silently;crag analyze --garbage-flagwrote governance with no warning. Now exits 1 with a "did you mean?" hint for close matches.normalize.jsisNoise— extended with 11 new rules: standalone shell builtins (break,exit,continue,shift,trap), backslash line continuations, version probes (node --version,which,shellcheck --version), variable assignments from embedded code (rake_version = File.read(...)), subshell fragments, cross-language prints (puts,print,console.log,die), andcurl | bashinstallers. Regression examples: vscode no longer getsbreakas a gate; duckdb no longer getsmake \; ruby no longer getsrake_version = ...leaked from a rubyrun: |block.normalize.jsextractMainCommand— now splits on;in addition to&&, and returns''when every part of the compound is noise so the caller rejects the whole line instead of leaking the last fragment.analyze.js— emits- true # TODO: …placeholder under### Testwhen zero gates are detected. Previously crag wrote a valid file with an empty## Gatessection and every downstream doctor/compile/diff call failed with "0 gates declared". 20 repos in the stress test hit this path (bitcoin, postgres, sqlite, cabal, flutter, jint, nginx, …).diff.js— deduplicate EXTRA commands across workflows vianormalizeCiGates; reuse analyze-sideextractCiCommandsso non-GitHub CI systems (Jenkins, GitLab, CircleCI, Azure, Buildkite, Cirrus, Drone, Woodpecker, Bitbucket) actually participate in drift detection. Previouslydiff.jsonly scanned.github/workflows/.diff.jsnormalizeCmd— strips YAML-style wrapping quotes iteratively so"npm test"compares equal tonpm test.
Coverage — 14 new stack detectors
stacks.js— C/CMake (CMakeLists.txt), C/autotools (configure.ac,autogen.sh), C/Meson (meson.build), Haskell (cabal/stack/hpack), OCaml (dune/opam), Zig (build.zig), Crystal (shard.yml), Nim (*.nimble), Julia (uuid-sniffedProject.toml), Dart/Flutter (pubspec.yaml), Erlang (rebar3/erlang.mk), Lua (rockspec), expanded .NET (.slnx,Directory.Build.props,Directory.Packages.props,global.json). C/C++ Makefile detection is guarded so Node/Python/Go projects with a convenienceMakefilearen't mislabelled.stacks.jsdetectNestedStacks— now skips fixture directories (examples/,samples/,fixtures/,docs/,testdata/,benchmarks/,node_modules/,target/,dist/, …) so nx no longer reports 7 stacks because of fixture sub-apps. Added symlink cycle protection via realpath identity (lstatSync+ visitedSet).stacks.jsdetectKotlin— Kotlin-onlybuild.gradle.ktsnow also addsjava/gradle+ detectsgradleWrappersoinferKotlinGateshas a build system hook.gates.js— newinferGatesimplementations for 12 languages (Erlang, Haskell, OCaml, Zig, Crystal, Nim, Julia, Dart, Flutter, C-family CMake/Meson/autotools/Makefile).
Coverage — CI systems
ci-extractors.js— added Cirrus CI extractor (.cirrus.yml*_script:keys), used by bitcoin, postgres, flutter, and many embedded / systems projects. Added ad-hocci/*.sh,.ci/*.sh,scripts/ci-*.shscanner for canonical gate names (test.sh, lint.sh, check.sh).ci-extractors.js— block-scalar quote stripping is now consistent across every extractor path. Previously CircleCI (run: |form), Azure (script: |), and the genericextractYamlListFieldpath used by GitLab/Travis/Buildkite/Drone/Bitbucket all droppedstripYamlQuoteson block scalars, leaking quoted strings. Regression guard: new parametrized test intest/analyze-ci-extractors.test.jsasserts inline + block-scalar quote stripping across 7 CI systems.ci-extractors.jsextractCircleCommands— now handles therun: |block scalar form. Previously onlycommand: |was parsed, so any CircleCI job using- run: |\n <commands>dropped its entire body.yaml-run.jsextractRunCommands— block scalars on GitHub Actions paths now also callstripYamlQuotes.
Coverage — task runners
task-runners.js—GATE_TARGET_NAMESexpanded with 20+ names includingkselftest,selftest,sanity,smoke,regress,integration,e2e,unit,itest,validate,audit,security,sec,sast. Removed ambiguous'style'(often a CSS build artifact target, not a linter).
UX
compile.js— target validation is now the first thingcompile()does, socrag compile --target zzzunknownfails fast without the previous "Compiling → zzzunknown / 0 gates, 0 runtimes" noise that used to precede the error.compile.js— refuses to emit executable targets (github,husky,pre-commit) whengateCount === 0. Previously crag would write a valid-YAML-but-no-steps workflow file. Doc-only targets (cursor,agents-md,gemini, …) still work.compile.js— help text uses${ALL_TARGETS.length}instead of a hardcoded "12".analyze.js— cross-section gate dedup vianormalizeCmd. Fixes chalk regression where both### Test - npm run testand### CI - npm testshowed up.analyze.js— auto-installs universal skills after writing governance.md (opt out with--no-install-skills). Closes the UX gap wherecrag checkalways failed right aftercrag analyze.check.js— new--governance-onlymode that only requiresgovernance.md, for the post-analyze path.analyze.js— rotates.bak.<millis>files to the 3 newest. Previous behaviour accumulated one backup per run.analyze.js— warns when invoked from a known infra subdirectory (.claude/,.github/,.buildkite/,.gitlab/,.cursor/,.vscode/,.idea/,.husky/). Previous behaviour was to silently treat the subdirectory as its own project.analyze.js— drains malformed-JSON warnings fromstacks.jsand reports them viacliWarn. Users now see when a rootpackage.jsonfailed to parse.
Audit items
parse.js—MAX_CONTENT_SIZEtruncation now cuts at the last\n##section boundary instead of mid-line, preserving gate integrity on oversize files.doctor.js—rtk-hook-versionmarker window 5 → 20 lines.doctor.js— git command timeouts (git branch -a,git log) now surface aswarnwith a clear detail instead of silent skip.
- 498 tests passing (from 357). 141 new cases covering every new rule above, including a parametrized cross-CI quote-stripping regression test against GitHub Actions, GitLab, CircleCI, Travis, Azure, Drone, Bitbucket with both inline and block-scalar forms.
- New test files:
cli-args.test.js,compile-validation.test.js,workspace.test.js,upgrade.test.js.
- 101 open-source repositories × 21 main commands + 23 edge-case commands = ~4,400 invocations. 0 crashes, 0 unexpected exit codes.
- Verified post-fix: all 17 previously-failing
doctor --cirepos now pass; vscode/duckdb/ruby/gatsby/elixir leaks are gone; bitcoin/postgres/cabal/flutter/jint/duckdb now get correct stacks instead ofunknown.
Auto-release bumps. No user-visible changes between [0.2.3] and
[0.2.11]; consolidated here rather than keeping empty version headers.
0.2.3 — 2026-04-05
- Shell injection in
pre-commit.js—gate.pathandgate.conditionfromgovernance.mdwere interpolated intocd "..."and[ -e "..." ]without escaping. An adversarial governance file could break out of the shell context. Both values now go throughshellEscapeDoubleQuoted(backslash-first escape order). The wholebash -c '...'body is wrapped withshellEscapeSingleQuoted. - YAML injection in
github-actions.js—gate.pathwas concatenated intoworking-directory:andgate.conditionintohashFiles('...')without escaping. Both now route throughyamlScalar(). ThehashFilesargument additionally has single-quote-doubling ('') for GHA expression syntax. - Path traversal in governance annotations —
parseGovernance()now validatespath:andif:annotation values viaisValidAnnotationPath(). Rejects absolute POSIX paths, Windows drive-letter paths, UNC paths,..segments, newlines, and null bytes. Invalid values are dropped and a warning is recorded. - Husky backslash-ordering fix —
gate.path/gate.conditionin husky hooks are now escaped viashellEscapeDoubleQuotedwhich handles\before"so a trailing backslash cannot eat the closing quote. atomicWritetemp suffix is now crypto-random — previously${pid}.${Date.now()}was predictable. Now usescrypto.randomBytes(8).toString('hex')+ thewxopen flag as a defense-in-depth against symlink races on shared tmpfs.- Stricter
yamlScalar— also quotes strings beginning with YAML flow indicators ([,],{,},,), block-sequence markers (-), tag/complex-key markers (?,!), and control characters. Previously a classification-prefixed name like[OPTIONAL] testcould have been interpreted as a flow sequence. SECURITY.md— published threat model, supported versions, disclosure process.
crag compile --dry-run— preview target output paths without writing files.crag check --json— machine-readable infrastructure report.- Test runner filter —
node test/all.js parse diffruns only matching files. - Structured exit codes —
src/cli-errors.jsexportsEXIT_USER=1andEXIT_INTERNAL=2. Scripts can now distinguish user-recoverable errors from environmental failures. All commands route throughcliError(). - Windows shell handling in
init—spawn('claude', ...)now usesshell: bashon Windows instead of defaulting tocmd.exe, which could not always resolve the claude binary. os.homedir()fallback ininit— crash-hardens against containers/CI where bothHOMEandUSERPROFILEare unset..gitattributes— pins shell scripts, hooks, and YAML to LF so Windows contributors cannot commit CRLF into generated artifacts.- 69 new tests (159 → 228) covering: path-traversal annotation rejection (10), injection regression for pre-commit and github-actions (8),
isTrustedSourcesymlink protection (7),checkcommand logic (6), sharedyaml-runhelper (13),resolveHomeDir,atomicWriteedge cases (5), expandedyamlScalarrules (6), pre-commit + agents-md + cursor-rules + gemini-md compile targets (12).
- GitHub Actions generator — the Python setup step now uses
shell: bashexplicitly so2>/dev/nullredirects work on Windows runners (previously silently failed incmd.exe). extractRunCommands/isGateCommand— moved from duplicated copies inanalyze.jsanddiff.jsinto a sharedsrc/governance/yaml-run.js. Both commands import from the shared module; public exports remain for test compatibility.- Error handling at file I/O boundaries —
init,compile,diff,analyzenow wrapfs.copyFileSync,fs.readFileSync, andfs.writeFileSyncwith try/catch and emit actionable errors viacliErrorinstead of raw Node stack traces. - Parser warnings are surfaced —
compileanddiffprintparsed.warningsto stderr before proceeding, so invalid annotations are visible. - Skill source_hash sync — skill frontmatter
version:fields updated to0.2.2.
0.2.2 — 2026-04-05
- Fully automated release pipeline (
.github/workflows/release.yml). Triggers on every push tomaster. Runs all gates + 159 tests + compile-all smoke test, detects whether thepackage.jsonversion is new, and if so publishes to npm with SLSA provenance, creates the git tag, and creates a GitHub release with notes auto-extracted fromCHANGELOG.md. Zero manual steps between commit and package-on-npm. - Auto skill-hash sync workflow (
.github/workflows/sync-hashes.yml). Recomputessource_hashfrontmatter wheneversrc/skills/*.mdcontent changes. Commits updates asgithub-actions[bot]with[skip ci]to avoid loops. Contributors never manually track hashes. - Version bump helper (
scripts/bump-version.js). One-command semver bump vianpm run release:patch | :minor | :major. Updatespackage.jsonand converts the[Unreleased]CHANGELOG header into a dated version section. Accepts explicit versions too. - Skill hash sync script (
scripts/sync-skill-hashes.js). Reusable CLI:npm run sync-hashes. Reads every skill, computes SHA-256 of body with CRLF normalization, updates frontmatter if drifted. - Maintainer workflow docs in
CONTRIBUTING.mdcovering the three-command release flow and troubleshooting.
- Removed
.github/workflows/publish.yml(the old manual-trigger release workflow).release.ymlreplaces it with full push-driven automation.
bump-version.jsnow inserts a blank line between version sections and uses the maintainer's local date (not UTC date).circuit-breaker.shcounter now lives under.claude/.tmp/instead of/tmp/— avoids stale-state issues on Windows + Git Bash where/tmppersists across sessions.
0.2.1 — 2026-04-05
- README rendering on npm. Replaced 4 mermaid diagrams with ASCII art / markdown tables. npm's markdown renderer doesn't support mermaid, so the diagrams were showing as raw YAML text on the package page. GitHub still renders mermaid natively, but the canonical README is now cross-platform (GitHub, npm, text readers, terminals).
0.2.0 — 2026-04-05
Renamed and expanded. First release under the @whitehatd/crag name.
- Four new commands:
analyze,diff,upgrade,workspace. crag analyze— zero-interview governance generation. Reads CI workflows (recursively, includingrun: |multiline blocks),package.jsonscripts, linter configs (ESLint/Biome/Prettier/Ruff/Clippy/Rustfmt/Mypy/TypeScript), git log for branch/commit patterns, and deployment configs (Docker, k8s, Vercel, Fly, Netlify, Render, Terraform).crag diff— governance vs reality comparison with MATCH/DRIFT/MISSING/EXTRA verdicts, memoized package.json + bin reads, command alias normalization (npm test⇔npm run test,./gradlew⇔gradlew).crag upgrade— version-tracked skill updates. Skills carryversionandsource_hash(SHA-256 CRLF-normalized). Only overwrites unmodified skills unless--force(with timestamped backup).crag workspace— workspace inspector. Prints detected type, root, members, tech stacks per member, governance hierarchy. JSON output mode via--json.- Workspace detection for 11+ types: pnpm, npm/yarn, Cargo, Go, Gradle (kts + groovy), Maven, Nx, Turborepo, Bazel, git submodules, independent nested repos.
- Multi-level governance with
## Gates (inherit: root)marker. Root gates prepended, member gates appended, runtimes deduped. - Governance v2 format (backward-compatible):
### Section (path: dir/)— path-scoped gates (cd before running)### Section (if: file)— conditional sections (skip if file missing)# [MANDATORY]/# [OPTIONAL]/# [ADVISORY]— gate classifications## Gates (inherit: root)— inheritance marker
- 12 compile targets (was 3):
- CI / git hooks:
github,husky,pre-commit - AI agents (native):
agents-md,cursor,gemini - AI agents (additional):
copilot,cline,continue,windsurf,zed,cody
- CI / git hooks:
- Runtime version inference — CI generator reads
package.json engines.node,pyproject.toml requires-python,build.gradle.ktstoolchain,pom.xml maven.compiler.source,go.mod go X.Ydirective instead of hardcoding defaults. - Auto-update system — skills track version + SHA-256 source_hash in YAML frontmatter. CRLF normalization for Windows/Unix portability. Global cache at
~/.claude/crag/update-check.jsonwith 24h TTL. Graceful offline failure. Opt-out viaCRAG_NO_UPDATE_CHECK=1. - 159 tests across 12 test files (was 0). Zero dependencies. Run via
npm testornode test/all.js. - Atomicity — all compile targets use
atomicWrite()(temp file + rename). Partial failures leave old state intact.
- Renamed from
scaffold-clito@whitehatd/crag. npm blocked the unscopedcragname via its short-name similarity policy; scoped package under the user's npm scope is the recommended fallback. - Rebranded tagline to "The bedrock layer for AI coding agents. One governance.md. Any project. Never stale."
- Modular architecture: split 397-line
bin/scaffold.jsinto 24+ modules across 6 directories (commands/,governance/,workspace/,compile/,update/,cli.js). Zero new dependencies. - Post-start skill: added concrete runtime instructions for v2 annotations (
path:,if:, classifications,inherit:). - Pre-start skill: added Section 0.05 (skill currency check) and Section 1.5 (workspace detection).
- Shell injection in
gateToShell()when processingVerify "..."patterns. All interpolated values now escape\,`,$, and". - CRLF hash mismatch — same content now produces identical hashes on Windows and Unix.
- Path traversal in workspace glob expansion.
expandGlobs()now usesfs.realpathSyncand rejects..patterns. - Symlink attack on source skills.
isTrustedSource()requires a regular file insidesrc/skills/. - YAML injection in GitHub Actions compile target. Uses block scalars for
run:andyamlDqEscape()for labels. - YAML injection in frontmatter writes.
yamlScalar()quotes colons, newlines, boolean-like, and number-like strings. - ReDoS in governance parser. 256 KB input cap, line-scan
extractSection()replaces the regex. - HTTPS cleanup — request unref, timeout, 100 KB response cap, atomic cache write.
- Conditional gate shell precedence — now uses
if [ -e f ]; then cmd || exit 1; fiinstead of[ -e f ] && cmd || exit 1which fails when the file is missing. crag upgrade --checkwas not actually dry-run — it was silently writing files. Now honorsdryRunoption.init.jsclaude --versiontimeout (5s) — prevents CLI hang if the binary crashes.init.jspre-flight checks — warns if not a git repo, warns if existinggovernance.mdwould be overwritten, handles subprocess errors gracefully.diff.jsmemoization — singlepackage.jsonread per diff run;node_modules/.binscanned once.mergeGovernance()defensive normalization — never throws on malformed member input.analyze.jsmulti-linerun: |block extraction from GitHub Actions workflows.analyze.jsrecursive workflow walking — finds nested.github/workflows/ci/*.yml.analyze.jsmergeWithExistingpreserves section order — new sections added in their original order from the generated template, not reshuffled.- Windows stderr noise on git commands (
execSyncstdio pipes instead of2>/dev/null).
- Added
sandbox-guard.shstyle hard-blocks at hook level (already existed in scaffold-cli, verified for crag). - Security-reviewer agent gained 4 new checks: shell injection, path traversal, symlink validation, YAML injection.
dependency-scanneragent added for package vulnerability audits (Node, Rust, Python, Go, Java).
- Zero dependencies, Node 18+ required.
- Package
fileswhitelist:bin,src,README.md,LICENSE(excludes.claude/,test/, settings, hooks). - 30 files, 52 KB tarball.
- Published as
@whitehatd/cragon npm registry. - GitHub repo at
github.com/WhitehatD/cragwith 14 topic tags for discoverability.
0.1.0 — 2026-04-03 (pre-rename, as scaffold-cli)
Initial release under the scaffold-cli name.
Initial capabilities: universal skills (pre-start-context, post-start-validation), interview-driven governance generation, 3 compile targets (github, husky, pre-commit), basic workspace support for monorepos via multi-level governance.md.