feat: usability round — dynamic stack detection, more languages, self-update, quiet CLI, self-dogfood#49
Merged
Conversation
…LI, self-dogfood
Four owner-requested improvements, plus a ReDoS fix found in review.
Tech (dynamic + broader):
- src/stack.js + `forge stack`: detect the repo's REAL stack by reading its
manifests (package.json/pyproject/go.mod/Cargo.toml/Gemfile/composer.json/
pom.xml·gradle/*.csproj) → languages, frameworks, package managers, and the
actual test commands, which now feed substrate's verification checklist.
Data-driven (add a row, not code), fail-safe on every manifest.
- atlas RULES gains Ruby, C#, PHP, Kotlin, Swift, C/C++ (and Java method defs).
One registry; the walk, completion gate, and docs sweep pick each up via
CODE_EXTS. The shared Java/C# method grammar is line-anchored and {0,6}-bounded
after review caught polynomial backtracking (5.2s → 26ms on a pathological
file); a ReDoS regression test pins it.
Auto-update:
- src/update.js + `forge update` (`--check` reports commits-behind-upstream from a
cached hourly fetch; bare applies via ff-only pull, or hands back `npm i -g`).
doctor surfaces a non-nagging notice (FORGE_NO_UPDATE_CHECK=1 silences).
Fail-open on offline / non-git / detached HEAD.
Quiet CLI:
- The `Forge <cmd> —` title line is now behind `--verbose`/FORGE_VERBOSE; commands
emit their result first. The --help/--version banner is unchanged.
Self-dogfood:
- .claude/settings.json wires forgekit's own guards via ${CLAUDE_PROJECT_DIR}, so
the repo runs its own completion gate / cortex / guards in local dev.
Docs (README/GUIDE/ARCHITECTURE) + CHANGELOG updated; `forge docs check` green.
620 tests → 632 (12 new), biome + typecheck clean.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
…ix detection
Two verified findings from the review of this branch:
- HIGH: the C/C++ function regex `^[\w*\s]+?…\{` had the same ReDoS class as
the Java/C# one — `\s` crossed newlines and the lazy run scanned the whole
file from every line start, O(n²). A 445 KB header of prototype declarations
took 13s (and build() runs on the Stop-hook path, so it could freeze a
session). Rewritten line-anchored and linear: ≤4 whitespace-separated type
tokens + name + `(args){` with args excluding `;{}` and newlines. Requiring a
same-line brace also correctly rejects prototypes. 13s → 13ms; regression test
added (12k-declaration header must build < 1s).
- LOW: `forge stack` never detected Remix — the scoped signature `@remix-run/`
was matched with exact array `.includes`, which can't equal `@remix-run/react`.
Node signatures now match exact-or-`@scope/`-prefix, which also avoids the
`preact`→React / `next-auth`→Next.js false positives a naive substring match
would introduce. Regression test pins both directions.
The reviewer confirmed the rest fail-open: update.js (offline/non-git/detached
HEAD/dirty-tree pull), stack.js (string/array deps, monorepo, corrupt manifest),
the quiet-CLI refactor (no command reduced to silence), and the dogfood settings.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Four day-to-day usability gaps the owner hit, plus a ReDoS fix caught in review. Standing directive: dynamic & smart over static hardcoded lists.
existsSync(package.json).forge stack(src/stack.js) reads the repo's real dependency manifests (package.json,pyproject.toml,go.mod,Cargo.toml,Gemfile,composer.json,pom.xml/build.gradle,*.csproj) → languages, frameworks, package managers, and the actual test commands, which now feed the substrate's verification checklist instead of assuming npm. Data-driven (extend by a row), fail-safe on every manifest.RULEStable; the walk, completion gate, and docs sweep pick each up viaCODE_EXTS.forge update(src/update.js):--checkreports commits-behind-upstream (cached hourly fetch); bare applies (git pull --ff-onlyfor a checkout, or thenpm i -gcommand).forge doctorshows a non-nagging notice (FORGE_NO_UPDATE_CHECK=1silences). Fail-open on offline / non-git / detached HEAD.Forge <cmd> —title line is now behind--verbose/FORGE_VERBOSE; commands emit their result first. The--help/--versionbanner is unchanged..claude/settings.jsonwires forgekit's own guards via${CLAUDE_PROJECT_DIR}, so the repo runs its own completion gate / cortex / guards in local dev.Checklist
npm testpasses (Node 18/20/22) — 632 tests, 630 pass / 2 skipped, 12 newnpm run checkpasses (Biome lint + format)feat:/fix:/docs:…)CHANGELOG.mdupdated under## [Unreleased]forge substrate,forge impact, router/gate, or MCP substrate tools — GUIDE (forge stack / forge update sections, env rows), ARCHITECTURE, README;forge docs checkpassesRisk & rollback
forge updateand the doctor notice are fail-open (offline/non-git/detached-HEAD return "unknown", never error); the quiet-CLI change is cosmetic and reversible withFORGE_VERBOSE=1.public static public static …: 5.2s). Rewritten line-anchored +{0,6}-bounded → 26ms, with a regression test. These regexes run over every file in a repo, so this mattered.FORGE_VERBOSE=1(restore titles),FORGE_NO_UPDATE_CHECK=1(silence the notice), delete.claude/settings.json(un-dogfood).Extra checks (tick if applicable)
npm run typecheckpasses🤖 Generated with Claude Code
https://claude.ai/code/session_019PXuKmJp92Gdo2FudNjSx2
Generated by Claude Code