@ipul-labs/forge 1.13.2 → 1.14.1
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 +137 -91
- package/package.json +9 -20
- package/server/forge/core/ForgeAgent.js +12 -2
- package/server/forge/core/claudeClient.js +3 -1
- package/server/forge/core/prompts.js +45 -1
- package/server/forge/routes.js +3 -0
- package/dist-lib/favicon.svg +0 -8
- package/dist-lib/index.d.ts +0 -1
- package/dist-lib/style.css +0 -1
- package/dist-lib/ui.d.ts +0 -2
- package/dist-lib/ui.js +0 -5922
- package/dist-lib/views/Forge/ForgeDashboard.d.ts +0 -5
- package/dist-lib/views/Forge/activeJobs.d.ts +0 -29
- package/dist-lib/views/Forge/analysisCache.d.ts +0 -64
- package/dist-lib/views/Forge/api.d.ts +0 -4
- package/dist-lib/views/Forge/components/AnalysisProgress.d.ts +0 -13
- package/dist-lib/views/Forge/components/CITerminal.d.ts +0 -44
- package/dist-lib/views/Forge/components/DiffViewer.d.ts +0 -37
- package/dist-lib/views/Forge/components/ForgeConnect.d.ts +0 -6
- package/dist-lib/views/Forge/components/IssueList.d.ts +0 -28
- package/dist-lib/views/Forge/components/MRStatus.d.ts +0 -9
- package/dist-lib/views/Forge/components/NewTaskModal.d.ts +0 -1
- package/dist-lib/views/Forge/components/OpenMRList.d.ts +0 -11
- package/dist-lib/views/Forge/components/PipelineStatus.d.ts +0 -12
- package/dist-lib/views/Forge/components/PipelinesList.d.ts +0 -9
- package/dist-lib/views/Forge/components/RolloutStatus.d.ts +0 -5
- package/dist-lib/views/Forge/components/UsageWidget.d.ts +0 -8
- package/dist-lib/views/Forge/components/ValidationPanel.d.ts +0 -22
- package/dist-lib/views/Forge/context/ForgeProvider.d.ts +0 -23
- package/dist-lib/views/Forge/hooks/useConfig.d.ts +0 -54
- package/dist-lib/views/Forge/hooks/useForgeDashboard.d.ts +0 -107
- package/dist-lib/views/Forge/hooks/useForgeQuota.d.ts +0 -22
- package/dist-lib/views/Forge/phases/AnalyzingView.d.ts +0 -1
- package/dist-lib/views/Forge/phases/IdleView.d.ts +0 -1
- package/dist-lib/views/Forge/phases/MonitoringIssueTab.d.ts +0 -1
- package/dist-lib/views/Forge/phases/MonitoringPipelineTab.d.ts +0 -1
- package/dist-lib/views/Forge/phases/MonitoringView.d.ts +0 -1
- package/dist-lib/views/Forge/phases/ReviewingView.d.ts +0 -1
- package/dist-lib/views/Forge/phases/SelectedIssueTab.d.ts +0 -11
- package/dist-lib/views/Forge/phases/SelectedMRTab.d.ts +0 -1
- package/dist-lib/views/Forge/phases/SelectedView.d.ts +0 -1
- package/dist-lib/views/Forge/phases/shared/CloseIssueConfirm.d.ts +0 -1
- package/dist-lib/views/Forge/phases/shared/DetailTabs.d.ts +0 -14
- package/dist-lib/views/Forge/phases/shared/EnvironmentsPanel.d.ts +0 -9
- package/dist-lib/views/Forge/phases/shared/ForgeActivity.d.ts +0 -1
- package/dist-lib/views/Forge/phases/shared/IssueHeaderBlock.d.ts +0 -13
- package/dist-lib/views/Forge/phases/shared/MergedMRList.d.ts +0 -4
- package/dist-lib/views/Forge/phases/shared/PreviousAnalyses.d.ts +0 -1
- package/dist-lib/views/Forge/phases/shared/ResolutionCheckPanel.d.ts +0 -6
- package/dist-lib/views/Forge/settings/ConnectionRow.d.ts +0 -16
- package/dist-lib/views/Forge/settings/ConnectionsSection.d.ts +0 -7
- package/dist-lib/views/Forge/settings/DefaultsSection.d.ts +0 -7
- package/dist-lib/views/Forge/settings/ReposSection.d.ts +0 -7
- package/dist-lib/views/Forge/settings/SettingsView.d.ts +0 -1
- package/dist-lib/views/Forge/shell/ConfigBar.d.ts +0 -1
- package/dist-lib/views/Forge/shell/ForgeRouter.d.ts +0 -9
- package/dist-lib/views/Forge/shell/ForgeShell.d.ts +0 -7
- package/dist-lib/views/Forge/shell/Sidebar.d.ts +0 -1
- package/dist-lib/views/Forge/shell/SidebarFooterMenu.d.ts +0 -1
- package/dist-lib/views/Forge/shell/SidebarNav.d.ts +0 -1
- package/dist-lib/views/Forge/shell/SidebarNavItem.d.ts +0 -10
- package/dist-lib/views/Forge/shell/TopBar.d.ts +0 -5
- package/dist-lib/views/Forge/types.d.ts +0 -235
- package/dist-lib/views/Forge/utils.d.ts +0 -11
package/README.md
CHANGED
|
@@ -30,32 +30,112 @@ Everything else fills in the gaps that matter for real teams:
|
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
-
##
|
|
33
|
+
## Getting started
|
|
34
|
+
|
|
35
|
+
### Prerequisites
|
|
36
|
+
|
|
37
|
+
- Node.js 20+
|
|
38
|
+
- `claude` CLI installed and authenticated (`claude auth login`)
|
|
39
|
+
- Credentials for your SCM provider (see [Configuration](#configuration))
|
|
40
|
+
|
|
41
|
+
### Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
git clone https://gitlab.com/ipul-labs/forge.git
|
|
45
|
+
cd forge
|
|
46
|
+
npm install
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Configure
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
# Interactive setup — writes .env and ~/.forge/config.json
|
|
53
|
+
npx forge init
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or copy the example env and fill in the values manually:
|
|
34
57
|
|
|
35
58
|
```bash
|
|
36
59
|
cp .env.example .env
|
|
37
|
-
# fill in FORGE_TOKEN plus your provider credentials
|
|
60
|
+
# fill in FORGE_TOKEN plus your provider credentials
|
|
61
|
+
```
|
|
38
62
|
|
|
39
|
-
|
|
63
|
+
### Launch the UI
|
|
64
|
+
|
|
65
|
+
```bash
|
|
40
66
|
npm run dev
|
|
41
|
-
#
|
|
67
|
+
# opens http://localhost:5000 (frontend) with API on :5001
|
|
42
68
|
```
|
|
43
69
|
|
|
44
|
-
|
|
70
|
+
For production:
|
|
45
71
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
72
|
+
```bash
|
|
73
|
+
npm run build:app # builds Vite SPA to dist/
|
|
74
|
+
npm start # NODE_ENV=production node server.js
|
|
75
|
+
```
|
|
49
76
|
|
|
50
|
-
###
|
|
77
|
+
### CLI usage
|
|
78
|
+
|
|
79
|
+
The `forge` CLI drives the same orchestrator from the terminal. Install globally or use `npx`:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# Global install (adds `forge` to PATH)
|
|
83
|
+
npm install -g @ipul-labs/forge
|
|
84
|
+
|
|
85
|
+
# Or run via npx from the repo
|
|
86
|
+
npx forge <command>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
#### End-to-end: issue to production
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
forge ship 42
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Runs: analyze → review → validate → apply → watch CI → merge → watch deploy → close, with a `y/N` gate at every state-changing step.
|
|
96
|
+
|
|
97
|
+
#### Step-by-step commands
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
forge issues # List open issues (--label X, --mine, --limit N)
|
|
101
|
+
forge issue 42 # Show full description
|
|
102
|
+
forge analyze 42 # Run two-pass analysis, cache result
|
|
103
|
+
forge show # Re-render cached analysis
|
|
104
|
+
forge refine --feedback "..." # Iterate with feedback
|
|
105
|
+
forge validate # Run lint/typecheck/test against proposed changes
|
|
106
|
+
forge apply # Push branch + open MR
|
|
107
|
+
forge watch # Poll the MR pipeline
|
|
108
|
+
forge ci-fix # Re-analyze with failed-pipeline logs
|
|
109
|
+
forge merge # Merge the MR
|
|
110
|
+
forge resolution-check # Verify merged MR closes the issue
|
|
111
|
+
forge close # Close the issue
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
#### Options
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
-p, --port <n> Port for start
|
|
118
|
+
--repo <group/repo> Primary repo
|
|
119
|
+
--secondary <repo> Additional repo (repeatable)
|
|
120
|
+
--all-repos Include every configured repo
|
|
121
|
+
--model <id> Claude model override
|
|
122
|
+
--agent <name> Agent backend: claude | openclaw
|
|
123
|
+
--prompt <text> Extra user prompt
|
|
124
|
+
--json JSON output
|
|
125
|
+
--quiet Suppress progress
|
|
126
|
+
--yes Skip confirmation gates
|
|
127
|
+
--validate Run validate before apply
|
|
128
|
+
```
|
|
51
129
|
|
|
52
|
-
|
|
130
|
+
#### Diagnostics
|
|
53
131
|
|
|
54
132
|
```bash
|
|
55
|
-
forge
|
|
133
|
+
forge doctor # Check prerequisites (node, claude CLI, env vars)
|
|
134
|
+
forge session list # List cached sessions
|
|
135
|
+
forge session clean # Remove stale session data
|
|
56
136
|
```
|
|
57
137
|
|
|
58
|
-
|
|
138
|
+
See [`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
139
|
|
|
60
140
|
---
|
|
61
141
|
|
|
@@ -65,7 +145,7 @@ forge-agent ship 42
|
|
|
65
145
|
|
|
66
146
|
| Variable | Required | Description |
|
|
67
147
|
|---|---|---|
|
|
68
|
-
| `FORGE_TOKEN` |
|
|
148
|
+
| `FORGE_TOKEN` | Yes | Dashboard password — users enter this to access Forge |
|
|
69
149
|
| `SCM_PROVIDER` | — | `gitlab` (default) · `github` · `azuredevops` |
|
|
70
150
|
| `FORGE_REPOS` | — | Comma-separated repo list for multi-repo support |
|
|
71
151
|
| `ANTHROPIC_API_KEY` | — | Enables live model list from Anthropic; falls back to hardcoded list |
|
|
@@ -81,25 +161,25 @@ forge-agent ship 42
|
|
|
81
161
|
|
|
82
162
|
| Variable | Required | Description |
|
|
83
163
|
|---|---|---|
|
|
84
|
-
| `FORGE_GITLAB_PROJECT` |
|
|
85
|
-
| `GITLAB_TOKEN` |
|
|
164
|
+
| `FORGE_GITLAB_PROJECT` | Yes | Default project path, e.g. `group/repo` |
|
|
165
|
+
| `GITLAB_TOKEN` | Yes | Personal access token with `api` + `write_repository` scopes |
|
|
86
166
|
|
|
87
167
|
### GitHub (`SCM_PROVIDER=github`)
|
|
88
168
|
|
|
89
169
|
| Variable | Required | Description |
|
|
90
170
|
|---|---|---|
|
|
91
|
-
| `GITHUB_TOKEN` |
|
|
92
|
-
| `GITHUB_OWNER` |
|
|
93
|
-
| `GITHUB_REPO` |
|
|
171
|
+
| `GITHUB_TOKEN` | Yes | Personal access token with `repo` + `workflow` scopes |
|
|
172
|
+
| `GITHUB_OWNER` | Yes | Organization or user, e.g. `ipul-labs` |
|
|
173
|
+
| `GITHUB_REPO` | Yes | Repository name, e.g. `web-app` |
|
|
94
174
|
| `GITHUB_BASE_BRANCH` | — | Default target branch (default: `main`) |
|
|
95
175
|
|
|
96
176
|
### Azure DevOps (`SCM_PROVIDER=azuredevops`)
|
|
97
177
|
|
|
98
178
|
| Variable | Required | Description |
|
|
99
179
|
|---|---|---|
|
|
100
|
-
| `AZURE_DEVOPS_TOKEN` |
|
|
101
|
-
| `AZURE_DEVOPS_ORG` |
|
|
102
|
-
| `AZURE_DEVOPS_PROJECT` |
|
|
180
|
+
| `AZURE_DEVOPS_TOKEN` | Yes | Personal access token (Full access or Code + Work Items) |
|
|
181
|
+
| `AZURE_DEVOPS_ORG` | Yes | Organization name, e.g. `ipul-labs` |
|
|
182
|
+
| `AZURE_DEVOPS_PROJECT` | Yes | Team project name, e.g. `web-app` |
|
|
103
183
|
| `AZURE_DEVOPS_REPO` | — | Git repo name (defaults to project name) |
|
|
104
184
|
| `AZURE_DEVOPS_BASE_BRANCH` | — | Default target branch (default: `main`) |
|
|
105
185
|
|
|
@@ -131,75 +211,19 @@ FORGE_REPOS=gitlab:ipul/web-app,github:my-org/mobile
|
|
|
131
211
|
|
|
132
212
|
| Feature | GitLab | GitHub | Azure DevOps |
|
|
133
213
|
|---|---|---|---|
|
|
134
|
-
| Issues / Work Items |
|
|
135
|
-
| Multi-file commits |
|
|
136
|
-
| Merge / Pull Requests |
|
|
137
|
-
| CI 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
|
-
```
|
|
214
|
+
| Issues / Work Items | Yes | Yes | Yes (Work Items) |
|
|
215
|
+
| Multi-file commits | Yes | Yes (Git Data API) | Yes (Pushes API) |
|
|
216
|
+
| Merge / Pull Requests | Yes | Yes | Yes |
|
|
217
|
+
| CI pipelines | Yes (GitLab CI) | Yes (GitHub Actions) | Yes (Azure Pipelines) |
|
|
218
|
+
| Job log traces | Yes | Yes | Yes |
|
|
219
|
+
| Server-side rebase | Yes | — | — |
|
|
196
220
|
|
|
197
221
|
---
|
|
198
222
|
|
|
199
223
|
## Production deployment
|
|
200
224
|
|
|
201
225
|
```bash
|
|
202
|
-
npm run build
|
|
226
|
+
npm run build:app # builds Vite SPA to dist/
|
|
203
227
|
NODE_ENV=production node server.js
|
|
204
228
|
```
|
|
205
229
|
|
|
@@ -215,15 +239,23 @@ docker run -p 5001:5001 --env-file .env forge
|
|
|
215
239
|
## Architecture
|
|
216
240
|
|
|
217
241
|
```
|
|
242
|
+
bin/
|
|
243
|
+
forge-agent.js # CLI entry point (forge command)
|
|
244
|
+
cli/
|
|
245
|
+
ship.js # End-to-end orchestrator (Ink UI)
|
|
246
|
+
analyze.js # Two-pass issue analysis
|
|
247
|
+
resolution.js # Post-merge resolution check
|
|
248
|
+
sessionStore.js # ~/.forge/sessions/ persistence
|
|
249
|
+
...
|
|
250
|
+
|
|
218
251
|
server/
|
|
219
252
|
forge/
|
|
220
253
|
routes.js # Express router — all /api/forge/* endpoints
|
|
221
254
|
core/
|
|
222
|
-
ForgeAgent.js # Orchestrates the full pipeline (analyze
|
|
255
|
+
ForgeAgent.js # Orchestrates the full pipeline (analyze -> apply -> refine)
|
|
223
256
|
claudeClient.js # Shells out to the claude CLI for structured output
|
|
224
257
|
openclawClient.js # OpenClaw Gateway HTTP client
|
|
225
258
|
agentClient.js # Dispatcher: routes to claudeClient or openclawClient
|
|
226
|
-
gitlabClient.js # Legacy shim (kept for backward compatibility)
|
|
227
259
|
k8s.js # Kubernetes client for rollout monitoring
|
|
228
260
|
providers/
|
|
229
261
|
base.js # Abstract ScmProvider — normalized shapes + interface
|
|
@@ -238,11 +270,7 @@ src/
|
|
|
238
270
|
api.ts # Token management + fetch helper
|
|
239
271
|
types.ts # Shared TypeScript types
|
|
240
272
|
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
|
|
273
|
+
components/ # Analysis progress, pipeline status, diff viewer
|
|
246
274
|
hooks/
|
|
247
275
|
useForgeDashboard.ts # All state, phase transitions, and API calls
|
|
248
276
|
```
|
|
@@ -268,6 +296,24 @@ All three SCM providers implement `ScmProvider` from `providers/base.js`. The co
|
|
|
268
296
|
|
|
269
297
|
---
|
|
270
298
|
|
|
299
|
+
## Programmatic usage
|
|
300
|
+
|
|
301
|
+
Mount the Forge Express router or use the core classes directly:
|
|
302
|
+
|
|
303
|
+
```js
|
|
304
|
+
import forgeRouter from "@ipul-labs/forge"; // Express router
|
|
305
|
+
import { ForgeAgent } from "@ipul-labs/forge/agent"; // Core pipeline class
|
|
306
|
+
import { createProvider } from "@ipul-labs/forge/providers"; // SCM factory
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
```js
|
|
310
|
+
const agent = new ForgeAgent({ project: "group/repo" });
|
|
311
|
+
const result = await agent.analyzeIssue(42, (event) => console.log(event));
|
|
312
|
+
const { branchName, mr } = await agent.applyFix(result);
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
---
|
|
316
|
+
|
|
271
317
|
## License
|
|
272
318
|
|
|
273
319
|
MIT
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ipul-labs/forge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.14.1",
|
|
4
4
|
"description": "AI-powered code change & deploy control panel — connects Claude, GitLab, and Kubernetes",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "server/forge/routes.js",
|
|
@@ -10,24 +10,16 @@
|
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./server/forge/routes.js",
|
|
12
12
|
"./agent": "./server/forge/core/ForgeAgent.js",
|
|
13
|
-
"./
|
|
14
|
-
"./ui": {
|
|
15
|
-
"import": "./dist-lib/ui.js",
|
|
16
|
-
"types": "./dist-lib/ui.d.ts"
|
|
17
|
-
},
|
|
18
|
-
"./style.css": "./dist-lib/style.css"
|
|
13
|
+
"./providers": "./server/forge/core/providers/index.js"
|
|
19
14
|
},
|
|
20
15
|
"files": [
|
|
21
16
|
"bin",
|
|
22
17
|
"server/forge",
|
|
23
|
-
"dist"
|
|
24
|
-
"dist-lib"
|
|
18
|
+
"dist"
|
|
25
19
|
],
|
|
26
20
|
"scripts": {
|
|
27
21
|
"dev": "trap 'kill 0' EXIT INT TERM; FORGE_NO_VITE=1 node --watch-path=./server --watch-path=./server.js server.js & vite; wait",
|
|
28
|
-
"build": "vite build
|
|
29
|
-
"build:app": "vite build",
|
|
30
|
-
"prepare": "npm run build",
|
|
22
|
+
"build": "vite build",
|
|
31
23
|
"start": "NODE_ENV=production node server.js",
|
|
32
24
|
"typecheck": "tsc --noEmit"
|
|
33
25
|
},
|
|
@@ -40,7 +32,10 @@
|
|
|
40
32
|
"ink": "^7.0.1",
|
|
41
33
|
"ink-select-input": "^6.2.0",
|
|
42
34
|
"ink-spinner": "^5.0.0",
|
|
43
|
-
"ink-text-input": "^6.0.0"
|
|
35
|
+
"ink-text-input": "^6.0.0",
|
|
36
|
+
"react": "^19.0.0",
|
|
37
|
+
"react-dom": "^19.0.0",
|
|
38
|
+
"react-router-dom": "^7.14.1"
|
|
44
39
|
},
|
|
45
40
|
"devDependencies": {
|
|
46
41
|
"@semantic-release/changelog": "^6.0.3",
|
|
@@ -58,13 +53,7 @@
|
|
|
58
53
|
"semantic-release": "^25.0.3",
|
|
59
54
|
"tailwindcss": "^3.4.14",
|
|
60
55
|
"typescript": "^5.6.0",
|
|
61
|
-
"vite": "^5.4.0"
|
|
62
|
-
"vite-plugin-dts": "^4.3.0"
|
|
63
|
-
},
|
|
64
|
-
"peerDependencies": {
|
|
65
|
-
"react": "^18.0.0 || ^19.0.0",
|
|
66
|
-
"react-dom": "^18.0.0 || ^19.0.0",
|
|
67
|
-
"react-router-dom": "^7.0.0"
|
|
56
|
+
"vite": "^5.4.0"
|
|
68
57
|
},
|
|
69
58
|
"engines": {
|
|
70
59
|
"node": ">=20.0.0"
|
|
@@ -350,7 +350,7 @@ export class ForgeAgent {
|
|
|
350
350
|
* @param {string} [userPrompt]
|
|
351
351
|
* @returns {Promise<AnalysisResult>}
|
|
352
352
|
*/
|
|
353
|
-
async analyzeIssue(issueIid, onProgress, model, ciContext, userPrompt, kind = "fresh", opts = {}) {
|
|
353
|
+
async analyzeIssue(issueIid, onProgress, model, ciContext, userPrompt, kind = "fresh", opts = {}, previousChanges = null) {
|
|
354
354
|
const emit = onProgress ?? (() => {});
|
|
355
355
|
const { signal } = opts;
|
|
356
356
|
|
|
@@ -416,7 +416,7 @@ export class ForgeAgent {
|
|
|
416
416
|
const propose = await proposeFix(
|
|
417
417
|
issue,
|
|
418
418
|
fileContents,
|
|
419
|
-
{ ciContext, userPrompt, repos: this.allRepos },
|
|
419
|
+
{ ciContext, userPrompt, previousChanges, repos: this.allRepos },
|
|
420
420
|
model,
|
|
421
421
|
this.agent,
|
|
422
422
|
{ signal },
|
|
@@ -859,6 +859,16 @@ export class ForgeAgent {
|
|
|
859
859
|
}
|
|
860
860
|
|
|
861
861
|
const provider = this._provider(repo);
|
|
862
|
+
|
|
863
|
+
// Rebase onto latest main before pushing so CI runs against current code.
|
|
864
|
+
try {
|
|
865
|
+
const mrs = await provider.listAllForgeMRs();
|
|
866
|
+
const mr = mrs.find((m) => m.source_branch === branchName);
|
|
867
|
+
if (mr && provider.supportsRebase) {
|
|
868
|
+
await provider.rebaseMR(mr.iid);
|
|
869
|
+
}
|
|
870
|
+
} catch { /* rebase failure is non-fatal — push will still work */ }
|
|
871
|
+
|
|
862
872
|
const actions = changes.map((c) => ({ action: c.action, file_path: c.file, content: c.proposed }));
|
|
863
873
|
const subject = buildCommitSubject(analysis);
|
|
864
874
|
const commitMessage = buildCommitMessage(subject, changes, analysis, "ci-fix");
|
|
@@ -14,6 +14,7 @@ import { spawn } from "child_process";
|
|
|
14
14
|
import {
|
|
15
15
|
SELECT_FILES_SCHEMA,
|
|
16
16
|
PROPOSE_FIX_SCHEMA,
|
|
17
|
+
CI_FIX_SCHEMA,
|
|
17
18
|
REFINE_OR_ASK_SCHEMA,
|
|
18
19
|
RESOLUTION_CHECK_SCHEMA,
|
|
19
20
|
buildIdentifyFilesPrompt,
|
|
@@ -332,9 +333,10 @@ Your final message MUST be a single raw JSON object matching the schema — no p
|
|
|
332
333
|
}
|
|
333
334
|
|
|
334
335
|
export async function proposeFix(issue, fileContents, options = {}, model, opts = {}) {
|
|
336
|
+
const schema = options.ciContext ? CI_FIX_SCHEMA : PROPOSE_FIX_SCHEMA;
|
|
335
337
|
const { data, cost, serviceTier, inputTokens, outputTokens, cacheCreationTokens, cacheReadTokens } = await runClaude(
|
|
336
338
|
buildProposeFixPrompt(issue, fileContents, options),
|
|
337
|
-
|
|
339
|
+
schema,
|
|
338
340
|
`You are Forge, an AI code assistant in a production React/TypeScript/Express codebase.
|
|
339
341
|
Rules:
|
|
340
342
|
- Changes must be minimal and surgical.
|
|
@@ -61,6 +61,43 @@ export const PROPOSE_FIX_SCHEMA = JSON.stringify({
|
|
|
61
61
|
required: ["title", "explanation", "changes"],
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
+
export const CI_FIX_SCHEMA = JSON.stringify({
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: {
|
|
67
|
+
unfixable: {
|
|
68
|
+
type: "boolean",
|
|
69
|
+
description: "True ONLY when the failure cannot be resolved by any source-code or package.json change (e.g. Docker registry outage, runner OOM, flaky network). Default false.",
|
|
70
|
+
},
|
|
71
|
+
unfixableReason: {
|
|
72
|
+
type: "string",
|
|
73
|
+
description: "Required when unfixable=true. One sentence explaining why no code change can fix this.",
|
|
74
|
+
},
|
|
75
|
+
title: {
|
|
76
|
+
type: "string",
|
|
77
|
+
description: "Conventional-commit MR title describing the actual fix, e.g. 'fix: resolve token refresh race condition in AuthService'. Max 72 chars. No issue number.",
|
|
78
|
+
},
|
|
79
|
+
explanation: {
|
|
80
|
+
type: "string",
|
|
81
|
+
description: "2-4 sentences on root cause and approach. If changes span multiple repos, describe how the pieces fit together.",
|
|
82
|
+
},
|
|
83
|
+
changes: {
|
|
84
|
+
type: "array",
|
|
85
|
+
items: {
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: {
|
|
88
|
+
repo: { type: "string", description: "Repository id this change belongs to, exactly as given in the 'Available repositories' list." },
|
|
89
|
+
file: { type: "string", description: "Path from that repo's root." },
|
|
90
|
+
action: { type: "string", enum: ["create", "modify", "delete"] },
|
|
91
|
+
proposed: { type: "string", description: "For create/modify: the COMPLETE new file content. For delete: empty string." },
|
|
92
|
+
summary: { type: "string", description: "One sentence describing this file's change." },
|
|
93
|
+
},
|
|
94
|
+
required: ["repo", "file", "action", "proposed", "summary"],
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["title", "explanation", "changes"],
|
|
99
|
+
});
|
|
100
|
+
|
|
64
101
|
export const REFINE_OR_ASK_SCHEMA = JSON.stringify({
|
|
65
102
|
type: "object",
|
|
66
103
|
properties: {
|
|
@@ -198,7 +235,14 @@ export function buildProposeFixPrompt(issue, fileContents, options = {}) {
|
|
|
198
235
|
: "";
|
|
199
236
|
|
|
200
237
|
const ciBlock = ciContext?.trim()
|
|
201
|
-
? `\n\n## CI pipeline failure logs
|
|
238
|
+
? `\n\n## CI pipeline failure logs
|
|
239
|
+
The pipeline failed. Read the logs carefully and classify the failure:
|
|
240
|
+
|
|
241
|
+
1. **Code/test failure** — broken imports, type errors, failing assertions → propose the source-code fix.
|
|
242
|
+
2. **Dependency audit failure** (npm audit, yarn audit) — a package has a known vulnerability → update the version constraint in package.json. Do NOT touch package-lock.json; the lock file will be regenerated automatically.
|
|
243
|
+
3. **Unfixable infrastructure failure** — Docker registry outage, runner OOM, network timeout, flaky CI runner → set "unfixable": true and explain why in "unfixableReason". Return an empty "changes" array.
|
|
244
|
+
|
|
245
|
+
${ciContext.trim()}`
|
|
202
246
|
: "";
|
|
203
247
|
|
|
204
248
|
const userBlock = userPrompt?.trim()
|
package/server/forge/routes.js
CHANGED
|
@@ -575,6 +575,8 @@ router.post("/issues/:iid/analyze", (req, res) => {
|
|
|
575
575
|
? req.body.kind
|
|
576
576
|
: "fresh";
|
|
577
577
|
|
|
578
|
+
const previousChanges = Array.isArray(req.body.previousChanges) ? req.body.previousChanges : null;
|
|
579
|
+
|
|
578
580
|
const jobId = jobStore.createJob("analyze", (send, signal) =>
|
|
579
581
|
agent.analyzeIssue(
|
|
580
582
|
Number(iid),
|
|
@@ -584,6 +586,7 @@ router.post("/issues/:iid/analyze", (req, res) => {
|
|
|
584
586
|
req.body.prompt || undefined,
|
|
585
587
|
kind,
|
|
586
588
|
{ signal },
|
|
589
|
+
previousChanges,
|
|
587
590
|
),
|
|
588
591
|
);
|
|
589
592
|
res.json({ jobId });
|
package/dist-lib/favicon.svg
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 36 36">
|
|
2
|
-
<path fill="#111" d="M6.814 33.279c-1.166 1.166-3.021 1.221-4.121.121-1.1-1.1-1.045-2.955.121-4.121L26.079 6.014c1.167-1.167 3.021-1.221 4.121-.121 1.101 1.1 1.046 2.955-.121 4.121L6.814 33.279z"/>
|
|
3
|
-
<path fill="#111" d="M32.585 7.657c.781-.781.781-2.048 0-2.829l-1.414-1.414c-.78-.78-2.047-.78-2.828 0-.781.781-.781 2.048 0 2.829l1.414 1.414c.781.781 2.048.781 2.828 0z"/>
|
|
4
|
-
<path fill="#66757F" d="M35.789 13.424c-.252-1.765-.375-4.354-3.204-7.182l-.707-.708-4.949-4.95c-.781-.781-2.048-.781-2.828 0L20.565 4.12c-.781.781-.781 2.047 0 2.829l6.364 6.364 2.121 2.121 1.414 1.414c1.027 1.027 3.314 3.315 4.718 1.911.773-.772.961-2.86.607-5.335z"/>
|
|
5
|
-
<path fill="#111" d="M29.185 33.279c1.166 1.166 3.022 1.221 4.121.121 1.1-1.1 1.045-2.955-.121-4.121L9.921 6.014C8.754 4.847 6.899 4.792 5.8 5.893c-1.101 1.1-1.046 2.955.121 4.121l23.264 23.265z"/>
|
|
6
|
-
<path fill="#111" d="M3.415 7.657c-.781-.781-.781-2.048 0-2.829l1.414-1.414c.78-.78 2.047-.78 2.828 0 .781.781.781 2.048 0 2.829L6.243 7.657c-.781.781-2.048.781-2.828 0z"/>
|
|
7
|
-
<path fill="#66757F" d="M4.122 15.436c.78.78 2.047.78 2.828 0l8.485-8.485c.781-.781.781-2.048 0-2.829L11.899.587c-.78-.781-2.047-.781-2.828 0L.586 9.071c-.781.781-.781 2.047 0 2.828l3.536 3.537z"/>
|
|
8
|
-
</svg>
|
package/dist-lib/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { ForgeDashboard } from './views/Forge/ForgeDashboard';
|
package/dist-lib/style.css
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
.visible{visibility:visible}.collapse{visibility:collapse}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.bottom-full{bottom:100%}.left-0{left:0}.right-0{right:0}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-1\.5{margin-bottom:.375rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.ml-1{margin-left:.25rem}.ml-10{margin-left:2.5rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.ml-5{margin-left:1.25rem}.ml-auto{margin-left:auto}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.block{display:block}.inline-block{display:inline-block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.hidden{display:none}.h-1\.5{height:.375rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-2\.5{height:.625rem}.h-20{height:5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-screen{height:100vh}.max-h-12{max-height:3rem}.max-h-32{max-height:8rem}.max-h-40{max-height:10rem}.max-h-48{max-height:12rem}.max-h-56{max-height:14rem}.max-h-64{max-height:16rem}.max-h-80{max-height:20rem}.max-h-\[50vh\]{max-height:50vh}.max-h-\[60vh\]{max-height:60vh}.max-h-\[65vh\]{max-height:65vh}.min-h-0{min-height:0px}.min-h-10{min-height:2.5rem}.min-h-\[12rem\]{min-height:12rem}.min-h-\[40vh\]{min-height:40vh}.min-h-\[60vh\]{min-height:60vh}.min-h-screen{min-height:100vh}.w-1\.5{width:.375rem}.w-2{width:.5rem}.w-2\.5{width:.625rem}.w-20{width:5rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-36{width:9rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-md{max-width:28rem}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.select-all{-webkit-user-select:all;-moz-user-select:all;user-select:all}.resize-none{resize:none}.resize-y{resize:vertical}.list-none{list-style-type:none}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-baseline{align-items:baseline}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-10{gap:2.5rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.self-start{align-self:flex-start}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.border{border-width:1px}.border-2{border-width:2px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-t-0{border-top-width:0px}.border-dashed{border-style:dashed}.border-amber-300{--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.border-amber-700{--tw-border-opacity: 1;border-color:rgb(180 83 9 / var(--tw-border-opacity, 1))}.border-amber-700\/50{border-color:#b4530980}.border-amber-800{--tw-border-opacity: 1;border-color:rgb(146 64 14 / var(--tw-border-opacity, 1))}.border-amber-800\/40{border-color:#92400e66}.border-amber-800\/60{border-color:#92400e99}.border-amber-900{--tw-border-opacity: 1;border-color:rgb(120 53 15 / var(--tw-border-opacity, 1))}.border-amber-900\/40{border-color:#78350f66}.border-current{border-color:currentColor}.border-emerald-800\/40{border-color:#065f4666}.border-emerald-800\/60{border-color:#065f4699}.border-green-800{--tw-border-opacity: 1;border-color:rgb(22 101 52 / var(--tw-border-opacity, 1))}.border-red-800{--tw-border-opacity: 1;border-color:rgb(153 27 27 / var(--tw-border-opacity, 1))}.border-red-800\/50{border-color:#991b1b80}.border-red-800\/60{border-color:#991b1b99}.border-red-800\/70{border-color:#991b1bb3}.border-red-900{--tw-border-opacity: 1;border-color:rgb(127 29 29 / var(--tw-border-opacity, 1))}.border-red-900\/60{border-color:#7f1d1d99}.border-sky-800\/60{border-color:#07598599}.border-transparent{border-color:transparent}.border-violet-300{--tw-border-opacity: 1;border-color:rgb(196 181 253 / var(--tw-border-opacity, 1))}.border-violet-400{--tw-border-opacity: 1;border-color:rgb(167 139 250 / var(--tw-border-opacity, 1))}.border-violet-500\/70{border-color:#8b5cf6b3}.border-violet-600{--tw-border-opacity: 1;border-color:rgb(124 58 237 / var(--tw-border-opacity, 1))}.border-violet-600\/40{border-color:#7c3aed66}.border-violet-700\/50{border-color:#6d28d980}.border-violet-800\/60{border-color:#5b21b699}.border-violet-900\/50{border-color:#4c1d9580}.border-yellow-400{--tw-border-opacity: 1;border-color:rgb(250 204 21 / var(--tw-border-opacity, 1))}.border-zinc-400{--tw-border-opacity: 1;border-color:rgb(161 161 170 / var(--tw-border-opacity, 1))}.border-zinc-500{--tw-border-opacity: 1;border-color:rgb(113 113 122 / var(--tw-border-opacity, 1))}.border-zinc-600{--tw-border-opacity: 1;border-color:rgb(82 82 91 / var(--tw-border-opacity, 1))}.border-zinc-700{--tw-border-opacity: 1;border-color:rgb(63 63 70 / var(--tw-border-opacity, 1))}.border-zinc-700\/50{border-color:#3f3f4680}.border-zinc-800{--tw-border-opacity: 1;border-color:rgb(39 39 42 / var(--tw-border-opacity, 1))}.border-zinc-800\/60{border-color:#27272a99}.\!border-b-violet-500{--tw-border-opacity: 1 !important;border-bottom-color:rgb(139 92 246 / var(--tw-border-opacity, 1))!important}.\!border-t-violet-500{--tw-border-opacity: 1 !important;border-top-color:rgb(139 92 246 / var(--tw-border-opacity, 1))!important}.border-t-transparent{border-top-color:transparent}.bg-amber-500\/60{background-color:#f59e0b99}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-amber-600\/40{background-color:#d9770666}.bg-amber-900\/50{background-color:#78350f80}.bg-amber-950\/20{background-color:#451a0333}.bg-amber-950\/30{background-color:#451a034d}.bg-amber-950\/40{background-color:#451a0366}.bg-amber-950\/60{background-color:#451a0399}.bg-black\/60{background-color:#0009}.bg-cyan-900\/50{background-color:#164e6380}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/60{background-color:#10b98199}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-emerald-900\/40{background-color:#064e3b66}.bg-emerald-950\/50{background-color:#022c2280}.bg-green-400{--tw-bg-opacity: 1;background-color:rgb(74 222 128 / var(--tw-bg-opacity, 1))}.bg-green-950\/40{background-color:#052e1666}.bg-orange-400{--tw-bg-opacity: 1;background-color:rgb(251 146 60 / var(--tw-bg-opacity, 1))}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-red-500\/60{background-color:#ef444499}.bg-red-700\/70{background-color:#b91c1cb3}.bg-red-800{--tw-bg-opacity: 1;background-color:rgb(153 27 27 / var(--tw-bg-opacity, 1))}.bg-red-900\/30{background-color:#7f1d1d4d}.bg-red-950\/30{background-color:#450a0a4d}.bg-red-950\/40{background-color:#450a0a66}.bg-sky-950\/30{background-color:#082f494d}.bg-sky-950\/50{background-color:#082f4980}.bg-violet-400{--tw-bg-opacity: 1;background-color:rgb(167 139 250 / var(--tw-bg-opacity, 1))}.bg-violet-600{--tw-bg-opacity: 1;background-color:rgb(124 58 237 / var(--tw-bg-opacity, 1))}.bg-violet-600\/15{background-color:#7c3aed26}.bg-violet-600\/25{background-color:#7c3aed40}.bg-violet-600\/40{background-color:#7c3aed66}.bg-violet-900\/40{background-color:#4c1d9566}.bg-violet-900\/50{background-color:#4c1d9580}.bg-violet-950\/30{background-color:#2e10654d}.bg-violet-950\/50{background-color:#2e106580}.bg-yellow-400{--tw-bg-opacity: 1;background-color:rgb(250 204 21 / var(--tw-bg-opacity, 1))}.bg-yellow-600{--tw-bg-opacity: 1;background-color:rgb(202 138 4 / var(--tw-bg-opacity, 1))}.bg-zinc-400{--tw-bg-opacity: 1;background-color:rgb(161 161 170 / var(--tw-bg-opacity, 1))}.bg-zinc-500{--tw-bg-opacity: 1;background-color:rgb(113 113 122 / var(--tw-bg-opacity, 1))}.bg-zinc-600{--tw-bg-opacity: 1;background-color:rgb(82 82 91 / var(--tw-bg-opacity, 1))}.bg-zinc-700{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.bg-zinc-800{--tw-bg-opacity: 1;background-color:rgb(39 39 42 / var(--tw-bg-opacity, 1))}.bg-zinc-800\/30{background-color:#27272a4d}.bg-zinc-800\/40{background-color:#27272a66}.bg-zinc-800\/50{background-color:#27272a80}.bg-zinc-800\/60{background-color:#27272a99}.bg-zinc-900{--tw-bg-opacity: 1;background-color:rgb(24 24 27 / var(--tw-bg-opacity, 1))}.bg-zinc-900\/40{background-color:#18181b66}.bg-zinc-900\/60{background-color:#18181b99}.bg-zinc-900\/80{background-color:#18181bcc}.bg-zinc-950{--tw-bg-opacity: 1;background-color:rgb(9 9 11 / var(--tw-bg-opacity, 1))}.bg-zinc-950\/40{background-color:#09090b66}.bg-zinc-950\/60{background-color:#09090b99}.bg-zinc-950\/80{background-color:#09090bcc}.p-1{padding:.25rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[2px\]{padding-top:2px;padding-bottom:2px}.py-px{padding-top:1px;padding-bottom:1px}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pl-1{padding-left:.25rem}.pl-2{padding-left:.5rem}.pt-0\.5{padding-top:.125rem}.pt-1{padding-top:.25rem}.pt-24{padding-top:6rem}.pt-3{padding-top:.75rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-4xl{font-size:2.25rem;line-height:2.5rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.capitalize{text-transform:capitalize}.normal-case{text-transform:none}.italic{font-style:italic}.ordinal{--tw-ordinal: ordinal;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-5{line-height:1.25rem}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-normal{letter-spacing:0em}.tracking-wide{letter-spacing:.025em}.text-amber-200{--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.text-amber-300{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.text-amber-300\/80{color:#fcd34dcc}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-400\/70{color:#fbbf24b3}.text-amber-400\/80{color:#fbbf24cc}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-cyan-300{--tw-text-opacity: 1;color:rgb(103 232 249 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-emerald-500\/80{color:#10b981cc}.text-green-300{--tw-text-opacity: 1;color:rgb(134 239 172 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-green-400\/80{color:#4ade80cc}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-orange-400{--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.text-red-200{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.text-red-300{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.text-red-300\/80{color:#fca5a5cc}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-400\/70{color:#f87171b3}.text-red-400\/80{color:#f87171cc}.text-red-500{--tw-text-opacity: 1;color:rgb(239 68 68 / var(--tw-text-opacity, 1))}.text-sky-300{--tw-text-opacity: 1;color:rgb(125 211 252 / var(--tw-text-opacity, 1))}.text-sky-400{--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.text-teal-400\/70{color:#2dd4bfb3}.text-violet-200{--tw-text-opacity: 1;color:rgb(221 214 254 / var(--tw-text-opacity, 1))}.text-violet-300{--tw-text-opacity: 1;color:rgb(196 181 253 / var(--tw-text-opacity, 1))}.text-violet-400{--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.text-violet-400\/70{color:#a78bfab3}.text-violet-400\/80{color:#a78bfacc}.text-violet-600{--tw-text-opacity: 1;color:rgb(124 58 237 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-300{--tw-text-opacity: 1;color:rgb(253 224 71 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.text-zinc-100{--tw-text-opacity: 1;color:rgb(244 244 245 / var(--tw-text-opacity, 1))}.text-zinc-200{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.text-zinc-300{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.text-zinc-400{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.text-zinc-500{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.text-zinc-500\/80{color:#71717acc}.text-zinc-600{--tw-text-opacity: 1;color:rgb(82 82 91 / var(--tw-text-opacity, 1))}.text-zinc-700{--tw-text-opacity: 1;color:rgb(63 63 70 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.decoration-dotted{text-decoration-style:dotted}.placeholder-zinc-600::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 91 / var(--tw-placeholder-opacity, 1))}.placeholder-zinc-600::placeholder{--tw-placeholder-opacity: 1;color:rgb(82 82 91 / var(--tw-placeholder-opacity, 1))}.accent-violet-500{accent-color:#8b5cf6}.opacity-0{opacity:0}.opacity-40{opacity:.4}.opacity-70{opacity:.7}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.\[overflow-anchor\:none\]{overflow-anchor:none}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}.placeholder\:text-zinc-500::-moz-placeholder{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.placeholder\:text-zinc-500::placeholder{--tw-text-opacity: 1;color:rgb(113 113 122 / var(--tw-text-opacity, 1))}.hover\:border-amber-600:hover{--tw-border-opacity: 1;border-color:rgb(217 119 6 / var(--tw-border-opacity, 1))}.hover\:border-red-800:hover{--tw-border-opacity: 1;border-color:rgb(153 27 27 / var(--tw-border-opacity, 1))}.hover\:border-red-800\/60:hover{border-color:#991b1b99}.hover\:border-red-900\/70:hover{border-color:#7f1d1db3}.hover\:border-violet-500:hover{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1))}.hover\:border-zinc-500:hover{--tw-border-opacity: 1;border-color:rgb(113 113 122 / var(--tw-border-opacity, 1))}.hover\:border-zinc-600:hover{--tw-border-opacity: 1;border-color:rgb(82 82 91 / var(--tw-border-opacity, 1))}.hover\:bg-amber-500:hover{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.hover\:bg-amber-900\/50:hover{background-color:#78350f80}.hover\:bg-emerald-500:hover{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-900\/60:hover{background-color:#064e3b99}.hover\:bg-red-600:hover{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:bg-red-900\/40:hover{background-color:#7f1d1d66}.hover\:bg-red-900\/50:hover{background-color:#7f1d1d80}.hover\:bg-red-950\/50:hover{background-color:#450a0a80}.hover\:bg-sky-900\/60:hover{background-color:#0c4a6e99}.hover\:bg-violet-500:hover{--tw-bg-opacity: 1;background-color:rgb(139 92 246 / var(--tw-bg-opacity, 1))}.hover\:bg-violet-600\/40:hover{background-color:#7c3aed66}.hover\:bg-violet-900\/20:hover{background-color:#4c1d9533}.hover\:bg-white\/\[0\.02\]:hover{background-color:#ffffff05}.hover\:bg-zinc-600:hover{--tw-bg-opacity: 1;background-color:rgb(82 82 91 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-700:hover{--tw-bg-opacity: 1;background-color:rgb(63 63 70 / var(--tw-bg-opacity, 1))}.hover\:bg-zinc-800\/50:hover{background-color:#27272a80}.hover\:bg-zinc-800\/60:hover{background-color:#27272a99}.hover\:text-amber-200:hover{--tw-text-opacity: 1;color:rgb(253 230 138 / var(--tw-text-opacity, 1))}.hover\:text-emerald-300:hover{--tw-text-opacity: 1;color:rgb(110 231 183 / var(--tw-text-opacity, 1))}.hover\:text-red-200:hover{--tw-text-opacity: 1;color:rgb(254 202 202 / var(--tw-text-opacity, 1))}.hover\:text-red-300:hover{--tw-text-opacity: 1;color:rgb(252 165 165 / var(--tw-text-opacity, 1))}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-violet-100:hover{--tw-text-opacity: 1;color:rgb(237 233 254 / var(--tw-text-opacity, 1))}.hover\:text-violet-200:hover{--tw-text-opacity: 1;color:rgb(221 214 254 / var(--tw-text-opacity, 1))}.hover\:text-violet-400:hover{--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-zinc-200:hover{--tw-text-opacity: 1;color:rgb(228 228 231 / var(--tw-text-opacity, 1))}.hover\:text-zinc-300:hover{--tw-text-opacity: 1;color:rgb(212 212 216 / var(--tw-text-opacity, 1))}.hover\:text-zinc-400:hover{--tw-text-opacity: 1;color:rgb(161 161 170 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.focus\:border-red-600:focus{--tw-border-opacity: 1;border-color:rgb(220 38 38 / var(--tw-border-opacity, 1))}.focus\:border-violet-500:focus{--tw-border-opacity: 1;border-color:rgb(139 92 246 / var(--tw-border-opacity, 1))}.focus\:border-zinc-500:focus{--tw-border-opacity: 1;border-color:rgb(113 113 122 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-violet-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(139 92 246 / var(--tw-ring-opacity, 1)) }.active\:cursor-grabbing:active{cursor:grabbing}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-40:disabled{opacity:.4}.disabled\:opacity-50:disabled{opacity:.5}.group[open] .group-open\:rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:opacity-100{opacity:1}
|
package/dist-lib/ui.d.ts
DELETED