forge

agent
Guvenlik Denetimi
Basarisiz
Health Uyari
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Low visibility — Only 5 GitHub stars
Code Basarisiz
  • spawnSync — Synchronous process spawning in bin/forge.js
  • rm -rf — Recursive force deletion command in install.sh
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

A reusable agent harness for any repository: test-first ticket cycle, Markdown tracker, typed knowledge base, role agents and the hooks that keep them honest. One forge.json describes the project; forge init installs the rest.

README.md

forge

forge — the cycle a ticket goes through, and the three records behind it

npm
downloads
license
python
node
dependencies
unpacked size

A reusable agent harness for software projects: a six-gate, specification-first
development cycle, a Markdown tracker, a typed knowledge base, agents that
accumulate the rules each project teaches them, and the hooks that keep all of
it honest — installable into any repository in one command.

Install

npx @vstlmkh/forge init --auto      # no install at all
npm install -g @vstlmkh/forge       # or keep `forge` on your PATH

The npm package is a shim: the CLI itself is Python 3.9+ with no dependencies,
exactly like the harness it installs. Node 16+ is only there to carry it.

Prefer no npm in the loop? The shell installer puts one git checkout in
~/.forge and one forge shim in ~/.local/bin:

gh api repos/vstlmkh/forge/contents/install.sh -H "Accept: application/vnd.github.raw" | sh

or, if you would rather clone first:

git clone https://github.com/vstlmkh/forge.git ~/.forge && ~/.forge/install.sh

The repository is private, which rules out the usual
curl … raw.githubusercontent.com/… | sh: raw URLs do not see your git
credentials and answer 404. gh api authenticates over the API, and a plain
git clone over https works through whatever credential helper already holds
your token. Once the repository is public, the short form works too:

curl -fsSL https://raw.githubusercontent.com/vstlmkh/forge/master/install.sh | sh

Re-run the installer any time to update, or run forge self-update — which
knows whether it is looking at a git checkout or an npm install and says the
right thing for each. FORGE_HOME, FORGE_BIN, FORGE_REF and FORGE_REPO
override where it lands, which ref it tracks and where it clones from.

On a machine with several GitHub accounts, gh repo clone and
[email protected]:… both fail with Repository not found: they use the default
ssh key, which belongs to another account. The installer handles it — it tries
https, then [email protected], then every Host alias in ~/.ssh/config whose
HostName is github.com, and tells you which one worked. Nothing ever waits
on a credential prompt, so piping it into sh cannot hang.

Use it in a project

cd /path/to/your/project
forge detect        # what forge thinks this repository is made of
forge init --auto   # install the harness from exactly that, asking nothing

Every command works through npx @vstlmkh/forge … just as well, if you would
rather not install anything.

detect reads .gitmodules, then looks for package.json, pyproject.toml,
composer.json, go.mod, Cargo.toml and pubspec.yaml — including one level
inside a submodule, where deployment repositories usually keep the application.
Out of that come the repositories, the scopes, a stack label and the real test,
lint, type and build commands the project already has. It guesses that those
commands work; forge doctor and you decide whether they do.

forge init without --auto asks instead — it still opens with what it
detected, so the usual answer is "yes, that's right".

Either way it writes forge.json, copies the harness into .claude/, scaffolds
docs/agile/, docs/knowledge/ and docs/lessons/, renders one engineer agent per scope, and
adds a managed block to your CLAUDE.md. Nothing else in the project is
touched.

What you get

Piece What it is
docs/agile/ backlog, task tracker and bug tracker as Markdown with YAML frontmatter; INDEX.md is generated
docs/knowledge/ eight-type knowledge base — business rules, incidents, decisions, contracts — with a generated coverage index
docs/lessons/ what the gates taught: one imperative line per rule, handed to the agent it binds, capped and ranked
.claude/agents/ pm, qa, and one engineer per code scope
.claude/skills/ the operating rules: artifacts, grooming, git, Definition of Done, knowledge, lessons
.claude/commands/ /agile:*, /kb:*, /lessons:*, /forge:doctor
.claude/scripts/ agile.py, kb.py, lessons.py, forge.py and five hooks — stdlib-only Python 3, no dependencies
forge.json the only project-specific file: repositories, scopes, owning agents, and the Definition-of-Done matrix

The cycle it enforces

Four properties are load-bearing, and all four are checked by a script rather
than trusted:

  • Test-first. qa writes a failing test per acceptance criterion and proves
    it red before an engineer starts. There is no todo -> in_progress.
  • The tests are not the implementer's. At the review gate qa diffs the test
    files against its own red commit; a loosened matcher or a deleted assertion is
    a rejection.
  • Nobody closes their own work. An engineer stops at review, qa moves it
    to verify, and only the top-level session sets done.
  • A gap is named, not hidden. SKIPPED, NO-TEST, NO-DOCS and
    NO-LESSON are the four waivers; each one must name what it falls back on,
    and lint refuses a ticket that reaches review having recorded neither a note
    nor a reason.
  • A bounced gate teaches something. A ticket that goes backwards owes a
    rule, filed by whoever took that edge, at the moment they take it. Every agent
    is handed its scope's rules — one line each, capped at a dozen, ranked by how
    often they have mattered — at the start of every gate, and a rule nobody has
    needed in six months is reported as the context cost it has become.

Everything project-specific lives in forge.json

