Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,21 @@ an **MCP server** for Roo Code and VS Code.
| **OpenClaw** | execution-folder `AGENTS.md` as project context; MCP registry is global | Rely on root `AGENTS.md`; write an OpenClaw-shaped `.openclaw/mcp.json` the operator applies with one `openclaw mcp add` |

Roo Code and VS Code receive the Forge MCP server via `forge init`
(`.roo/mcp.json`, `.vscode/mcp.json`) rather than a rules file.
(`.roo/mcp.json`, `.vscode/mcp.json`) rather than a rules file — like every per-tool file,
only for tools the repo uses (detected, or `forge init --tools`); the set is recorded in
`.forge/forge.config.json` so `forge sync` emits the same targets.

`AGENTS.md` is shared with people, so forge owns only a marked block in it
(`<!-- forge:begin -->` … `<!-- forge:end -->`). Sync appends that block to a hand-written
file and afterwards compares and rewrites only the block; the Stop-hook auto-sync does the
same and never adopts a file without one. A pre-block, fully generated `AGENTS.md` is
recognised by the hash in its header and converted to a block keeping any text a person
added around it; only one edited inside its generated text needs a full rewrite, which
`forge sync` does after saving a timestamped `AGENTS.md.forge-bak-<time>`. A body line that
reads exactly like a marker (a multi-line rule, fact or lesson) is indented one space so it
cannot end the block early. The Codex/Windsurf size checks measure the whole file, the
person's text included. Sync and doctor warn while an `AGENTS.md.forge-bak` from an older
forge still holds text AGENTS.md lacks, since no agent reads it.

### OpenClaw: what is automatic and what is not

Expand Down
43 changes: 43 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,49 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Fixed

- **`forge init` / `forge sync` no longer replace a hand-written `AGENTS.md`, and the Stop-hook
auto-sync no longer reverts human edits.** Forge now owns only a marked block
(`<!-- forge:begin -->` … `<!-- forge:end -->`): sync appends it to an existing file and
afterwards compares and rewrites only that block; auto-sync does the same and never adopts
a file without one. An `AGENTS.md` generated whole by an older version converts to a block
on the next sync, keeping any text added above or below the generated part (verified by
the hash in its header). If the generated text itself was edited, `forge sync` saves the
old file as a timestamped `AGENTS.md.forge-bak-<time>` first, instead of overwriting one
fixed `.forge-bak`. `forge doctor` reports a hand-written file as "no Forge block" and its
fix appends the block.
- **Rules an older version moved to `AGENTS.md.forge-bak` are no longer forgotten.** No agent
reads that file, so `forge sync` and `forge doctor` now warn for as long as it holds text
that `AGENTS.md` lacks, even when the Stop hook did the conversion out of sight.
- **Size checks cover the whole `AGENTS.md`.** The Codex (32 KiB) and Windsurf (~12k
characters) checks now count your text as well as Forge's block, and sync warns when your
text pushes the file over budget, since those tools drop the end of the file first. A rule,
fact or lesson containing a line that reads exactly like a block marker can no longer end
the block early.
- **Notes added under a generated `CLAUDE.md` header survive later syncs.** Sync refreshes
only the marker line instead of regenerating the file.

### Added

- **`forge init --tools <list|all>` chooses the agent tools a repo emits config for.** The
choice is recorded in `.forge/forge.config.json` (`tools`), and later `forge sync`,
`forge doctor --fix` and `forge integrations add` emit the same set.

### Changed

- **`forge init` emits config only for the tools a repo uses by default:** Claude Code plus
every tool with a sign on disk (`.cursor/`, `.codex/`, `.github/copilot-instructions.md`,
…). A repo with no recorded set still gets every tool on sync; `--tools all` restores the
old init behaviour.
- **`forge integrations add` writes to, and takes ownership in, only the recorded tools' MCP
config** (its dry run lists the files). A tool added to the set later gets the recorded
servers on that run and Forge owns those copies, while a same-name entry you configured
for that tool yourself stays yours: it is never overwritten or removed.
- **`forge tools <name>` adds the tool to a recorded set that lacks it**, so the primary tool
gets its own config. `forge tools --reset` now clears only the primary tool and keeps the
set.

## [1.3.2] - 2026-09-24

