forge-cc 1.0.0 → 1.0.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/package.json +3 -2
- package/dist/gates/codex-gate.d.ts +0 -51
- package/dist/gates/codex-gate.js +0 -121
- package/dist/gates/codex-gate.js.map +0 -1
- package/dist/gates/prd-gate.d.ts +0 -7
- package/dist/gates/prd-gate.js +0 -193
- package/dist/gates/prd-gate.js.map +0 -1
- package/dist/gates/remediation.d.ts +0 -46
- package/dist/gates/remediation.js +0 -423
- package/dist/gates/remediation.js.map +0 -1
- package/dist/gates/review-gate.d.ts +0 -16
- package/dist/gates/review-gate.js +0 -479
- package/dist/gates/review-gate.js.map +0 -1
- package/dist/gates/runtime-gate.d.ts +0 -5
- package/dist/gates/runtime-gate.js +0 -99
- package/dist/gates/runtime-gate.js.map +0 -1
- package/dist/gates/test-analysis.d.ts +0 -21
- package/dist/gates/test-analysis.js +0 -394
- package/dist/gates/test-analysis.js.map +0 -1
- package/dist/gates/visual-capture.d.ts +0 -24
- package/dist/gates/visual-capture.js +0 -144
- package/dist/gates/visual-capture.js.map +0 -1
- package/dist/gates/visual-gate.d.ts +0 -18
- package/dist/gates/visual-gate.js +0 -234
- package/dist/gates/visual-gate.js.map +0 -1
- package/dist/gates/visual-reviewer.d.ts +0 -11
- package/dist/gates/visual-reviewer.js +0 -211
- package/dist/gates/visual-reviewer.js.map +0 -1
- package/dist/go/auto-chain.d.ts +0 -136
- package/dist/go/auto-chain.js +0 -389
- package/dist/go/auto-chain.js.map +0 -1
- package/dist/go/executor.d.ts +0 -137
- package/dist/go/executor.js +0 -447
- package/dist/go/executor.js.map +0 -1
- package/dist/go/finalize.d.ts +0 -108
- package/dist/go/finalize.js +0 -331
- package/dist/go/finalize.js.map +0 -1
- package/dist/go/linear-sync-cli.d.ts +0 -55
- package/dist/go/linear-sync-cli.js +0 -192
- package/dist/go/linear-sync-cli.js.map +0 -1
- package/dist/go/linear-sync.d.ts +0 -112
- package/dist/go/linear-sync.js +0 -375
- package/dist/go/linear-sync.js.map +0 -1
- package/dist/go/prd-queue.d.ts +0 -43
- package/dist/go/prd-queue.js +0 -67
- package/dist/go/prd-queue.js.map +0 -1
- package/dist/go/prd-selector.d.ts +0 -57
- package/dist/go/prd-selector.js +0 -101
- package/dist/go/prd-selector.js.map +0 -1
- package/dist/go/verify-loop.d.ts +0 -64
- package/dist/go/verify-loop.js +0 -327
- package/dist/go/verify-loop.js.map +0 -1
- package/dist/hooks/pre-commit.d.ts +0 -5
- package/dist/hooks/pre-commit.js +0 -75
- package/dist/hooks/pre-commit.js.map +0 -1
- package/dist/linear/issues.d.ts +0 -22
- package/dist/linear/issues.js +0 -51
- package/dist/linear/issues.js.map +0 -1
- package/dist/linear/milestones.d.ts +0 -11
- package/dist/linear/milestones.js +0 -32
- package/dist/linear/milestones.js.map +0 -1
- package/dist/linear/projects.d.ts +0 -16
- package/dist/linear/projects.js +0 -51
- package/dist/linear/projects.js.map +0 -1
- package/dist/reporter/human.d.ts +0 -7
- package/dist/reporter/human.js +0 -93
- package/dist/reporter/human.js.map +0 -1
- package/dist/reporter/json.d.ts +0 -2
- package/dist/reporter/json.js +0 -4
- package/dist/reporter/json.js.map +0 -1
- package/dist/setup/structural-templates.d.ts +0 -12
- package/dist/setup/structural-templates.js +0 -288
- package/dist/setup/structural-templates.js.map +0 -1
- package/dist/setup/templates.d.ts +0 -17
- package/dist/setup/templates.js +0 -109
- package/dist/setup/templates.js.map +0 -1
- package/dist/setup/test-planner.d.ts +0 -38
- package/dist/setup/test-planner.js +0 -91
- package/dist/setup/test-planner.js.map +0 -1
- package/dist/setup/test-scaffold.d.ts +0 -31
- package/dist/setup/test-scaffold.js +0 -209
- package/dist/setup/test-scaffold.js.map +0 -1
- package/dist/setup/test-templates.d.ts +0 -37
- package/dist/setup/test-templates.js +0 -313
- package/dist/setup/test-templates.js.map +0 -1
- package/dist/spec/generator.d.ts +0 -34
- package/dist/spec/generator.js +0 -227
- package/dist/spec/generator.js.map +0 -1
- package/dist/spec/interview.d.ts +0 -142
- package/dist/spec/interview.js +0 -287
- package/dist/spec/interview.js.map +0 -1
- package/dist/spec/linear-sync.d.ts +0 -48
- package/dist/spec/linear-sync.js +0 -125
- package/dist/spec/linear-sync.js.map +0 -1
- package/dist/spec/scanner.d.ts +0 -79
- package/dist/spec/scanner.js +0 -566
- package/dist/spec/scanner.js.map +0 -1
- package/dist/spec/templates.d.ts +0 -375
- package/dist/spec/templates.js +0 -95
- package/dist/spec/templates.js.map +0 -1
- package/dist/state/prd-status.d.ts +0 -62
- package/dist/state/prd-status.js +0 -122
- package/dist/state/prd-status.js.map +0 -1
- package/dist/state/reader.d.ts +0 -7
- package/dist/state/reader.js +0 -43
- package/dist/state/reader.js.map +0 -1
- package/dist/state/writer.d.ts +0 -21
- package/dist/state/writer.js +0 -106
- package/dist/state/writer.js.map +0 -1
- package/dist/team/consensus.d.ts +0 -28
- package/dist/team/consensus.js +0 -130
- package/dist/team/consensus.js.map +0 -1
- package/dist/team/index.d.ts +0 -4
- package/dist/team/index.js +0 -5
- package/dist/team/index.js.map +0 -1
- package/dist/team/lifecycle.d.ts +0 -37
- package/dist/team/lifecycle.js +0 -92
- package/dist/team/lifecycle.js.map +0 -1
- package/dist/team/reviewer.d.ts +0 -10
- package/dist/team/reviewer.js +0 -345
- package/dist/team/reviewer.js.map +0 -1
- package/dist/team/types.d.ts +0 -269
- package/dist/team/types.js +0 -70
- package/dist/team/types.js.map +0 -1
- package/dist/utils/browser.d.ts +0 -10
- package/dist/utils/browser.js +0 -96
- package/dist/utils/browser.js.map +0 -1
- package/dist/utils/platform.d.ts +0 -29
- package/dist/utils/platform.js +0 -90
- package/dist/utils/platform.js.map +0 -1
- package/dist/worktree/identity.d.ts +0 -9
- package/dist/worktree/identity.js +0 -32
- package/dist/worktree/identity.js.map +0 -1
- package/dist/worktree/parallel.d.ts +0 -87
- package/dist/worktree/parallel.js +0 -328
- package/dist/worktree/parallel.js.map +0 -1
- package/dist/worktree/session.d.ts +0 -67
- package/dist/worktree/session.js +0 -194
- package/dist/worktree/session.js.map +0 -1
- package/dist/worktree/state-merge.d.ts +0 -43
- package/dist/worktree/state-merge.js +0 -162
- package/dist/worktree/state-merge.js.map +0 -1
|
@@ -1,394 +0,0 @@
|
|
|
1
|
-
import { readdir, readFile, stat } from "node:fs/promises";
|
|
2
|
-
import { join, relative, basename, dirname, extname } from "node:path";
|
|
3
|
-
// ---------------------------------------------------------------------------
|
|
4
|
-
// Helpers
|
|
5
|
-
// ---------------------------------------------------------------------------
|
|
6
|
-
/** Recursively collect files under a directory. */
|
|
7
|
-
async function collectFiles(dir) {
|
|
8
|
-
const results = [];
|
|
9
|
-
let entries;
|
|
10
|
-
try {
|
|
11
|
-
entries = await readdir(dir, { withFileTypes: true });
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
return results;
|
|
15
|
-
}
|
|
16
|
-
for (const entry of entries) {
|
|
17
|
-
const full = join(dir, entry.name);
|
|
18
|
-
if (entry.isDirectory()) {
|
|
19
|
-
// Skip common non-source directories
|
|
20
|
-
if (entry.name === "node_modules" ||
|
|
21
|
-
entry.name === "dist" ||
|
|
22
|
-
entry.name === ".git" ||
|
|
23
|
-
entry.name === ".next" ||
|
|
24
|
-
entry.name === "coverage") {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
results.push(...(await collectFiles(full)));
|
|
28
|
-
}
|
|
29
|
-
else if (entry.isFile()) {
|
|
30
|
-
results.push(full);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return results;
|
|
34
|
-
}
|
|
35
|
-
/** Check whether a file path is a test file. */
|
|
36
|
-
function isTestFile(filePath) {
|
|
37
|
-
const base = basename(filePath);
|
|
38
|
-
return (base.endsWith(".test.ts") ||
|
|
39
|
-
base.endsWith(".test.tsx") ||
|
|
40
|
-
base.endsWith(".spec.ts") ||
|
|
41
|
-
base.endsWith(".spec.tsx") ||
|
|
42
|
-
base.endsWith(".test.js") ||
|
|
43
|
-
base.endsWith(".test.jsx") ||
|
|
44
|
-
base.endsWith(".spec.js") ||
|
|
45
|
-
base.endsWith(".spec.jsx"));
|
|
46
|
-
}
|
|
47
|
-
/** Check whether a file is a TypeScript/JavaScript source file (not a test, not a declaration). */
|
|
48
|
-
function isSourceFile(filePath) {
|
|
49
|
-
const base = basename(filePath);
|
|
50
|
-
const ext = extname(filePath);
|
|
51
|
-
if (![".ts", ".tsx", ".js", ".jsx"].includes(ext))
|
|
52
|
-
return false;
|
|
53
|
-
if (isTestFile(filePath))
|
|
54
|
-
return false;
|
|
55
|
-
if (base.endsWith(".d.ts"))
|
|
56
|
-
return false;
|
|
57
|
-
return true;
|
|
58
|
-
}
|
|
59
|
-
/** Check whether a directory exists. */
|
|
60
|
-
async function dirExists(dirPath) {
|
|
61
|
-
try {
|
|
62
|
-
const s = await stat(dirPath);
|
|
63
|
-
return s.isDirectory();
|
|
64
|
-
}
|
|
65
|
-
catch {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/** Check whether a file exists. */
|
|
70
|
-
async function fileExists(filePath) {
|
|
71
|
-
try {
|
|
72
|
-
const s = await stat(filePath);
|
|
73
|
-
return s.isFile();
|
|
74
|
-
}
|
|
75
|
-
catch {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
/** Read and parse package.json, returning null on failure. */
|
|
80
|
-
async function readPackageJson(projectDir) {
|
|
81
|
-
try {
|
|
82
|
-
const raw = await readFile(join(projectDir, "package.json"), "utf-8");
|
|
83
|
-
return JSON.parse(raw);
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
return null;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
async function detectTestRunner(projectDir, pkg) {
|
|
90
|
-
const patterns = [];
|
|
91
|
-
const deps = (pkg?.devDependencies ?? {});
|
|
92
|
-
const allDeps = {
|
|
93
|
-
...(pkg?.dependencies ?? {}),
|
|
94
|
-
...deps,
|
|
95
|
-
};
|
|
96
|
-
// Check for vitest
|
|
97
|
-
if ("vitest" in allDeps) {
|
|
98
|
-
patterns.push("vitest in dependencies");
|
|
99
|
-
}
|
|
100
|
-
if (await fileExists(join(projectDir, "vitest.config.ts"))) {
|
|
101
|
-
patterns.push("vitest.config.ts found");
|
|
102
|
-
}
|
|
103
|
-
if (await fileExists(join(projectDir, "vitest.config.js"))) {
|
|
104
|
-
patterns.push("vitest.config.js found");
|
|
105
|
-
}
|
|
106
|
-
// Check for jest
|
|
107
|
-
if ("jest" in allDeps) {
|
|
108
|
-
patterns.push("jest in dependencies");
|
|
109
|
-
}
|
|
110
|
-
if ("ts-jest" in allDeps) {
|
|
111
|
-
patterns.push("ts-jest in dependencies");
|
|
112
|
-
}
|
|
113
|
-
if (await fileExists(join(projectDir, "jest.config.ts"))) {
|
|
114
|
-
patterns.push("jest.config.ts found");
|
|
115
|
-
}
|
|
116
|
-
if (await fileExists(join(projectDir, "jest.config.js"))) {
|
|
117
|
-
patterns.push("jest.config.js found");
|
|
118
|
-
}
|
|
119
|
-
// Check for testing-library
|
|
120
|
-
for (const dep of Object.keys(allDeps)) {
|
|
121
|
-
if (dep.startsWith("@testing-library/")) {
|
|
122
|
-
patterns.push(`${dep} in devDeps`);
|
|
123
|
-
break;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
// Determine runner
|
|
127
|
-
const hasVitest = patterns.some((p) => p.includes("vitest"));
|
|
128
|
-
const hasJest = patterns.some((p) => p.includes("jest"));
|
|
129
|
-
let runner = "none";
|
|
130
|
-
if (hasVitest)
|
|
131
|
-
runner = "vitest";
|
|
132
|
-
else if (hasJest)
|
|
133
|
-
runner = "jest";
|
|
134
|
-
return { runner, patterns };
|
|
135
|
-
}
|
|
136
|
-
async function detectAppFramework(projectDir, pkg) {
|
|
137
|
-
const patterns = [];
|
|
138
|
-
const deps = {
|
|
139
|
-
...(pkg?.dependencies ?? {}),
|
|
140
|
-
...(pkg?.devDependencies ?? {}),
|
|
141
|
-
};
|
|
142
|
-
const hasNext = "next" in deps;
|
|
143
|
-
const hasReact = "react" in deps;
|
|
144
|
-
const hasExpress = "express" in deps;
|
|
145
|
-
const hasVite = "vite" in deps;
|
|
146
|
-
if (hasNext) {
|
|
147
|
-
patterns.push("next in dependencies");
|
|
148
|
-
// Detect App Router vs Pages Router
|
|
149
|
-
const hasAppDir = await dirExists(join(projectDir, "app")) ||
|
|
150
|
-
await dirExists(join(projectDir, "src", "app"));
|
|
151
|
-
const hasPagesDir = await dirExists(join(projectDir, "pages")) ||
|
|
152
|
-
await dirExists(join(projectDir, "src", "pages"));
|
|
153
|
-
if (hasAppDir) {
|
|
154
|
-
patterns.push("app/ directory found (App Router)");
|
|
155
|
-
return { framework: "nextjs-app", patterns };
|
|
156
|
-
}
|
|
157
|
-
if (hasPagesDir) {
|
|
158
|
-
patterns.push("pages/ directory found (Pages Router)");
|
|
159
|
-
return { framework: "nextjs-pages", patterns };
|
|
160
|
-
}
|
|
161
|
-
// Next.js detected but neither router pattern found — default to app
|
|
162
|
-
return { framework: "nextjs-app", patterns };
|
|
163
|
-
}
|
|
164
|
-
if (hasReact && hasVite) {
|
|
165
|
-
patterns.push("react + vite in dependencies");
|
|
166
|
-
return { framework: "react-vite", patterns };
|
|
167
|
-
}
|
|
168
|
-
if (hasExpress) {
|
|
169
|
-
patterns.push("express in dependencies");
|
|
170
|
-
return { framework: "express", patterns };
|
|
171
|
-
}
|
|
172
|
-
// Check for TypeScript project
|
|
173
|
-
if (await fileExists(join(projectDir, "tsconfig.json"))) {
|
|
174
|
-
patterns.push("tsconfig.json found");
|
|
175
|
-
return { framework: "plain-ts", patterns };
|
|
176
|
-
}
|
|
177
|
-
return { framework: "unknown", patterns };
|
|
178
|
-
}
|
|
179
|
-
// ---------------------------------------------------------------------------
|
|
180
|
-
// File Discovery
|
|
181
|
-
// ---------------------------------------------------------------------------
|
|
182
|
-
/** Locate test directories and co-located test files. */
|
|
183
|
-
async function discoverTestFiles(projectDir) {
|
|
184
|
-
const testFiles = [];
|
|
185
|
-
const allFiles = await collectFiles(projectDir);
|
|
186
|
-
for (const f of allFiles) {
|
|
187
|
-
if (isTestFile(f)) {
|
|
188
|
-
testFiles.push(relative(projectDir, f));
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return testFiles;
|
|
192
|
-
}
|
|
193
|
-
/** Locate source files, using sourceDir as the primary search root. */
|
|
194
|
-
async function discoverSourceFiles(projectDir, sourceDir) {
|
|
195
|
-
const sourceFiles = [];
|
|
196
|
-
// Scan the source directory
|
|
197
|
-
const srcPath = join(projectDir, sourceDir);
|
|
198
|
-
if (await dirExists(srcPath)) {
|
|
199
|
-
const allFiles = await collectFiles(srcPath);
|
|
200
|
-
for (const f of allFiles) {
|
|
201
|
-
if (isSourceFile(f)) {
|
|
202
|
-
sourceFiles.push(relative(projectDir, f));
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
// Also scan app/ and pages/ for Next.js projects
|
|
207
|
-
for (const extra of ["app", "pages"]) {
|
|
208
|
-
const extraPath = join(projectDir, extra);
|
|
209
|
-
if (await dirExists(extraPath)) {
|
|
210
|
-
const allFiles = await collectFiles(extraPath);
|
|
211
|
-
for (const f of allFiles) {
|
|
212
|
-
if (isSourceFile(f)) {
|
|
213
|
-
const rel = relative(projectDir, f);
|
|
214
|
-
if (!sourceFiles.includes(rel)) {
|
|
215
|
-
sourceFiles.push(rel);
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return sourceFiles;
|
|
222
|
-
}
|
|
223
|
-
// ---------------------------------------------------------------------------
|
|
224
|
-
// Source-to-Test Mapping
|
|
225
|
-
// ---------------------------------------------------------------------------
|
|
226
|
-
/**
|
|
227
|
-
* Build a mapping from source file to its corresponding test file (if any).
|
|
228
|
-
* Tries several naming conventions:
|
|
229
|
-
* - Co-located: src/foo/bar.ts -> src/foo/bar.test.ts
|
|
230
|
-
* - Mirrored: src/foo/bar.ts -> tests/foo/bar.test.ts
|
|
231
|
-
* - __tests__: src/foo/bar.ts -> src/foo/__tests__/bar.test.ts
|
|
232
|
-
*/
|
|
233
|
-
function mapSourceToTests(sourceFiles, testFiles) {
|
|
234
|
-
const testSet = new Set(testFiles.map((t) => t.replace(/\\/g, "/")));
|
|
235
|
-
const mapping = new Map();
|
|
236
|
-
for (const src of sourceFiles) {
|
|
237
|
-
const normalized = src.replace(/\\/g, "/");
|
|
238
|
-
const dir = dirname(normalized);
|
|
239
|
-
const base = basename(normalized);
|
|
240
|
-
const nameWithoutExt = base.replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
241
|
-
const ext = extname(base);
|
|
242
|
-
const testExt = ext === ".tsx" || ext === ".jsx" ? ext : ".ts";
|
|
243
|
-
// Candidate patterns
|
|
244
|
-
const candidates = [
|
|
245
|
-
// Co-located: same directory
|
|
246
|
-
`${dir}/${nameWithoutExt}.test${testExt}`,
|
|
247
|
-
`${dir}/${nameWithoutExt}.spec${testExt}`,
|
|
248
|
-
// __tests__ subdirectory
|
|
249
|
-
`${dir}/__tests__/${nameWithoutExt}.test${testExt}`,
|
|
250
|
-
`${dir}/__tests__/${nameWithoutExt}.spec${testExt}`,
|
|
251
|
-
];
|
|
252
|
-
// Mirrored directory: replace leading source dir with common test dirs
|
|
253
|
-
const srcPrefixes = ["src/", "lib/", "app/", "pages/"];
|
|
254
|
-
const testPrefixes = ["tests/", "test/", "__tests__/"];
|
|
255
|
-
for (const sp of srcPrefixes) {
|
|
256
|
-
if (normalized.startsWith(sp)) {
|
|
257
|
-
const rest = normalized.slice(sp.length);
|
|
258
|
-
const restDir = dirname(rest);
|
|
259
|
-
const restBase = basename(rest).replace(/\.(ts|tsx|js|jsx)$/, "");
|
|
260
|
-
for (const tp of testPrefixes) {
|
|
261
|
-
candidates.push(`${tp}${restDir}/${restBase}.test${testExt}`, `${tp}${restDir}/${restBase}.spec${testExt}`, `${tp}${restBase}.test${testExt}`, `${tp}${restBase}.spec${testExt}`);
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
let matched = null;
|
|
266
|
-
for (const c of candidates) {
|
|
267
|
-
// Normalize candidate (handle ./ prefix from dirname of top-level files)
|
|
268
|
-
const clean = c.replace(/^\.\//, "");
|
|
269
|
-
if (testSet.has(clean)) {
|
|
270
|
-
matched = clean;
|
|
271
|
-
break;
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
mapping.set(normalized, matched);
|
|
275
|
-
}
|
|
276
|
-
return mapping;
|
|
277
|
-
}
|
|
278
|
-
function categorizeFile(filePath) {
|
|
279
|
-
const normalized = filePath.replace(/\\/g, "/");
|
|
280
|
-
const parts = normalized.split("/");
|
|
281
|
-
const base = basename(normalized);
|
|
282
|
-
const ext = extname(normalized);
|
|
283
|
-
// API routes
|
|
284
|
-
if (parts.includes("api") ||
|
|
285
|
-
parts.includes("routes") ||
|
|
286
|
-
normalized.includes("app/api/") ||
|
|
287
|
-
normalized.includes("pages/api/")) {
|
|
288
|
-
return "api-routes";
|
|
289
|
-
}
|
|
290
|
-
// Middleware
|
|
291
|
-
if (base.startsWith("middleware") ||
|
|
292
|
-
parts.includes("middleware")) {
|
|
293
|
-
return "middleware";
|
|
294
|
-
}
|
|
295
|
-
// Models / schemas / entities
|
|
296
|
-
if (parts.includes("models") ||
|
|
297
|
-
parts.includes("schemas") ||
|
|
298
|
-
parts.includes("entities")) {
|
|
299
|
-
return "models";
|
|
300
|
-
}
|
|
301
|
-
// Components: .tsx files or in components/ directory
|
|
302
|
-
if (parts.includes("components") || ext === ".tsx") {
|
|
303
|
-
return "components";
|
|
304
|
-
}
|
|
305
|
-
// Utils / lib / helpers
|
|
306
|
-
if (parts.includes("utils") ||
|
|
307
|
-
parts.includes("lib") ||
|
|
308
|
-
parts.includes("helpers")) {
|
|
309
|
-
return "utils";
|
|
310
|
-
}
|
|
311
|
-
return "other";
|
|
312
|
-
}
|
|
313
|
-
function buildCategories(sourceFiles, mapping) {
|
|
314
|
-
const buckets = new Map();
|
|
315
|
-
for (const src of sourceFiles) {
|
|
316
|
-
const normalized = src.replace(/\\/g, "/");
|
|
317
|
-
const cat = categorizeFile(normalized);
|
|
318
|
-
if (!buckets.has(cat)) {
|
|
319
|
-
buckets.set(cat, { sources: [], tests: [], untested: [] });
|
|
320
|
-
}
|
|
321
|
-
const bucket = buckets.get(cat);
|
|
322
|
-
bucket.sources.push(normalized);
|
|
323
|
-
const testFile = mapping.get(normalized);
|
|
324
|
-
if (testFile) {
|
|
325
|
-
bucket.tests.push(testFile);
|
|
326
|
-
}
|
|
327
|
-
else {
|
|
328
|
-
bucket.untested.push(normalized);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
// Sort categories in a stable order
|
|
332
|
-
const order = [
|
|
333
|
-
"api-routes",
|
|
334
|
-
"components",
|
|
335
|
-
"utils",
|
|
336
|
-
"middleware",
|
|
337
|
-
"models",
|
|
338
|
-
"other",
|
|
339
|
-
];
|
|
340
|
-
const categories = [];
|
|
341
|
-
for (const name of order) {
|
|
342
|
-
const bucket = buckets.get(name);
|
|
343
|
-
if (bucket && bucket.sources.length > 0) {
|
|
344
|
-
categories.push({
|
|
345
|
-
name,
|
|
346
|
-
sourceFiles: bucket.sources.sort(),
|
|
347
|
-
testFiles: bucket.tests.sort(),
|
|
348
|
-
untestedFiles: bucket.untested.sort(),
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
return categories;
|
|
353
|
-
}
|
|
354
|
-
// ---------------------------------------------------------------------------
|
|
355
|
-
// Main
|
|
356
|
-
// ---------------------------------------------------------------------------
|
|
357
|
-
export async function analyzeTestCoverage(projectDir) {
|
|
358
|
-
const pkg = await readPackageJson(projectDir);
|
|
359
|
-
// Detect frameworks
|
|
360
|
-
const { runner, patterns: runnerPatterns } = await detectTestRunner(projectDir, pkg);
|
|
361
|
-
const { framework, patterns: frameworkPatterns } = await detectAppFramework(projectDir, pkg);
|
|
362
|
-
const detectedPatterns = [...runnerPatterns, ...frameworkPatterns];
|
|
363
|
-
// Discover files
|
|
364
|
-
const sourceDir = "src";
|
|
365
|
-
const sourceFiles = await discoverSourceFiles(projectDir, sourceDir);
|
|
366
|
-
const testFiles = await discoverTestFiles(projectDir);
|
|
367
|
-
// Build mapping
|
|
368
|
-
const mapping = mapSourceToTests(sourceFiles, testFiles);
|
|
369
|
-
// Compute coverage
|
|
370
|
-
const untestedFiles = [];
|
|
371
|
-
for (const [src, test] of mapping) {
|
|
372
|
-
if (!test) {
|
|
373
|
-
untestedFiles.push(src);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
const ratio = sourceFiles.length > 0 ? testFiles.length / sourceFiles.length : 0;
|
|
377
|
-
// Build categories
|
|
378
|
-
const categories = buildCategories(sourceFiles, mapping);
|
|
379
|
-
return {
|
|
380
|
-
framework: {
|
|
381
|
-
testRunner: runner,
|
|
382
|
-
appFramework: framework,
|
|
383
|
-
detectedPatterns,
|
|
384
|
-
},
|
|
385
|
-
coverage: {
|
|
386
|
-
sourceFiles: sourceFiles.length,
|
|
387
|
-
testFiles: testFiles.length,
|
|
388
|
-
ratio: Math.round(ratio * 100) / 100,
|
|
389
|
-
untestedFiles: untestedFiles.sort(),
|
|
390
|
-
},
|
|
391
|
-
categories,
|
|
392
|
-
};
|
|
393
|
-
}
|
|
394
|
-
//# sourceMappingURL=test-analysis.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"test-analysis.js","sourceRoot":"","sources":["../../src/gates/test-analysis.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import type { Page } from "playwright";
|
|
2
|
-
import type { ViewportConfig, VisualCaptureResult } from "../types.js";
|
|
3
|
-
/** Default viewports for multi-viewport capture: desktop, tablet, mobile */
|
|
4
|
-
export declare const DEFAULT_VIEWPORTS: ViewportConfig[];
|
|
5
|
-
/** Options for the visual capture function */
|
|
6
|
-
export interface CaptureOptions {
|
|
7
|
-
pagePath: string;
|
|
8
|
-
screenshotDir: string;
|
|
9
|
-
viewports?: ViewportConfig[];
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Capture multi-viewport screenshots and extract DOM structure from a Playwright page.
|
|
13
|
-
*
|
|
14
|
-
* For each viewport in the configuration:
|
|
15
|
-
* 1. Resizes the viewport via page.setViewportSize()
|
|
16
|
-
* 2. Waits for layout to settle (500ms)
|
|
17
|
-
* 3. Takes a full-page screenshot saved as {safeName}_{viewportName}.png
|
|
18
|
-
* 4. Extracts the serialized DOM tree via page.evaluate()
|
|
19
|
-
*
|
|
20
|
-
* @param page - Playwright Page instance (already navigated to the target URL)
|
|
21
|
-
* @param options - Capture configuration including page path, screenshot dir, and optional viewports
|
|
22
|
-
* @returns VisualCaptureResult with screenshots array, DOM snapshots per viewport, and metadata
|
|
23
|
-
*/
|
|
24
|
-
export declare function captureVisual(page: Page, options: CaptureOptions): Promise<VisualCaptureResult>;
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
import { mkdirSync } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
/** Default viewports for multi-viewport capture: desktop, tablet, mobile */
|
|
4
|
-
export const DEFAULT_VIEWPORTS = [
|
|
5
|
-
{ name: "desktop", width: 1280, height: 800 },
|
|
6
|
-
{ name: "tablet", width: 768, height: 1024 },
|
|
7
|
-
{ name: "mobile", width: 390, height: 844 },
|
|
8
|
-
];
|
|
9
|
-
/**
|
|
10
|
-
* Sanitize a page path into a safe filename component.
|
|
11
|
-
* Replaces slashes with underscores and strips leading underscores.
|
|
12
|
-
* Falls back to "index" for root path.
|
|
13
|
-
*/
|
|
14
|
-
function sanitizePageName(pagePath) {
|
|
15
|
-
const sanitized = pagePath.replace(/\//g, "_").replace(/^_/, "");
|
|
16
|
-
return sanitized || "index";
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Extract DOM snapshot from the page via page.evaluate().
|
|
20
|
-
* The entire extraction logic runs inside the browser context so it must be
|
|
21
|
-
* self-contained -- no references to Node.js modules or TypeScript types.
|
|
22
|
-
*/
|
|
23
|
-
async function extractDOM(page) {
|
|
24
|
-
return await page.evaluate(() => {
|
|
25
|
-
function walkElement(el, isTopLevel) {
|
|
26
|
-
const style = window.getComputedStyle(el);
|
|
27
|
-
const visible = style.display !== "none" &&
|
|
28
|
-
style.visibility !== "hidden" &&
|
|
29
|
-
style.opacity !== "0";
|
|
30
|
-
const node = {
|
|
31
|
-
tag: el.tagName.toLowerCase(),
|
|
32
|
-
visible,
|
|
33
|
-
children: [],
|
|
34
|
-
};
|
|
35
|
-
if (el.id) {
|
|
36
|
-
node.id = el.id;
|
|
37
|
-
}
|
|
38
|
-
if (el.className &&
|
|
39
|
-
typeof el.className === "string" &&
|
|
40
|
-
el.className.trim()) {
|
|
41
|
-
node.className = el.className.trim();
|
|
42
|
-
}
|
|
43
|
-
// Only capture bounding rect for top-level elements to limit payload size
|
|
44
|
-
if (isTopLevel) {
|
|
45
|
-
const rect = el.getBoundingClientRect();
|
|
46
|
-
node.rect = {
|
|
47
|
-
x: Math.round(rect.x),
|
|
48
|
-
y: Math.round(rect.y),
|
|
49
|
-
width: Math.round(rect.width),
|
|
50
|
-
height: Math.round(rect.height),
|
|
51
|
-
};
|
|
52
|
-
}
|
|
53
|
-
const childElements = el.children;
|
|
54
|
-
for (let i = 0; i < childElements.length; i++) {
|
|
55
|
-
node.children.push(walkElement(childElements[i], false));
|
|
56
|
-
}
|
|
57
|
-
return node;
|
|
58
|
-
}
|
|
59
|
-
const body = document.body;
|
|
60
|
-
if (!body) {
|
|
61
|
-
return { tag: "body", visible: true, children: [] };
|
|
62
|
-
}
|
|
63
|
-
const snapshot = {
|
|
64
|
-
tag: "body",
|
|
65
|
-
visible: true,
|
|
66
|
-
children: [],
|
|
67
|
-
};
|
|
68
|
-
if (body.id) {
|
|
69
|
-
snapshot.id = body.id;
|
|
70
|
-
}
|
|
71
|
-
if (body.className &&
|
|
72
|
-
typeof body.className === "string" &&
|
|
73
|
-
body.className.trim()) {
|
|
74
|
-
snapshot.className = body.className.trim();
|
|
75
|
-
}
|
|
76
|
-
const childElements = body.children;
|
|
77
|
-
for (let i = 0; i < childElements.length; i++) {
|
|
78
|
-
snapshot.children.push(walkElement(childElements[i], true));
|
|
79
|
-
}
|
|
80
|
-
return snapshot;
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Capture multi-viewport screenshots and extract DOM structure from a Playwright page.
|
|
85
|
-
*
|
|
86
|
-
* For each viewport in the configuration:
|
|
87
|
-
* 1. Resizes the viewport via page.setViewportSize()
|
|
88
|
-
* 2. Waits for layout to settle (500ms)
|
|
89
|
-
* 3. Takes a full-page screenshot saved as {safeName}_{viewportName}.png
|
|
90
|
-
* 4. Extracts the serialized DOM tree via page.evaluate()
|
|
91
|
-
*
|
|
92
|
-
* @param page - Playwright Page instance (already navigated to the target URL)
|
|
93
|
-
* @param options - Capture configuration including page path, screenshot dir, and optional viewports
|
|
94
|
-
* @returns VisualCaptureResult with screenshots array, DOM snapshots per viewport, and metadata
|
|
95
|
-
*/
|
|
96
|
-
export async function captureVisual(page, options) {
|
|
97
|
-
const start = Date.now();
|
|
98
|
-
const viewports = options.viewports ?? DEFAULT_VIEWPORTS;
|
|
99
|
-
const safeName = sanitizePageName(options.pagePath);
|
|
100
|
-
mkdirSync(options.screenshotDir, { recursive: true });
|
|
101
|
-
const screenshots = [];
|
|
102
|
-
const domSnapshots = {};
|
|
103
|
-
for (const viewport of viewports) {
|
|
104
|
-
try {
|
|
105
|
-
// Resize viewport
|
|
106
|
-
await page.setViewportSize({
|
|
107
|
-
width: viewport.width,
|
|
108
|
-
height: viewport.height,
|
|
109
|
-
});
|
|
110
|
-
// Wait for layout to settle after resize
|
|
111
|
-
await page.waitForTimeout(500);
|
|
112
|
-
// Take full-page screenshot
|
|
113
|
-
const screenshotPath = join(options.screenshotDir, `${safeName}_${viewport.name}.png`);
|
|
114
|
-
try {
|
|
115
|
-
await page.screenshot({ path: screenshotPath, fullPage: true });
|
|
116
|
-
screenshots.push({
|
|
117
|
-
page: options.pagePath,
|
|
118
|
-
viewport: viewport.name,
|
|
119
|
-
path: screenshotPath,
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
catch {
|
|
123
|
-
// Screenshot failed for this viewport — skip it but continue
|
|
124
|
-
}
|
|
125
|
-
// Extract DOM snapshot
|
|
126
|
-
const domSnapshot = await extractDOM(page);
|
|
127
|
-
domSnapshots[viewport.name] = domSnapshot;
|
|
128
|
-
}
|
|
129
|
-
catch {
|
|
130
|
-
// Viewport resize or other operation failed — skip this viewport entirely
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
return {
|
|
134
|
-
screenshots,
|
|
135
|
-
domSnapshots,
|
|
136
|
-
metadata: {
|
|
137
|
-
viewports,
|
|
138
|
-
pagePath: options.pagePath,
|
|
139
|
-
capturedAt: new Date().toISOString(),
|
|
140
|
-
durationMs: Date.now() - start,
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
//# sourceMappingURL=visual-capture.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"visual-capture.js","sourceRoot":"","sources":["../../src/gates/visual-capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { VisualResult } from "../types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Capture and store "before" snapshots for the given pages.
|
|
4
|
-
* Snapshots are persisted to disk (.forge/screenshots/before/*.snapshot.json)
|
|
5
|
-
* so they survive across separate CLI invocations.
|
|
6
|
-
*/
|
|
7
|
-
export declare function captureBeforeSnapshots(projectDir: string, pages: string[], options?: {
|
|
8
|
-
devServerCommand?: string;
|
|
9
|
-
devServerPort?: number;
|
|
10
|
-
screenshotDir?: string;
|
|
11
|
-
}): Promise<void>;
|
|
12
|
-
/** Clear all stored "before" snapshots from disk (e.g. between milestones). */
|
|
13
|
-
export declare function clearBeforeSnapshots(projectDir: string): void;
|
|
14
|
-
export declare function verifyVisual(projectDir: string, pages: string[], options?: {
|
|
15
|
-
devServerCommand?: string;
|
|
16
|
-
devServerPort?: number;
|
|
17
|
-
screenshotDir?: string;
|
|
18
|
-
}): Promise<VisualResult>;
|