{
  "repos":  { "backend": { "path": "backend", "branch": "master", "submodule": true } },
  "scopes": { "backend": { "repo": "backend", "agent": "backend-engineer",
                           "kb_scope": "backend", "stack": "Laravel 11",
                           "workdir": "backend/app" } },
  "checks": { "backend": [ { "id": "tests", "command": "composer test",
                             "cwd": "backend/app", "available": true } ] }
}

The scripts, skills, agents and commands read it; none of them hardcode a scope,
a branch or a command. That is what makes the same harness fit a one-repository
service and a super-repo with submodules, and what lets the Definition-of-Done
matrix tighten itself: when a bootstrap ticket makes mypy real, flipping
"available": false to true is part of that ticket's acceptance criteria.

python3 .claude/scripts/forge.py scopes        # who implements what, and where
python3 .claude/scripts/forge.py checks api    # the matrix qa is bound by
python3 .claude/scripts/forge.py doctor        # does the config match the repo?

Commands in a project that has the harness

/agile:board            what is going on
/agile:groom <request>  turn a request into tickets
/agile:next             what to work on
/agile:work <ID>        the six gates: spec → tests → implement → validate → document → board
/agile:close <ID>       merge, record the sha, close
/agile:bug <symptom>    file and triage a defect

/kb:consult <subject>   what do we already know?
/kb:new <finding>       file it, correctly typed and cross-linked
/kb:audit               gaps, misfilings, staleness, broken links
/forge:doctor           does the harness still match the repository?

CLI

forge detect [TARGET]    print the shape forge infers, and change nothing
forge init [TARGET]      install — interactively, or --auto, or --preset NAME
forge agents [TARGET]    re-render the per-scope engineer agents from forge.json
forge upgrade [TARGET]   refresh scripts, skills, commands and specs in place
forge doctor [TARGET]    run the installed harness's self-check
forge self-update        pull the newest forge into ~/.forge
forge where              print where forge is installed

upgrade never touches forge.json except to record a policy a new gate needs,
leaves the per-scope engineer agents alone (pass --agents to re-render those
too), and rewrites only the <!-- forge:begin --> block in CLAUDE.md. Running
it twice leaves a zero diff.

Repository layout

forge/
├── install.sh             clones into ~/.forge and links the shim; re-run to update
├── package.json           the npm package: @vstlmkh/forge
├── bin/forge              the CLI: detect, init, agents, upgrade, doctor
├── bin/forge.js           the npm shim that runs it
├── assets/logo.py         the mark -> logo-{light,dark}.svg, favicon.svg
├── assets/banner.py       regenerates the banners; imports the mark
├── template/              the payload that gets copied into a project
│   ├── .claude/           agents, skills, commands, scripts, settings
│   ├── docs/              the tracker, knowledge-base and lessons specifications
│   ├── CLAUDE.harness.md.tmpl
│   └── forge.example.*.json
├── docs/                  how the harness works and how to extend it
├── tests/smoke.sh         installs into a throwaway repo and proves every gate fires
├── CONTRIBUTING.md        how to file an issue and how to change forge itself
└── LICENSE                MIT

Requirements

Python 3.9+ and git — plus Node 16+ only if you install through npm, which uses
it for nothing but the shim. No third-party packages, at install time or
afterwards —
the hooks run on every turn, so the harness refuses to own a dependency tree.
Updating forge never touches a project: a project picks up a new version when
you run forge upgrade in it.

Tests

tests/smoke.sh

Installs into a temporary repository, files a ticket and a note through the
scripts, and asserts that each gate fires: the spec gate, the docs gate, the
lessons gate, the knowledge-base naming guard, the generated-index guard, the
byte-stability of all three indexes, and the one-working-tree rule.

Attribution

forge signs the files it generates — the three INDEX.md boards, the managed
CLAUDE.md block, the rendered engineer agents — with one line and a link:

_Kept by [forge](https://github.com/vstlmkh/forge)._

It signs nothing else. Not a commit, not a pull request, not a ticket, not a
knowledge-base note, not a file anyone on the project wrote. The line is plain
visible text, because the only honest mark to leave in somebody else's
repository is one they can read and delete — and a hidden one in a client
codebase is a liability for whoever installed it.

Turn it off entirely with forge init --no-attribution, or later:

{ "attribution": false }     // in forge.json; regenerate and every instance is gone
python3 .claude/scripts/forge.py credit   # what this project signs with, if anything

Contributing

Issues and pull requests are welcome —
CONTRIBUTING.md is the whole of it. The short version:

  • a bug is forge where, forge version, forge detect . and the shortest
    reproduction that still fails — in a throwaway repository, never a paste of a
    private one;
  • a stack forge does not recognise is the cheapest contribution there is:
    one _<lang>_checks() function and one MANIFESTS entry in bin/forge,
    plus an assertion in tests/smoke.sh;
  • a new rule has to name the failure it prevents, because every rule under
    template/ is one an agent obeys in somebody else's repository forever;
  • nothing in template/ may name a project, a stack, a branch, a scope or a
    command
    — that is what keeps the payload identical everywhere and
    forge upgrade safe;
  • tests/smoke.sh has to pass, and new behaviour needs a new assertion in
    it. A gate nobody tests is a gate that silently stops firing.

Before asking for a feature, check whether it is already a
forge.json edit — most of them are. If it genuinely
cannot be expressed there, that is the feature request worth filing.

Security issues go to [email protected], not to the tracker.

License

MIT — see LICENSE.

That covers everything under template/ too, so the harness a project installs
carries the same terms. Installed files get no licence header: they land in
someone else's repository, and a per-file banner there would be noise.

Yorumlar (0)

Sonuc bulunamadi