@ipul-labs/forge 1.14.0 → 1.15.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 +152 -96
- package/package.json +14 -22
- package/server/forge/core/ForgeAgent.js +42 -15
- package/server/forge/core/ForgeAgent.test.js +179 -0
- package/server/forge/core/claudeClient.js +27 -5
- package/server/forge/core/configStore.js +15 -0
- package/server/forge/core/configStore.test.js +89 -0
- package/server/forge/core/localRepo.js +4 -2
- package/server/forge/core/prompts.js +124 -17
- package/server/forge/core/prompts.test.js +219 -0
- package/server/forge/core/providers/azuredevops.js +4 -3
- package/server/forge/core/providers/github.js +3 -4
- package/server/forge/core/providers/gitlab.js +6 -6
- package/server/forge/core/validator/clone.js +3 -2
- package/server/forge/core/validator.js +3 -2
- package/server/forge/routes.js +10 -7
- 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 -5946
- package/dist-lib/views/Forge/ForgeDashboard.d.ts +0 -6
- 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/context/ForgeRouterContext.d.ts +0 -22
- 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
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
classifyIssue,
|
|
5
|
+
buildIdentifyFilesPrompt,
|
|
6
|
+
buildProposeFixPrompt,
|
|
7
|
+
buildRefineOrAskPrompt,
|
|
8
|
+
} from "./prompts.js";
|
|
9
|
+
|
|
10
|
+
// ─── classifyIssue ───────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
describe("classifyIssue", () => {
|
|
13
|
+
it("detects feat prefix in title", () => {
|
|
14
|
+
expect(classifyIssue({ title: "feat(mixes): Live Mixes section" })).toBe("feature");
|
|
15
|
+
expect(classifyIssue({ title: "feat: add new page" })).toBe("feature");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("detects fix prefix in title", () => {
|
|
19
|
+
expect(classifyIssue({ title: "fix: broken auth flow" })).toBe("fix");
|
|
20
|
+
expect(classifyIssue({ title: "fix(auth): token refresh race" })).toBe("fix");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("detects chore prefix", () => {
|
|
24
|
+
expect(classifyIssue({ title: "chore: bump dependencies" })).toBe("chore");
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("detects refactor prefix", () => {
|
|
28
|
+
expect(classifyIssue({ title: "refactor: extract auth service" })).toBe("refactor");
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("falls back to labels when no title prefix", () => {
|
|
32
|
+
expect(classifyIssue({ title: "Add mixes page", labels: ["feature"] })).toBe("feature");
|
|
33
|
+
expect(classifyIssue({ title: "Add mixes page", labels: ["enhancement"] })).toBe("feature");
|
|
34
|
+
expect(classifyIssue({ title: "Auth broken", labels: ["bug"] })).toBe("fix");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it("handles label objects with name field", () => {
|
|
38
|
+
expect(classifyIssue({ title: "Add page", labels: [{ name: "Feature" }] })).toBe("feature");
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("falls back to description heuristics", () => {
|
|
42
|
+
expect(classifyIssue({
|
|
43
|
+
title: "Live Mixes section",
|
|
44
|
+
description: "## Approach\nReuse existing infrastructure...",
|
|
45
|
+
})).toBe("feature");
|
|
46
|
+
|
|
47
|
+
expect(classifyIssue({
|
|
48
|
+
title: "Multi-track mashups",
|
|
49
|
+
description: "## Frontend changes\n- Generalize StemsEngine...",
|
|
50
|
+
})).toBe("feature");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("defaults to fix when nothing matches", () => {
|
|
54
|
+
expect(classifyIssue({ title: "Something is wrong" })).toBe("fix");
|
|
55
|
+
expect(classifyIssue({ title: "Update thing", labels: [] })).toBe("fix");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("handles missing/null fields gracefully", () => {
|
|
59
|
+
expect(classifyIssue({})).toBe("fix");
|
|
60
|
+
expect(classifyIssue({ title: null, labels: null })).toBe("fix");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// ─── buildIdentifyFilesPrompt ────────────────────────────────────────────────
|
|
65
|
+
|
|
66
|
+
describe("buildIdentifyFilesPrompt", () => {
|
|
67
|
+
const repoTrees = [
|
|
68
|
+
{ repo: "group/web-app", files: ["src/App.tsx", "src/types.ts"] },
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
it("uses feature selection rules for feat issues", () => {
|
|
72
|
+
const issue = { iid: 25, title: "feat(mixes): Live Mixes section", labels: [] };
|
|
73
|
+
const prompt = buildIdentifyFilesPrompt(issue, repoTrees);
|
|
74
|
+
|
|
75
|
+
expect(prompt).toContain("feature implementation");
|
|
76
|
+
expect(prompt).toContain("PATTERNS");
|
|
77
|
+
expect(prompt).toContain("max 15");
|
|
78
|
+
expect(prompt).not.toContain("failing assertion");
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it("uses bug-fix selection rules for fix issues", () => {
|
|
82
|
+
const issue = { iid: 10, title: "fix: broken auth", labels: [] };
|
|
83
|
+
const prompt = buildIdentifyFilesPrompt(issue, repoTrees);
|
|
84
|
+
|
|
85
|
+
expect(prompt).toContain("bug fix");
|
|
86
|
+
expect(prompt).toContain("failing assertion");
|
|
87
|
+
expect(prompt).toContain("max 10");
|
|
88
|
+
expect(prompt).not.toContain("PATTERNS");
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it("says implementing for features, fixing for bugs", () => {
|
|
92
|
+
const feat = buildIdentifyFilesPrompt(
|
|
93
|
+
{ iid: 1, title: "feat: new page", labels: [] }, repoTrees,
|
|
94
|
+
);
|
|
95
|
+
const fix = buildIdentifyFilesPrompt(
|
|
96
|
+
{ iid: 2, title: "fix: crash", labels: [] }, repoTrees,
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
expect(feat).toContain("implementing");
|
|
100
|
+
expect(fix).toContain("fixing");
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it("includes multi-repo guidance when multiple repos present", () => {
|
|
104
|
+
const multi = [
|
|
105
|
+
{ repo: "group/web-app", files: ["src/App.tsx"] },
|
|
106
|
+
{ repo: "group/api", files: ["internal/handler.go"] },
|
|
107
|
+
];
|
|
108
|
+
const prompt = buildIdentifyFilesPrompt(
|
|
109
|
+
{ iid: 1, title: "fix: thing", labels: [] }, multi,
|
|
110
|
+
);
|
|
111
|
+
expect(prompt).toContain("Multi-repo guidance");
|
|
112
|
+
expect(prompt).toContain("group/web-app, group/api");
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// ─── buildProposeFixPrompt ───────────────────────────────────────────────────
|
|
117
|
+
|
|
118
|
+
describe("buildProposeFixPrompt", () => {
|
|
119
|
+
const fileContents = [
|
|
120
|
+
{ repo: "group/web-app", path: "src/App.tsx", content: "export default function App() {}" },
|
|
121
|
+
];
|
|
122
|
+
|
|
123
|
+
it("uses feat: prefix for feature issues", () => {
|
|
124
|
+
const issue = { iid: 25, title: "feat: add mixes", labels: [] };
|
|
125
|
+
const prompt = buildProposeFixPrompt(issue, fileContents);
|
|
126
|
+
|
|
127
|
+
expect(prompt).toContain('"feat:');
|
|
128
|
+
expect(prompt).toContain("Implement this feature");
|
|
129
|
+
expect(prompt).not.toContain("Root-cause discipline");
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it("uses fix: prefix for bug issues", () => {
|
|
133
|
+
const issue = { iid: 10, title: "fix: broken auth", labels: [] };
|
|
134
|
+
const prompt = buildProposeFixPrompt(issue, fileContents);
|
|
135
|
+
|
|
136
|
+
expect(prompt).toContain('"fix:');
|
|
137
|
+
expect(prompt).toContain("Propose a targeted fix");
|
|
138
|
+
expect(prompt).toContain("Root-cause discipline");
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
it("includes feature discipline for feature issues", () => {
|
|
142
|
+
const issue = { iid: 25, title: "feat: mixes", labels: [] };
|
|
143
|
+
const prompt = buildProposeFixPrompt(issue, fileContents);
|
|
144
|
+
|
|
145
|
+
expect(prompt).toContain("Feature implementation rules");
|
|
146
|
+
expect(prompt).toContain("Follow the issue specification");
|
|
147
|
+
expect(prompt).toContain("Do NOT invent changes");
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
it("injects promptRules when provided", () => {
|
|
151
|
+
const issue = { iid: 1, title: "fix: thing", labels: [] };
|
|
152
|
+
const prompt = buildProposeFixPrompt(issue, fileContents, {
|
|
153
|
+
promptRules: "Never restructure the NavBar",
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
expect(prompt).toContain("Custom rules");
|
|
157
|
+
expect(prompt).toContain("Never restructure the NavBar");
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("omits promptRules block when empty", () => {
|
|
161
|
+
const issue = { iid: 1, title: "fix: thing", labels: [] };
|
|
162
|
+
const prompt = buildProposeFixPrompt(issue, fileContents, { promptRules: "" });
|
|
163
|
+
|
|
164
|
+
expect(prompt).not.toContain("Custom rules");
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("includes CI context when provided", () => {
|
|
168
|
+
const issue = { iid: 1, title: "fix: thing", labels: [] };
|
|
169
|
+
const prompt = buildProposeFixPrompt(issue, fileContents, {
|
|
170
|
+
ciContext: "Error: Cannot find module './missing'",
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
expect(prompt).toContain("CI pipeline failure logs");
|
|
174
|
+
expect(prompt).toContain("Cannot find module");
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// ─── buildRefineOrAskPrompt ─────────────────────────────────────────────────
|
|
179
|
+
|
|
180
|
+
describe("buildRefineOrAskPrompt", () => {
|
|
181
|
+
const issue = { iid: 1, title: "fix: thing", labels: [] };
|
|
182
|
+
const fileContents = [
|
|
183
|
+
{ repo: "r", path: "src/a.ts", content: "const x = 1;" },
|
|
184
|
+
];
|
|
185
|
+
|
|
186
|
+
it("injects promptRules", () => {
|
|
187
|
+
const prompt = buildRefineOrAskPrompt(issue, fileContents, {
|
|
188
|
+
feedback: "fix the types",
|
|
189
|
+
promptRules: "Always use strict TypeScript",
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
expect(prompt).toContain("Custom rules");
|
|
193
|
+
expect(prompt).toContain("Always use strict TypeScript");
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it("omits promptRules when empty", () => {
|
|
197
|
+
const prompt = buildRefineOrAskPrompt(issue, fileContents, {
|
|
198
|
+
feedback: "fix it",
|
|
199
|
+
promptRules: "",
|
|
200
|
+
});
|
|
201
|
+
expect(prompt).not.toContain("Custom rules");
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
it("includes repo access block for tools mode", () => {
|
|
205
|
+
const prompt = buildRefineOrAskPrompt(issue, fileContents, {
|
|
206
|
+
feedback: "check types",
|
|
207
|
+
repoAccessMode: "tools",
|
|
208
|
+
});
|
|
209
|
+
expect(prompt).toContain("current working directory is a checkout");
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it("includes repo access block for tree mode", () => {
|
|
213
|
+
const prompt = buildRefineOrAskPrompt(issue, fileContents, {
|
|
214
|
+
feedback: "check types",
|
|
215
|
+
repoAccessMode: "tree",
|
|
216
|
+
});
|
|
217
|
+
expect(prompt).toContain("full file tree above");
|
|
218
|
+
});
|
|
219
|
+
});
|
|
@@ -247,13 +247,14 @@ export class AzureDevOpsProvider extends ScmProvider {
|
|
|
247
247
|
|
|
248
248
|
// ─── Repository ───────────────────────────────────────────────────────────
|
|
249
249
|
|
|
250
|
-
async getFileTree(srcPath = "
|
|
250
|
+
async getFileTree(srcPath = "", ref = this._defaultBranch) {
|
|
251
|
+
const scopeParam = srcPath ? `&$scopePath=/${srcPath}` : "";
|
|
251
252
|
const data = await this._req(
|
|
252
|
-
`${this._gitBase()}/trees/${ref}?recursive=true
|
|
253
|
+
`${this._gitBase()}/trees/${ref}?recursive=true${scopeParam}`,
|
|
253
254
|
);
|
|
254
255
|
return (data?.treeEntries ?? [])
|
|
255
256
|
.filter((item) => item.gitObjectType === "blob")
|
|
256
|
-
.filter((item) => /\.(ts|tsx|js|jsx|json|css|yaml|yml|md)$/.test(item.relativePath))
|
|
257
|
+
.filter((item) => /\.(ts|tsx|js|jsx|json|css|yaml|yml|md|go|py|rs|java|rb|sh|toml)$/.test(item.relativePath))
|
|
257
258
|
.map((item) => item.relativePath);
|
|
258
259
|
}
|
|
259
260
|
|
|
@@ -186,13 +186,12 @@ export class GitHubProvider extends ScmProvider {
|
|
|
186
186
|
|
|
187
187
|
// ─── Repository ───────────────────────────────────────────────────────────
|
|
188
188
|
|
|
189
|
-
async getFileTree(srcPath = "
|
|
190
|
-
// Use recursive tree API — much faster than walking
|
|
189
|
+
async getFileTree(srcPath = "", ref = this._defaultBranch) {
|
|
191
190
|
const data = await this._req(`/git/trees/${ref}?recursive=1`);
|
|
192
191
|
return (data.tree ?? [])
|
|
193
192
|
.filter((item) => item.type === "blob")
|
|
194
|
-
.filter((item) => item.path.startsWith(srcPath + "/") || item.path === srcPath)
|
|
195
|
-
.filter((item) => /\.(ts|tsx|js|jsx|json|css|yaml|yml|md)$/.test(item.path))
|
|
193
|
+
.filter((item) => !srcPath || item.path.startsWith(srcPath + "/") || item.path === srcPath)
|
|
194
|
+
.filter((item) => /\.(ts|tsx|js|jsx|json|css|yaml|yml|md|go|py|rs|java|rb|sh|toml)$/.test(item.path))
|
|
196
195
|
.map((item) => item.path);
|
|
197
196
|
}
|
|
198
197
|
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* GitLab REST API v4 implementation of ScmProvider.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* Token resolved via configStore.getConnection("gitlab") — set in Settings UI
|
|
7
|
+
* or via GITLAB_TOKEN env var. Project resolved via configStore.getPrimaryProject()
|
|
8
|
+
* or the constructor argument.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import { getConnection } from "../configStore.js";
|
|
11
|
+
import { getConnection, getPrimaryProject } from "../configStore.js";
|
|
12
12
|
import { ScmProvider } from "./base.js";
|
|
13
13
|
|
|
14
14
|
const CLOSING_ISSUE_RE = /\b(?:Closes|Fixes|Resolves)\s+#(\d+)/gi;
|
|
@@ -24,7 +24,7 @@ export class GitLabProvider extends ScmProvider {
|
|
|
24
24
|
/** @param {string} [project] */
|
|
25
25
|
constructor(project) {
|
|
26
26
|
super();
|
|
27
|
-
this._project = project ??
|
|
27
|
+
this._project = project ?? getPrimaryProject();
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
get name() { return "gitlab"; }
|
|
@@ -173,7 +173,7 @@ export class GitLabProvider extends ScmProvider {
|
|
|
173
173
|
|
|
174
174
|
// ─── Repository ───────────────────────────────────────────────────────────
|
|
175
175
|
|
|
176
|
-
async getFileTree(srcPath = "
|
|
176
|
+
async getFileTree(srcPath = "", ref = "main") {
|
|
177
177
|
const scan = async (pathParam) => {
|
|
178
178
|
const items = [];
|
|
179
179
|
let page = 1;
|
|
@@ -14,6 +14,7 @@ import fs from "node:fs/promises";
|
|
|
14
14
|
import os from "node:os";
|
|
15
15
|
import path from "node:path";
|
|
16
16
|
|
|
17
|
+
import { getConnection } from "../configStore.js";
|
|
17
18
|
import { runCmd } from "./cmd.js";
|
|
18
19
|
import { exists } from "./fs.js";
|
|
19
20
|
|
|
@@ -25,9 +26,9 @@ function sanitizeRepo(repo) {
|
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
function gitlabCloneUrl(project) {
|
|
28
|
-
const token =
|
|
29
|
+
const { token } = getConnection("gitlab");
|
|
29
30
|
if (!token) {
|
|
30
|
-
throw new Error("
|
|
31
|
+
throw new Error("GitLab token is required to clone the repo for validation. Set it in Settings → Connections or via GITLAB_TOKEN env var.");
|
|
31
32
|
}
|
|
32
33
|
return `https://oauth2:${token}@gitlab.com/${project}.git`;
|
|
33
34
|
}
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
28
|
import { branchNameFor } from "./branchName.js";
|
|
29
|
+
import * as configStore from "./configStore.js";
|
|
29
30
|
import { attributeChanges } from "./validator/attribute.js";
|
|
30
31
|
import { ensureClone } from "./validator/clone.js";
|
|
31
32
|
import { overlayChanges } from "./validator/overlay.js";
|
|
@@ -86,8 +87,8 @@ function resolveCandidates(analysis) {
|
|
|
86
87
|
if (fromAnalysis.length) return fromAnalysis;
|
|
87
88
|
const fromChange = analysis.changes?.[0]?.repo;
|
|
88
89
|
if (fromChange) return [fromChange];
|
|
89
|
-
const
|
|
90
|
-
return
|
|
90
|
+
const primary = configStore.getPrimaryProject();
|
|
91
|
+
return primary ? [primary] : [];
|
|
91
92
|
}
|
|
92
93
|
|
|
93
94
|
/**
|
package/server/forge/routes.js
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Express router for /api/forge/*.
|
|
5
5
|
*
|
|
6
6
|
* Required env vars:
|
|
7
|
-
* FORGE_TOKEN
|
|
8
|
-
*
|
|
9
|
-
*
|
|
7
|
+
* FORGE_TOKEN — dashboard password
|
|
8
|
+
*
|
|
9
|
+
* Project + token resolved via configStore (Settings UI) with env-var fallbacks.
|
|
10
10
|
*
|
|
11
11
|
* Multi-repo support
|
|
12
12
|
* ──────────────────
|
|
@@ -80,9 +80,9 @@ function getAvailableRepos() {
|
|
|
80
80
|
function parseRepo(req) {
|
|
81
81
|
const repos = getAvailableRepos();
|
|
82
82
|
const requested = req.query.repo ?? req.body?.repo ?? null;
|
|
83
|
-
if (!requested) return repos[0]?.id ??
|
|
83
|
+
if (!requested) return repos[0]?.id ?? configStore.getPrimaryProject();
|
|
84
84
|
const match = repos.find((r) => r.id === requested);
|
|
85
|
-
return match?.id ?? repos[0]?.id ??
|
|
85
|
+
return match?.id ?? repos[0]?.id ?? configStore.getPrimaryProject();
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
/**
|
|
@@ -177,10 +177,10 @@ router.get("/status", requireAuth, async (_req, res) => {
|
|
|
177
177
|
|
|
178
178
|
res.json({
|
|
179
179
|
ok: true,
|
|
180
|
-
project:
|
|
180
|
+
project: configStore.getPrimaryProject(),
|
|
181
181
|
repos,
|
|
182
182
|
supportsMultiRepo: repos.length > 1,
|
|
183
|
-
hasGitlabToken: Boolean(
|
|
183
|
+
hasGitlabToken: Boolean(configStore.getConnection("gitlab").token),
|
|
184
184
|
defaultModel: process.env.FORGE_MODEL ?? "claude-sonnet-4-6",
|
|
185
185
|
models,
|
|
186
186
|
agents,
|
|
@@ -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