### Fixed
Expand Down
20 changes: 13 additions & 7 deletions ONBOARDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ start paying off on day two.
```mermaid
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#201a15','primaryTextColor':'#f2ede7','primaryBorderColor':'#372c22','lineColor':'#f26430','secondaryColor':'#272019','tertiaryColor':'#171310','edgeLabelBackground':'#201a15','clusterBkg':'#171310','clusterBorder':'#4a3b2e','fontFamily':'ui-sans-serif, system-ui, sans-serif','fontSize':'14px'},'flowchart':{'curve':'basis','padding':10,'nodeSpacing':36,'rankSpacing':44}}}%%
flowchart TD
I["forge init"] --> Cfg["every tool configured<br/>from one source"]
I["forge init"] --> Cfg["your tools configured<br/>from one source"]
Cfg --> Work["you work as usual"]
Work --> Gate["substrate checks each task:<br/>ask first? · which model? · what breaks?"]
Gate --> Edit["agent edits, with guardrails"]
Expand Down Expand Up @@ -44,16 +44,22 @@ Full matrix (no-registry `github:` install, symlink dev setup) →
## 2. Configure a repo (once per repo)

One config for every tool. Author your rules once; `forge init` emits each tool's
native file.
native file — for the tools this repo uses.

```bash
cd ~/your-project
forge init # emits AGENTS.md, CLAUDE.md, .gemini/settings.json, .aider.conf.yml …
forge init # AGENTS.md + CLAUDE.md + .mcp.json, plus each tool it detects
forge init --tools all # or pick: --tools claude,cursor,gemini (recorded for later syncs)
```

Now Claude Code, Codex, Cursor, Gemini, Aider, Copilot, Windsurf, Zed, Continue, and
OpenClaw all read the **same** rules — each from its own native file (plus MCP server
config for Roo Code and VS Code).
With `--tools all`, Claude Code, Codex, Cursor, Gemini, Aider, Copilot, Windsurf, Zed,
Continue, and OpenClaw all read the **same** rules — each from its own native file (plus
MCP server config for Roo Code and VS Code). Without it, init emits Claude Code's files and
those of any tool the repo already shows (`.cursor/`, `.codex/`,
`.github/copilot-instructions.md`, …); AGENTS.md-reading tools get the rules regardless.

Already have an `AGENTS.md`? It is kept: Forge appends its rules between
`<!-- forge:begin -->` and `<!-- forge:end -->` and only ever rewrites that block.

On OpenClaw the rules arrive automatically (it reads the execution folder's `AGENTS.md`
as project context), but the MCP server is a deliberate one-command step, because
Expand All @@ -72,7 +78,7 @@ Change a rule later by editing `source/rules.json` (or dropping a per-repo
`.forge/rules.json`), then:

```bash
forge sync # recompiles into every tool; idempotent (only rewrites what changed)
forge sync # recompiles into each selected tool; idempotent (only rewrites what changed)
```

## 3. Use the cognitive substrate
Expand Down
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ without corresponding public evidence.

```bash
npm install -g @codewithjuber/forgekit # or: npm install -g github:CodeWithJuber/forgekit
forge init # emit native configuration from one source
forge init # emit native config for the tools this repo uses
forge doctor # verify providers, hooks, and MCP wiring
```

Expand Down Expand Up @@ -388,6 +388,15 @@ forge doctor --fix
Forgekit-managed entries. The implementation preserves unrelated entries and creates a
timestamped backup before changing the file.

`forge init` emits configuration only for the agent tools the repository already uses:
Claude Code plus any tool with a sign on disk (`.cursor/`, `.codex/`,
`.github/copilot-instructions.md`, and so on). Choose explicitly with
`forge init --tools claude,cursor` or `--tools all`; the choice is recorded in
`.forge/forge.config.json`, so later `forge sync` runs emit the same set. In `AGENTS.md`,
Forgekit owns only the block between `<!-- forge:begin -->` and `<!-- forge:end -->`. A
hand-written `AGENTS.md` keeps every line and gets the block appended; `forge sync` and the
Stop-hook auto-sync rewrite that block and nothing else.

For an explicit model provider, inspect or update configuration with `forge config`. API keys
remain environment variables; Forgekit's provider file stores the environment-variable name,
not the secret value.
Expand All @@ -400,7 +409,7 @@ and output live in [`docs/GUIDE.md`](docs/GUIDE.md).
<!-- forge:render:commands-table:begin (generated by `forge docs render` — do not edit) -->
| Group | Command | Does |
| ----------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Core** | `forge init` | scaffold this repo's config — emits every tool from one shared source |
| **Core** | `forge init` | scaffold this repo's config — emits the tools it uses (Claude + detected, or --tools) from one shared source |
| | `forge sync` | recompile the canonical source into each tool's native config files |
| | `forge doctor` | health-check installed tools, guards, MCP auth, and config drift |
| | `forge tools` | primary-tool config — gitignore secondary-tool artifacts (.cursor/.gemini/…) for tools this repo doesn't use (`forge tools <name>` sets it, `--reset` clears) |
Expand Down
Loading
Loading