@ipul-labs/forge 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +273 -0
- package/bin/README.md +210 -0
- package/bin/cli/analyze.js +516 -0
- package/bin/cli/apply.js +264 -0
- package/bin/cli/cifix.js +300 -0
- package/bin/cli/close.js +125 -0
- package/bin/cli/doctor.js +161 -0
- package/bin/cli/init.js +306 -0
- package/bin/cli/ink.js +57 -0
- package/bin/cli/issue.js +116 -0
- package/bin/cli/issues.js +155 -0
- package/bin/cli/merge.js +175 -0
- package/bin/cli/refine.js +253 -0
- package/bin/cli/repos.js +91 -0
- package/bin/cli/resolution.js +126 -0
- package/bin/cli/session.js +230 -0
- package/bin/cli/sessionStore.js +214 -0
- package/bin/cli/ship.js +762 -0
- package/bin/cli/utils.js +145 -0
- package/bin/cli/validate.js +280 -0
- package/bin/cli/watch.js +274 -0
- package/bin/forge-agent.js +174 -0
- package/dist/assets/index-CNTCMbW9.js +80 -0
- package/dist/assets/index-InpYS-zg.css +1 -0
- package/dist/favicon.svg +8 -0
- package/dist/index.html +19 -0
- package/dist-lib/favicon.svg +8 -0
- package/dist-lib/index.d.ts +1 -0
- package/dist-lib/style.css +1 -0
- package/dist-lib/ui.d.ts +2 -0
- package/dist-lib/ui.js +7390 -0
- package/dist-lib/views/Forge/ForgeDashboard.d.ts +5 -0
- package/dist-lib/views/Forge/activeJobs.d.ts +29 -0
- package/dist-lib/views/Forge/analysisCache.d.ts +64 -0
- package/dist-lib/views/Forge/api.d.ts +4 -0
- package/dist-lib/views/Forge/components/AnalysisProgress.d.ts +13 -0
- package/dist-lib/views/Forge/components/CITerminal.d.ts +44 -0
- package/dist-lib/views/Forge/components/DiffViewer.d.ts +37 -0
- package/dist-lib/views/Forge/components/ForgeConnect.d.ts +6 -0
- package/dist-lib/views/Forge/components/IssueList.d.ts +28 -0
- package/dist-lib/views/Forge/components/MRStatus.d.ts +9 -0
- package/dist-lib/views/Forge/components/NewTaskModal.d.ts +1 -0
- package/dist-lib/views/Forge/components/OpenMRList.d.ts +11 -0
- package/dist-lib/views/Forge/components/PipelineStatus.d.ts +12 -0
- package/dist-lib/views/Forge/components/PipelinesList.d.ts +9 -0
- package/dist-lib/views/Forge/components/RolloutStatus.d.ts +5 -0
- package/dist-lib/views/Forge/components/UsageWidget.d.ts +8 -0
- package/dist-lib/views/Forge/components/ValidationPanel.d.ts +22 -0
- package/dist-lib/views/Forge/context/ForgeProvider.d.ts +23 -0
- package/dist-lib/views/Forge/hooks/useConfig.d.ts +54 -0
- package/dist-lib/views/Forge/hooks/useForgeDashboard.d.ts +107 -0
- package/dist-lib/views/Forge/hooks/useForgeQuota.d.ts +22 -0
- package/dist-lib/views/Forge/phases/AnalyzingView.d.ts +1 -0
- package/dist-lib/views/Forge/phases/IdleView.d.ts +1 -0
- package/dist-lib/views/Forge/phases/MonitoringIssueTab.d.ts +1 -0
- package/dist-lib/views/Forge/phases/MonitoringPipelineTab.d.ts +1 -0
- package/dist-lib/views/Forge/phases/MonitoringView.d.ts +1 -0
- package/dist-lib/views/Forge/phases/ReviewingView.d.ts +1 -0
- package/dist-lib/views/Forge/phases/SelectedIssueTab.d.ts +11 -0
- package/dist-lib/views/Forge/phases/SelectedMRTab.d.ts +1 -0
- package/dist-lib/views/Forge/phases/SelectedView.d.ts +1 -0
- package/dist-lib/views/Forge/phases/shared/CloseIssueConfirm.d.ts +1 -0
- package/dist-lib/views/Forge/phases/shared/DetailTabs.d.ts +14 -0
- package/dist-lib/views/Forge/phases/shared/EnvironmentsPanel.d.ts +9 -0
- package/dist-lib/views/Forge/phases/shared/ForgeActivity.d.ts +1 -0
- package/dist-lib/views/Forge/phases/shared/IssueHeaderBlock.d.ts +13 -0
- package/dist-lib/views/Forge/phases/shared/MergedMRList.d.ts +4 -0
- package/dist-lib/views/Forge/phases/shared/PreviousAnalyses.d.ts +1 -0
- package/dist-lib/views/Forge/phases/shared/ResolutionCheckPanel.d.ts +6 -0
- package/dist-lib/views/Forge/settings/ConnectionRow.d.ts +16 -0
- package/dist-lib/views/Forge/settings/ConnectionsSection.d.ts +7 -0
- package/dist-lib/views/Forge/settings/DefaultsSection.d.ts +7 -0
- package/dist-lib/views/Forge/settings/ReposSection.d.ts +7 -0
- package/dist-lib/views/Forge/settings/SettingsView.d.ts +1 -0
- package/dist-lib/views/Forge/shell/ConfigBar.d.ts +1 -0
- package/dist-lib/views/Forge/shell/ForgeRouter.d.ts +9 -0
- package/dist-lib/views/Forge/shell/ForgeShell.d.ts +7 -0
- package/dist-lib/views/Forge/shell/Sidebar.d.ts +1 -0
- package/dist-lib/views/Forge/shell/SidebarFooterMenu.d.ts +1 -0
- package/dist-lib/views/Forge/shell/SidebarNav.d.ts +1 -0
- package/dist-lib/views/Forge/shell/SidebarNavItem.d.ts +10 -0
- package/dist-lib/views/Forge/shell/TopBar.d.ts +5 -0
- package/dist-lib/views/Forge/types.d.ts +235 -0
- package/dist-lib/views/Forge/utils.d.ts +11 -0
- package/package.json +88 -0
- package/server/forge/core/ForgeAgent.js +1144 -0
- package/server/forge/core/agentClient.js +36 -0
- package/server/forge/core/branchName.js +41 -0
- package/server/forge/core/claudeClient.js +356 -0
- package/server/forge/core/configStore.js +214 -0
- package/server/forge/core/gitlabClient.js +340 -0
- package/server/forge/core/jobs.js +180 -0
- package/server/forge/core/k8s.js +54 -0
- package/server/forge/core/localRepo.js +136 -0
- package/server/forge/core/openclawClient.js +125 -0
- package/server/forge/core/prompts.js +369 -0
- package/server/forge/core/providers/azuredevops.js +408 -0
- package/server/forge/core/providers/base.js +208 -0
- package/server/forge/core/providers/github.js +349 -0
- package/server/forge/core/providers/gitlab.js +529 -0
- package/server/forge/core/providers/index.js +47 -0
- package/server/forge/core/quotaClient.js +101 -0
- package/server/forge/core/validator/attribute.js +84 -0
- package/server/forge/core/validator/clone.js +91 -0
- package/server/forge/core/validator/cmd.js +98 -0
- package/server/forge/core/validator/fs.js +9 -0
- package/server/forge/core/validator/overlay.js +52 -0
- package/server/forge/core/validator/projectType.js +87 -0
- package/server/forge/core/validator/runners/go.js +107 -0
- package/server/forge/core/validator/runners/node.js +84 -0
- package/server/forge/core/validator/tdd.js +105 -0
- package/server/forge/core/validator.js +166 -0
- package/server/forge/routes.js +1012 -0
package/README.md
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
# Forge by iPuL
|
|
2
|
+
|
|
3
|
+
AI-powered code change & deploy control panel. Connect an issue tracker, let Claude propose a fix, review the diff, approve — and Forge creates the branch, commits the changes, opens the MR/PR, and monitors the CI pipeline.
|
|
4
|
+
|
|
5
|
+
Built on: Claude Code CLI · GitLab / GitHub / Azure DevOps · Kubernetes
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Why Forge
|
|
10
|
+
|
|
11
|
+
**The CI refinement loop is the thing.** Every other AI coding tool hands off after the PR is open. Forge keeps going: when your pipeline fails, it grabs the last 150 lines of the failed job log, feeds them back to Claude with the original fix context, generates a targeted patch, and commits it to the branch — automatically. No human has to read the stack trace, translate it into a prompt, and paste it somewhere. The loop closes itself.
|
|
12
|
+
|
|
13
|
+
Everything else fills in the gaps that matter for real teams:
|
|
14
|
+
|
|
15
|
+
- **No per-token cost** — Claude runs via the `claude` CLI using your existing Claude subscription, not API credits. Heavy use doesn't trigger a bill.
|
|
16
|
+
- **Multi-provider** — GitLab, GitHub, and Azure DevOps are all first-class. Switch providers with a single env var; all normalized data shapes stay the same.
|
|
17
|
+
- **Self-hosted** — your code never leaves your infrastructure. The backend runs wherever you deploy it; AI calls go to Anthropic (or a local gateway via OpenClaw).
|
|
18
|
+
- **Two-pass analysis keeps context focused** — Claude first identifies the 6 most relevant files, then reads only those when proposing the fix. This produces sharper diffs than dumping the whole repo into one prompt.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## How it works
|
|
23
|
+
|
|
24
|
+
1. **Connect** — enter your Forge token to authenticate
|
|
25
|
+
2. **Pick an issue** — Forge loads open issues from your project
|
|
26
|
+
3. **Analyze** — Claude reads the repo file tree, identifies relevant files, and proposes a targeted fix
|
|
27
|
+
4. **Review** — inspect the diff file-by-file; refine with natural-language feedback if needed
|
|
28
|
+
5. **Apply** — Forge creates a branch, commits all changes, and opens a merge/pull request
|
|
29
|
+
6. **Monitor** — watch the CI pipeline run; if it fails, click "Fix with AI" to iterate
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
cp .env.example .env
|
|
37
|
+
# fill in FORGE_TOKEN plus your provider credentials (see Configuration below)
|
|
38
|
+
|
|
39
|
+
npm install
|
|
40
|
+
npm run dev
|
|
41
|
+
# open http://localhost:5000
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Prerequisites
|
|
45
|
+
|
|
46
|
+
- Node.js 20+
|
|
47
|
+
- `claude` CLI installed and authenticated (`claude auth login`)
|
|
48
|
+
- Credentials for your SCM provider (see below)
|
|
49
|
+
|
|
50
|
+
### Headless / CLI
|
|
51
|
+
|
|
52
|
+
The `forge-agent` bin drives the same orchestrator from the terminal — one command takes an issue all the way to production:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
forge-agent ship 42
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
…analyze → review → validate → apply → watch CI → merge → watch deploy → close, with a `y/N` gate at every state-changing step. See [`bin/README.md`](./bin/README.md) for a quick start, [`docs/cli.md`](./docs/cli.md) for the full command reference, and [`docs/cli-ship-workflow.md`](./docs/cli-ship-workflow.md) for the workflow design.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
### Core
|
|
65
|
+
|
|
66
|
+
| Variable | Required | Description |
|
|
67
|
+
|---|---|---|
|
|
68
|
+
| `FORGE_TOKEN` | ✅ | Dashboard password — users enter this to access Forge |
|
|
69
|
+
| `SCM_PROVIDER` | — | `gitlab` (default) · `github` · `azuredevops` |
|
|
70
|
+
| `FORGE_REPOS` | — | Comma-separated repo list for multi-repo support |
|
|
71
|
+
| `ANTHROPIC_API_KEY` | — | Enables live model list from Anthropic; falls back to hardcoded list |
|
|
72
|
+
| `FORGE_MODEL` | — | Override default model (default: `claude-sonnet-4-6`) |
|
|
73
|
+
| `VITE_FORGE_TOKEN` | — | Baked into the UI — skips the token entry form on load |
|
|
74
|
+
| `K8S_CLUSTER_TOKEN` | — | K8s service account token for rollout monitoring |
|
|
75
|
+
| `K8S_CLUSTER_SERVER` | — | K8s API server URL |
|
|
76
|
+
| `PORT` | — | HTTP server port (default: `5001`) |
|
|
77
|
+
| `OPENCLAW_GATEWAY_URL` | — | Enables OpenClaw agent backend; point at your local Gateway |
|
|
78
|
+
| `OPENCLAW_TOKEN` | — | Bearer token for OpenClaw Gateway auth |
|
|
79
|
+
|
|
80
|
+
### GitLab (`SCM_PROVIDER=gitlab`, default)
|
|
81
|
+
|
|
82
|
+
| Variable | Required | Description |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `FORGE_GITLAB_PROJECT` | ✅ | Default project path, e.g. `group/repo` |
|
|
85
|
+
| `GITLAB_TOKEN` | ✅ | Personal access token with `api` + `write_repository` scopes |
|
|
86
|
+
|
|
87
|
+
### GitHub (`SCM_PROVIDER=github`)
|
|
88
|
+
|
|
89
|
+
| Variable | Required | Description |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| `GITHUB_TOKEN` | ✅ | Personal access token with `repo` + `workflow` scopes |
|
|
92
|
+
| `GITHUB_OWNER` | ✅ | Organization or user, e.g. `ipul-labs` |
|
|
93
|
+
| `GITHUB_REPO` | ✅ | Repository name, e.g. `web-app` |
|
|
94
|
+
| `GITHUB_BASE_BRANCH` | — | Default target branch (default: `main`) |
|
|
95
|
+
|
|
96
|
+
### Azure DevOps (`SCM_PROVIDER=azuredevops`)
|
|
97
|
+
|
|
98
|
+
| Variable | Required | Description |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| `AZURE_DEVOPS_TOKEN` | ✅ | Personal access token (Full access or Code + Work Items) |
|
|
101
|
+
| `AZURE_DEVOPS_ORG` | ✅ | Organization name, e.g. `ipul-labs` |
|
|
102
|
+
| `AZURE_DEVOPS_PROJECT` | ✅ | Team project name, e.g. `web-app` |
|
|
103
|
+
| `AZURE_DEVOPS_REPO` | — | Git repo name (defaults to project name) |
|
|
104
|
+
| `AZURE_DEVOPS_BASE_BRANCH` | — | Default target branch (default: `main`) |
|
|
105
|
+
|
|
106
|
+
See `.env.example` for a full annotated list.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Multi-provider support
|
|
111
|
+
|
|
112
|
+
Forge's SCM layer is a clean provider abstraction — all three providers implement the same `ScmProvider` interface and return identical normalized shapes (`NormalIssue`, `NormalMR`, `NormalPipeline`, etc.). The rest of the codebase never knows which provider is active.
|
|
113
|
+
|
|
114
|
+
### Switching providers
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# .env
|
|
118
|
+
SCM_PROVIDER=github
|
|
119
|
+
GITHUB_TOKEN=ghp_...
|
|
120
|
+
GITHUB_OWNER=my-org
|
|
121
|
+
GITHUB_REPO=my-repo
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Per-repo prefix (multi-repo mixed-provider setups)
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
FORGE_REPOS=gitlab:ipul/web-app,github:my-org/mobile
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### Provider capabilities
|
|
131
|
+
|
|
132
|
+
| Feature | GitLab | GitHub | Azure DevOps |
|
|
133
|
+
|---|---|---|---|
|
|
134
|
+
| Issues / Work Items | ✅ | ✅ | ✅ (Work Items) |
|
|
135
|
+
| Multi-file commits | ✅ | ✅ (Git Data API) | ✅ (Pushes API) |
|
|
136
|
+
| Merge / Pull Requests | ✅ | ✅ | ✅ |
|
|
137
|
+
| CI pipelines | ✅ GitLab CI | ✅ GitHub Actions | ✅ Azure Pipelines |
|
|
138
|
+
| Job log traces | ✅ | ✅ | ✅ |
|
|
139
|
+
| Server-side rebase | ✅ | — | — |
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Using as an npm package
|
|
144
|
+
|
|
145
|
+
Mount the Forge Express router alongside your own app:
|
|
146
|
+
|
|
147
|
+
```js
|
|
148
|
+
import express from "express";
|
|
149
|
+
import forgeRouter from "forge-agent";
|
|
150
|
+
|
|
151
|
+
const app = express();
|
|
152
|
+
app.use("/api/forge", express.json(), forgeRouter);
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
The router reads all config from `process.env` — no constructor arguments needed.
|
|
156
|
+
|
|
157
|
+
### Available exports
|
|
158
|
+
|
|
159
|
+
```js
|
|
160
|
+
import forgeRouter from "forge-agent"; // Express router
|
|
161
|
+
import { ForgeAgent } from "forge-agent/agent"; // Core pipeline class
|
|
162
|
+
import { createProvider } from "forge-agent/providers"; // SCM provider factory
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### `ForgeAgent`
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
const agent = new ForgeAgent({ project: "group/repo" });
|
|
169
|
+
|
|
170
|
+
// Analyze an issue and stream progress events
|
|
171
|
+
const result = await agent.analyzeIssue(issueIid, (event) => {
|
|
172
|
+
console.log(event); // { type: "progress" | "result" | "error" | "usage", ... }
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
// Apply the analysis: creates branch + commit + MR/PR
|
|
176
|
+
const { branchName, mr } = await agent.applyFix(result);
|
|
177
|
+
|
|
178
|
+
// Refine with reviewer feedback
|
|
179
|
+
await agent.refineIssue(issueIid, result.changes, "use the existing logger utility");
|
|
180
|
+
|
|
181
|
+
// Push to an existing branch (for CI fixes)
|
|
182
|
+
await agent.commitToBranch(branchName, result);
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### `createProvider`
|
|
186
|
+
|
|
187
|
+
```js
|
|
188
|
+
import { createProvider } from "forge-agent/providers";
|
|
189
|
+
|
|
190
|
+
const provider = createProvider("github:my-org/my-repo");
|
|
191
|
+
|
|
192
|
+
const issues = await provider.listOpenIssues();
|
|
193
|
+
const mr = await provider.getMR(42);
|
|
194
|
+
const diffs = await provider.getMRDiffs(42);
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Production deployment
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
npm run build # builds Vite SPA → dist/
|
|
203
|
+
NODE_ENV=production node server.js
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Or with Docker:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
docker build -t forge .
|
|
210
|
+
docker run -p 5001:5001 --env-file .env forge
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Architecture
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
server/
|
|
219
|
+
forge/
|
|
220
|
+
routes.js # Express router — all /api/forge/* endpoints
|
|
221
|
+
core/
|
|
222
|
+
ForgeAgent.js # Orchestrates the full pipeline (analyze → apply → refine)
|
|
223
|
+
claudeClient.js # Shells out to the claude CLI for structured output
|
|
224
|
+
openclawClient.js # OpenClaw Gateway HTTP client
|
|
225
|
+
agentClient.js # Dispatcher: routes to claudeClient or openclawClient
|
|
226
|
+
gitlabClient.js # Legacy shim (kept for backward compatibility)
|
|
227
|
+
k8s.js # Kubernetes client for rollout monitoring
|
|
228
|
+
providers/
|
|
229
|
+
base.js # Abstract ScmProvider — normalized shapes + interface
|
|
230
|
+
gitlab.js # GitLab REST API v4
|
|
231
|
+
github.js # GitHub REST API v3 + Git Data API
|
|
232
|
+
azuredevops.js # Azure DevOps REST API
|
|
233
|
+
index.js # createProvider() factory
|
|
234
|
+
|
|
235
|
+
src/
|
|
236
|
+
views/Forge/
|
|
237
|
+
ForgeDashboard.tsx # Root UI component with tabbed issue/MR views
|
|
238
|
+
api.ts # Token management + fetch helper
|
|
239
|
+
types.ts # Shared TypeScript types
|
|
240
|
+
utils.ts # SSE helper + state utilities
|
|
241
|
+
components/
|
|
242
|
+
AnalysisProgress.tsx # Streaming progress display (analyze + ci-fix modes)
|
|
243
|
+
PipelineStatus.tsx # CI pipeline + per-job log traces
|
|
244
|
+
MRStatus.tsx # MR conflict/rebase banner + inline diff viewer
|
|
245
|
+
OpenMRList.tsx # All open Forge MRs with pipeline badges
|
|
246
|
+
hooks/
|
|
247
|
+
useForgeDashboard.ts # All state, phase transitions, and API calls
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Two-pass analysis
|
|
251
|
+
|
|
252
|
+
**Pass 1** — `identifyRelevantFiles`: Claude reads the issue + file tree, returns the max-6 most relevant paths.
|
|
253
|
+
|
|
254
|
+
**Pass 2** — `proposeFix`: Claude reads the actual file contents and proposes a targeted fix as a JSON diff.
|
|
255
|
+
|
|
256
|
+
Both passes use `claude --print --output-format json` so cost and service tier are tracked automatically.
|
|
257
|
+
|
|
258
|
+
### CI refinement
|
|
259
|
+
|
|
260
|
+
When a pipeline fails, Forge fetches the last 150 lines of each failed job's trace log and feeds them to pass 2 with an explicit "pipeline failed" framing — not generic reviewer feedback. This improves fix quality for common failures like lint errors and type errors.
|
|
261
|
+
|
|
262
|
+
### Provider abstraction
|
|
263
|
+
|
|
264
|
+
All three SCM providers implement `ScmProvider` from `providers/base.js`. The contract is:
|
|
265
|
+
- **Normalized return types** — all methods return `NormalIssue`, `NormalMR`, `NormalPipeline`, etc., regardless of provider
|
|
266
|
+
- **Instance-scoped** — each provider is instantiated with a repo string; no global state
|
|
267
|
+
- **`supportsRebase`** — providers that don't support server-side rebase return `false`; the UI and API layer check this before showing the rebase button
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## License
|
|
272
|
+
|
|
273
|
+
MIT
|
package/bin/README.md
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# `forge-agent` — CLI
|
|
2
|
+
|
|
3
|
+
> Type an issue, accept the suggested fix, and watch it merge to production. One command.
|
|
4
|
+
|
|
5
|
+
`forge-agent` is the headless half of [Forge](../README.md). Same orchestrator the web UI uses, no browser required.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g forge-agent
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or run from a checkout without installing:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
node bin/forge-agent.js <command>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
You'll need:
|
|
22
|
+
|
|
23
|
+
- **Node.js 20+**
|
|
24
|
+
- **`claude` CLI** installed and authenticated (`claude auth login`)
|
|
25
|
+
- A **GitLab / GitHub / Azure DevOps** personal access token
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## First-time setup
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
forge-agent init # interactive wizard — writes .env + ~/.forge/config.json
|
|
33
|
+
forge-agent doctor # confirm node, git, claude CLI, token, and config are all ready
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
`init` walks you through:
|
|
37
|
+
|
|
38
|
+
1. `FORGE_TOKEN` (a generated default — accept with Enter)
|
|
39
|
+
2. `PORT` (only matters if you also want the web UI)
|
|
40
|
+
3. SCM provider (gitlab / github / azuredevops, arrow keys)
|
|
41
|
+
4. Primary repo, then **add another?** (loop to add secondaries — needed for cross-repo features)
|
|
42
|
+
5. SCM token (masked input)
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## The headline command
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
forge-agent ship <iid>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Walks an issue from "open ticket" to "deployed in production" in one command, pausing for `y/N` at every step that changes shared state:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
ship <iid>
|
|
56
|
+
├─ analyze (or load cached if you've already analysed)
|
|
57
|
+
├─ review proposal (per-file diff + summary + divergence warnings)
|
|
58
|
+
├─ ?accept → continue, refuse, or refine with feedback
|
|
59
|
+
├─ validate (lint / typecheck / test against the proposed contents)
|
|
60
|
+
├─ ?apply → branch + commit + open MR
|
|
61
|
+
├─ watch CI
|
|
62
|
+
├─ ?ci-fix (only if the pipeline fails — re-analyse with logs, push to same branch)
|
|
63
|
+
├─ ?merge → merge to main
|
|
64
|
+
├─ watch deploy (post-merge pipeline)
|
|
65
|
+
└─ ?close issue
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Resumable.** If you abort or the process dies, re-run `forge-agent ship <iid>` and it picks up at the next gate (state lives in `~/.forge/sessions/`).
|
|
69
|
+
|
|
70
|
+
**Confirm-by-default.** Cursor on every gate defaults to *no*. Pass `--yes` (or set `FORGE_YES=1`) for unattended mode.
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
forge-agent ship 42 # interactive, all gates
|
|
74
|
+
forge-agent ship 42 --all-repos # cross-repo (web-app + api + …)
|
|
75
|
+
forge-agent ship 42 --yes # unattended, no prompts
|
|
76
|
+
forge-agent ship 42 --auto # arm auto-merge instead of merging now
|
|
77
|
+
forge-agent ship 42 --skip-validate # skip the auto-validate before apply
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Discover what to work on
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
forge-agent issues # latest open issues, sorted by recency
|
|
86
|
+
forge-agent issues --label feature # filter by label
|
|
87
|
+
forge-agent issues --mine # filter by author (FORGE_USER || USER)
|
|
88
|
+
forge-agent issues --json | jq . # pipe-friendly
|
|
89
|
+
forge-agent issue 42 # full description, labels, URL
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## Drive each phase by hand
|
|
95
|
+
|
|
96
|
+
`ship` is a thin orchestrator — every phase is also a standalone command. Useful when you want to inspect, iterate, or only do part of the flow.
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
forge-agent analyze 42 --all-repos # produce + cache a fresh analysis
|
|
100
|
+
forge-agent show # re-render the most recent analysis
|
|
101
|
+
forge-agent show 42 # ...for a specific issue
|
|
102
|
+
forge-agent refine --feedback "use Resend instead of SendGrid"
|
|
103
|
+
forge-agent validate # lint/typecheck/test the proposal
|
|
104
|
+
forge-agent apply --validate # gate apply on green validation
|
|
105
|
+
forge-agent watch # poll the MR pipeline
|
|
106
|
+
forge-agent ci-fix # re-analyse with failed-job logs, push to same branch
|
|
107
|
+
forge-agent merge # confirm + merge
|
|
108
|
+
forge-agent merge --auto # arm auto-merge instead
|
|
109
|
+
forge-agent resolution-check # ask the model: did this MR actually fix the issue?
|
|
110
|
+
forge-agent close # confirm + close the issue
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`<iid>`-less commands resolve via the **HEAD pointer** — the most recently touched session. Like `git`'s HEAD: whatever you analysed last is what `show`/`validate`/`apply`/`watch`/`merge`/`close` operate on unless you pass an explicit `<iid>`.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Sessions (`~/.forge/sessions/`)
|
|
118
|
+
|
|
119
|
+
Each issue you work on gets a directory:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
~/.forge/sessions/<repo>/<iid>/
|
|
123
|
+
analysis.json last cached analyzeIssue result
|
|
124
|
+
state.json { phase, branch, mrIid, mrUrl, lastPipelineStatus, ... }
|
|
125
|
+
events.ndjson append-only audit log
|
|
126
|
+
~/.forge/sessions/HEAD "<repo>/<iid>" — the most recently touched session
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Inspect and clean:
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
forge-agent session list # table of all sessions, HEAD marked *
|
|
133
|
+
forge-agent session list --json
|
|
134
|
+
forge-agent session show # full state of HEAD
|
|
135
|
+
forge-agent session show 42 # ...for a specific issue
|
|
136
|
+
forge-agent session clean 42 # remove one session
|
|
137
|
+
forge-agent session clean --all # wipe everything
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Override the location with `FORGE_SESSIONS_PATH` (handy for CI or test isolation).
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Common workflows
|
|
145
|
+
|
|
146
|
+
### Ship a small fix, fully unattended
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
forge-agent ship 42 --yes
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Don't do this on prod the first time. Watch a couple of runs interactively first.
|
|
153
|
+
|
|
154
|
+
### Drive review explicitly
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
forge-agent analyze 42 --all-repos # produce
|
|
158
|
+
forge-agent show # review on the same screen later
|
|
159
|
+
forge-agent refine --feedback "..." # iterate
|
|
160
|
+
forge-agent ship 42 # pick up where you left off
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Run from CI
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
FORGE_YES=1 forge-agent ship 42
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
`--json` is available on `analyze`, `issues`, `issue`, `repos list`, `session list/show`, `watch`, and `validate` — pipe-safe outputs that bypass Ink.
|
|
170
|
+
|
|
171
|
+
### Recover from a failed step
|
|
172
|
+
|
|
173
|
+
Just re-run the same command. State is on disk; it picks up where it left off.
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
forge-agent ship 42 # if it died mid-flow, this resumes
|
|
177
|
+
forge-agent ci-fix # if CI failed, fix it without re-running ship
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Doctor & troubleshooting
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
forge-agent doctor
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Sequential checklist — `node`, `git`, `claude`, `FORGE_TOKEN`, config file, frontend build. Exits non-zero if any check fails.
|
|
189
|
+
|
|
190
|
+
If `analyze` is timing out (5-minute Claude CLI cap), narrow the scope:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
forge-agent analyze 42 --secondary group/api # explicit secondary instead of --all-repos
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
If `apply` says "no repos to validate against", check `forge-agent repos list` and your session's `primary` field.
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
|
|
200
|
+
## Reference
|
|
201
|
+
|
|
202
|
+
- [`docs/cli.md`](../docs/cli.md) — full command reference, every flag
|
|
203
|
+
- [`docs/cli-ship-workflow.md`](../docs/cli-ship-workflow.md) — design + status of the end-to-end ship workflow (per-phase delivery, decisions, risks)
|
|
204
|
+
- [`../README.md`](../README.md) — the broader Forge project (web UI, server, multi-provider details)
|
|
205
|
+
|
|
206
|
+
---
|
|
207
|
+
|
|
208
|
+
## License
|
|
209
|
+
|
|
210
|
+
MIT — same as the rest of Forge.
|