forge-cc 0.1.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.
Files changed (105) hide show
  1. package/.forge.json +5 -0
  2. package/AGENTS.md +42 -0
  3. package/README.md +283 -0
  4. package/dist/cli.d.ts +2 -0
  5. package/dist/cli.js +148 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/config/loader.d.ts +2 -0
  8. package/dist/config/loader.js +44 -0
  9. package/dist/config/loader.js.map +1 -0
  10. package/dist/config/schema.d.ts +57 -0
  11. package/dist/config/schema.js +15 -0
  12. package/dist/config/schema.js.map +1 -0
  13. package/dist/gates/index.d.ts +11 -0
  14. package/dist/gates/index.js +106 -0
  15. package/dist/gates/index.js.map +1 -0
  16. package/dist/gates/lint-gate.d.ts +2 -0
  17. package/dist/gates/lint-gate.js +66 -0
  18. package/dist/gates/lint-gate.js.map +1 -0
  19. package/dist/gates/prd-gate.d.ts +7 -0
  20. package/dist/gates/prd-gate.js +193 -0
  21. package/dist/gates/prd-gate.js.map +1 -0
  22. package/dist/gates/runtime-gate.d.ts +5 -0
  23. package/dist/gates/runtime-gate.js +99 -0
  24. package/dist/gates/runtime-gate.js.map +1 -0
  25. package/dist/gates/tests-gate.d.ts +2 -0
  26. package/dist/gates/tests-gate.js +116 -0
  27. package/dist/gates/tests-gate.js.map +1 -0
  28. package/dist/gates/types-gate.d.ts +2 -0
  29. package/dist/gates/types-gate.js +59 -0
  30. package/dist/gates/types-gate.js.map +1 -0
  31. package/dist/gates/visual-gate.d.ts +6 -0
  32. package/dist/gates/visual-gate.js +118 -0
  33. package/dist/gates/visual-gate.js.map +1 -0
  34. package/dist/go/auto-chain.d.ts +107 -0
  35. package/dist/go/auto-chain.js +303 -0
  36. package/dist/go/auto-chain.js.map +1 -0
  37. package/dist/go/executor.d.ts +130 -0
  38. package/dist/go/executor.js +409 -0
  39. package/dist/go/executor.js.map +1 -0
  40. package/dist/go/finalize.d.ts +58 -0
  41. package/dist/go/finalize.js +200 -0
  42. package/dist/go/finalize.js.map +1 -0
  43. package/dist/go/linear-sync.d.ts +75 -0
  44. package/dist/go/linear-sync.js +239 -0
  45. package/dist/go/linear-sync.js.map +1 -0
  46. package/dist/go/verify-loop.d.ts +47 -0
  47. package/dist/go/verify-loop.js +172 -0
  48. package/dist/go/verify-loop.js.map +1 -0
  49. package/dist/hooks/pre-commit.d.ts +5 -0
  50. package/dist/hooks/pre-commit.js +69 -0
  51. package/dist/hooks/pre-commit.js.map +1 -0
  52. package/dist/linear/client.d.ts +108 -0
  53. package/dist/linear/client.js +388 -0
  54. package/dist/linear/client.js.map +1 -0
  55. package/dist/linear/issues.d.ts +20 -0
  56. package/dist/linear/issues.js +39 -0
  57. package/dist/linear/issues.js.map +1 -0
  58. package/dist/linear/milestones.d.ts +11 -0
  59. package/dist/linear/milestones.js +32 -0
  60. package/dist/linear/milestones.js.map +1 -0
  61. package/dist/linear/projects.d.ts +16 -0
  62. package/dist/linear/projects.js +50 -0
  63. package/dist/linear/projects.js.map +1 -0
  64. package/dist/reporter/human.d.ts +2 -0
  65. package/dist/reporter/human.js +63 -0
  66. package/dist/reporter/human.js.map +1 -0
  67. package/dist/reporter/json.d.ts +2 -0
  68. package/dist/reporter/json.js +4 -0
  69. package/dist/reporter/json.js.map +1 -0
  70. package/dist/server.d.ts +2 -0
  71. package/dist/server.js +109 -0
  72. package/dist/server.js.map +1 -0
  73. package/dist/spec/generator.d.ts +14 -0
  74. package/dist/spec/generator.js +206 -0
  75. package/dist/spec/generator.js.map +1 -0
  76. package/dist/spec/interview.d.ts +104 -0
  77. package/dist/spec/interview.js +342 -0
  78. package/dist/spec/interview.js.map +1 -0
  79. package/dist/spec/linear-sync.d.ts +48 -0
  80. package/dist/spec/linear-sync.js +125 -0
  81. package/dist/spec/linear-sync.js.map +1 -0
  82. package/dist/spec/scanner.d.ts +45 -0
  83. package/dist/spec/scanner.js +473 -0
  84. package/dist/spec/scanner.js.map +1 -0
  85. package/dist/spec/templates.d.ts +345 -0
  86. package/dist/spec/templates.js +86 -0
  87. package/dist/spec/templates.js.map +1 -0
  88. package/dist/state/reader.d.ts +29 -0
  89. package/dist/state/reader.js +116 -0
  90. package/dist/state/reader.js.map +1 -0
  91. package/dist/state/writer.d.ts +60 -0
  92. package/dist/state/writer.js +222 -0
  93. package/dist/state/writer.js.map +1 -0
  94. package/dist/types.d.ts +64 -0
  95. package/dist/types.js +2 -0
  96. package/dist/types.js.map +1 -0
  97. package/dist/utils/browser.d.ts +10 -0
  98. package/dist/utils/browser.js +89 -0
  99. package/dist/utils/browser.js.map +1 -0
  100. package/hooks/pre-commit-verify.js +103 -0
  101. package/package.json +68 -0
  102. package/skills/README.md +33 -0
  103. package/skills/forge-go.md +332 -0
  104. package/skills/forge-spec.md +251 -0
  105. package/skills/forge-triage.md +133 -0
@@ -0,0 +1,473 @@
1
+ import { readdir, readFile, stat } from "node:fs/promises";
2
+ import { join, relative, extname, basename } from "node:path";
3
+ // ── Helpers ────────────────────────────────────────────────────────────────
4
+ const IGNORE_DIRS = new Set([
5
+ "node_modules", ".git", "dist", "build", ".next", ".nuxt",
6
+ ".svelte-kit", ".output", "coverage", ".turbo", ".cache",
7
+ ]);
8
+ async function exists(p) {
9
+ try {
10
+ await stat(p);
11
+ return true;
12
+ }
13
+ catch {
14
+ return false;
15
+ }
16
+ }
17
+ async function readJson(p) {
18
+ try {
19
+ const raw = await readFile(p, "utf-8");
20
+ return JSON.parse(raw);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ async function walkDir(dir, base, maxDepth, depth = 0) {
27
+ if (depth > maxDepth)
28
+ return [];
29
+ let entries;
30
+ try {
31
+ const items = await readdir(dir, { withFileTypes: true });
32
+ entries = [];
33
+ for (const item of items) {
34
+ const full = join(dir, item.name);
35
+ const rel = relative(base, full);
36
+ if (item.isDirectory()) {
37
+ if (!IGNORE_DIRS.has(item.name)) {
38
+ entries.push(rel + "/");
39
+ const sub = await walkDir(full, base, maxDepth, depth + 1);
40
+ entries.push(...sub);
41
+ }
42
+ }
43
+ else {
44
+ entries.push(rel);
45
+ }
46
+ }
47
+ }
48
+ catch {
49
+ entries = [];
50
+ }
51
+ return entries;
52
+ }
53
+ const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".vue", ".svelte"]);
54
+ function isCodeFile(file) {
55
+ return CODE_EXTS.has(extname(file));
56
+ }
57
+ // ── Structure Scan ─────────────────────────────────────────────────────────
58
+ const FRAMEWORK_MARKERS = {
59
+ next: "Next.js",
60
+ nuxt: "Nuxt",
61
+ "react-dom": "React",
62
+ vue: "Vue",
63
+ svelte: "Svelte",
64
+ "@sveltejs/kit": "SvelteKit",
65
+ angular: "Angular",
66
+ "@angular/core": "Angular",
67
+ express: "Express",
68
+ fastify: "Fastify",
69
+ hono: "Hono",
70
+ koa: "Koa",
71
+ "react-native": "React Native",
72
+ expo: "Expo",
73
+ electron: "Electron",
74
+ astro: "Astro",
75
+ remix: "Remix",
76
+ gatsby: "Gatsby",
77
+ "@nestjs/core": "NestJS",
78
+ };
79
+ const CONFIG_FILES = [
80
+ "tsconfig.json", "jsconfig.json",
81
+ "tailwind.config.ts", "tailwind.config.js", "tailwind.config.mjs",
82
+ "postcss.config.js", "postcss.config.mjs",
83
+ "vite.config.ts", "vite.config.js",
84
+ "next.config.ts", "next.config.js", "next.config.mjs",
85
+ "nuxt.config.ts",
86
+ "svelte.config.js",
87
+ "astro.config.mjs",
88
+ ".env", ".env.local", ".env.example",
89
+ "docker-compose.yml", "Dockerfile",
90
+ ".eslintrc.json", ".eslintrc.js", "eslint.config.js", "eslint.config.mjs",
91
+ "biome.json", "biome.jsonc",
92
+ "vitest.config.ts", "jest.config.ts", "jest.config.js",
93
+ "playwright.config.ts",
94
+ ".prettierrc", ".prettierrc.json",
95
+ "drizzle.config.ts", "prisma/schema.prisma",
96
+ ];
97
+ const ENTRY_CANDIDATES = [
98
+ "src/index.ts", "src/index.tsx", "src/main.ts", "src/main.tsx",
99
+ "src/app.ts", "src/app.tsx", "src/server.ts",
100
+ "index.ts", "index.js", "app.ts", "server.ts",
101
+ "src/index.js", "src/main.js", "src/app.js",
102
+ ];
103
+ export async function scanStructure(projectDir) {
104
+ const pkg = await readJson(join(projectDir, "package.json"));
105
+ // Project name
106
+ const projectName = pkg?.name || basename(projectDir);
107
+ // Detect frameworks from dependencies
108
+ const allDeps = {
109
+ ...(typeof pkg?.dependencies === "object" ? pkg.dependencies : {}),
110
+ ...(typeof pkg?.devDependencies === "object" ? pkg.devDependencies : {}),
111
+ };
112
+ const frameworks = [];
113
+ for (const [dep, label] of Object.entries(FRAMEWORK_MARKERS)) {
114
+ if (dep in allDeps) {
115
+ frameworks.push(label);
116
+ }
117
+ }
118
+ // Deduplicate (e.g. React appears via react-dom and next)
119
+ const uniqueFrameworks = [...new Set(frameworks)];
120
+ // Language
121
+ const hasTs = await exists(join(projectDir, "tsconfig.json"));
122
+ const language = hasTs
123
+ ? "typescript"
124
+ : pkg ? "javascript" : "unknown";
125
+ // Package manager
126
+ let packageManager = "unknown";
127
+ if (await exists(join(projectDir, "bun.lockb")) || await exists(join(projectDir, "bun.lock"))) {
128
+ packageManager = "bun";
129
+ }
130
+ else if (await exists(join(projectDir, "pnpm-lock.yaml"))) {
131
+ packageManager = "pnpm";
132
+ }
133
+ else if (await exists(join(projectDir, "yarn.lock"))) {
134
+ packageManager = "yarn";
135
+ }
136
+ else if (await exists(join(projectDir, "package-lock.json"))) {
137
+ packageManager = "npm";
138
+ }
139
+ // Config files present
140
+ const configFiles = [];
141
+ for (const cf of CONFIG_FILES) {
142
+ if (await exists(join(projectDir, cf))) {
143
+ configFiles.push(cf);
144
+ }
145
+ }
146
+ // Top-level directories
147
+ const topLevelDirs = [];
148
+ try {
149
+ const items = await readdir(projectDir, { withFileTypes: true });
150
+ for (const item of items) {
151
+ if (item.isDirectory() && !IGNORE_DIRS.has(item.name) && !item.name.startsWith(".")) {
152
+ topLevelDirs.push(item.name);
153
+ }
154
+ }
155
+ }
156
+ catch { /* empty */ }
157
+ // Entry points
158
+ const entryPoints = [];
159
+ for (const ep of ENTRY_CANDIDATES) {
160
+ if (await exists(join(projectDir, ep))) {
161
+ entryPoints.push(ep);
162
+ }
163
+ }
164
+ return {
165
+ projectName,
166
+ frameworks: uniqueFrameworks,
167
+ language,
168
+ packageManager,
169
+ configFiles,
170
+ topLevelDirs,
171
+ entryPoints,
172
+ };
173
+ }
174
+ // ── Routes / UI Scan ───────────────────────────────────────────────────────
175
+ const ROUTE_DIRS = [
176
+ { dir: "app", framework: "Next.js (App Router)" },
177
+ { dir: "pages", framework: "Next.js (Pages Router)" },
178
+ { dir: "src/app", framework: "Next.js (App Router)" },
179
+ { dir: "src/pages", framework: "Next.js (Pages Router)" },
180
+ { dir: "src/routes", framework: "SvelteKit/Remix" },
181
+ { dir: "routes", framework: "Remix" },
182
+ { dir: "src/views", framework: "Vue" },
183
+ { dir: "src/screens", framework: "React Native" },
184
+ ];
185
+ const COMPONENT_DIRS = [
186
+ "src/components", "components", "src/ui", "ui",
187
+ "src/features", "src/modules",
188
+ ];
189
+ function classifyRouteFile(filePath) {
190
+ const name = basename(filePath).toLowerCase();
191
+ if (name.startsWith("layout"))
192
+ return "layout";
193
+ if (name.startsWith("middleware") || name === "_middleware.ts" || name === "_middleware.js")
194
+ return "middleware";
195
+ if (filePath.includes("/api/") || filePath.includes("\\api\\"))
196
+ return "api";
197
+ return "page";
198
+ }
199
+ function fileToRoutePath(file, routeDir) {
200
+ let route = file
201
+ .replace(routeDir, "")
202
+ .replace(/\\/g, "/");
203
+ // Strip file extension
204
+ route = route.replace(/\.(ts|tsx|js|jsx|vue|svelte)$/, "");
205
+ // Strip index suffix
206
+ route = route.replace(/\/index$/, "") || "/";
207
+ // Strip Next.js page.tsx pattern
208
+ route = route.replace(/\/page$/, "") || "/";
209
+ return route;
210
+ }
211
+ export async function scanRoutes(projectDir) {
212
+ let framework = null;
213
+ let routeDir = null;
214
+ const routes = [];
215
+ // Find the route directory
216
+ for (const candidate of ROUTE_DIRS) {
217
+ const fullPath = join(projectDir, candidate.dir);
218
+ if (await exists(fullPath)) {
219
+ framework = candidate.framework;
220
+ routeDir = candidate.dir;
221
+ break;
222
+ }
223
+ }
224
+ // Scan routes if found
225
+ if (routeDir) {
226
+ const fullRouteDir = join(projectDir, routeDir);
227
+ const files = await walkDir(fullRouteDir, fullRouteDir, 5);
228
+ for (const file of files) {
229
+ if (file.endsWith("/"))
230
+ continue; // skip directories
231
+ if (!isCodeFile(file))
232
+ continue;
233
+ const name = basename(file).toLowerCase();
234
+ // Skip test files and non-route utilities
235
+ if (name.includes(".test.") || name.includes(".spec.") || name.startsWith("_"))
236
+ continue;
237
+ const type = classifyRouteFile(file);
238
+ routes.push({
239
+ path: fileToRoutePath(file, ""),
240
+ file: join(routeDir, file),
241
+ type,
242
+ });
243
+ }
244
+ }
245
+ // Scan component directories
246
+ const components = [];
247
+ for (const compDir of COMPONENT_DIRS) {
248
+ const fullPath = join(projectDir, compDir);
249
+ if (!(await exists(fullPath)))
250
+ continue;
251
+ const files = await walkDir(fullPath, fullPath, 3);
252
+ for (const file of files) {
253
+ if (file.endsWith("/"))
254
+ continue;
255
+ if (!isCodeFile(file))
256
+ continue;
257
+ const name = basename(file).toLowerCase();
258
+ if (name.includes(".test.") || name.includes(".spec."))
259
+ continue;
260
+ components.push(join(compDir, file));
261
+ }
262
+ }
263
+ return { framework, routeDir, routes, components };
264
+ }
265
+ // ── Data / APIs Scan ───────────────────────────────────────────────────────
266
+ const API_DIRS = [
267
+ "src/api", "api", "src/server", "server",
268
+ "src/controllers", "controllers",
269
+ "src/handlers", "handlers",
270
+ "app/api", "pages/api", "src/app/api", "src/pages/api",
271
+ ];
272
+ const HTTP_METHOD_RE = /\.(get|post|put|patch|delete|all)\s*\(/gi;
273
+ const ROUTE_STRING_RE = /['"`](\/[a-zA-Z0-9/:_\-.*[\]{}]*?)['"`]/g;
274
+ async function extractAPIEndpoints(projectDir, filePath) {
275
+ const endpoints = [];
276
+ try {
277
+ const content = await readFile(join(projectDir, filePath), "utf-8");
278
+ // Check for HTTP method patterns (Express/Hono/Fastify style)
279
+ let match;
280
+ const methodRe = new RegExp(HTTP_METHOD_RE.source, "gi");
281
+ while ((match = methodRe.exec(content)) !== null) {
282
+ const method = match[1].toUpperCase();
283
+ // Try to find route string near this match
284
+ const nearby = content.slice(Math.max(0, match.index - 100), match.index + 200);
285
+ const routeMatch = ROUTE_STRING_RE.exec(nearby);
286
+ ROUTE_STRING_RE.lastIndex = 0;
287
+ endpoints.push({
288
+ method,
289
+ path: routeMatch ? routeMatch[1] : "(dynamic)",
290
+ file: filePath,
291
+ });
292
+ }
293
+ // Next.js API route convention: file path IS the route
294
+ if (filePath.includes("/api/")) {
295
+ const routePath = "/" + filePath
296
+ .replace(/.*\/api\//, "api/")
297
+ .replace(/\.(ts|tsx|js|jsx)$/, "")
298
+ .replace(/\/route$/, "")
299
+ .replace(/\/index$/, "");
300
+ // Check for exported HTTP methods (Next.js App Router)
301
+ const exportedMethods = ["GET", "POST", "PUT", "PATCH", "DELETE"];
302
+ for (const m of exportedMethods) {
303
+ if (content.includes(`export function ${m}`) || content.includes(`export async function ${m}`)) {
304
+ endpoints.push({ method: m, path: routePath, file: filePath });
305
+ }
306
+ }
307
+ // If no explicit methods found, add a generic entry
308
+ if (endpoints.filter(e => e.file === filePath).length === 0) {
309
+ endpoints.push({ method: "ANY", path: routePath, file: filePath });
310
+ }
311
+ }
312
+ }
313
+ catch { /* unreadable file */ }
314
+ return endpoints;
315
+ }
316
+ const PRISMA_MODEL_RE = /^model\s+(\w+)/gm;
317
+ const DRIZZLE_TABLE_RE = /export\s+const\s+(\w+)\s*=\s*(?:pgTable|mysqlTable|sqliteTable)\(/g;
318
+ const MONGOOSE_MODEL_RE = /mongoose\.model\s*[<(]\s*['"`]?(\w+)/g;
319
+ async function extractDataModels(projectDir) {
320
+ const models = [];
321
+ // Prisma
322
+ const prismaPath = join(projectDir, "prisma/schema.prisma");
323
+ try {
324
+ const content = await readFile(prismaPath, "utf-8");
325
+ let match;
326
+ const re = new RegExp(PRISMA_MODEL_RE.source, "gm");
327
+ while ((match = re.exec(content)) !== null) {
328
+ models.push({ name: match[1], file: "prisma/schema.prisma", source: "prisma" });
329
+ }
330
+ }
331
+ catch { /* no prisma */ }
332
+ // Drizzle — look for schema files
333
+ const drizzleCandidates = [
334
+ "src/db/schema.ts", "src/schema.ts", "drizzle/schema.ts",
335
+ "src/db/schema/index.ts", "src/lib/db/schema.ts",
336
+ ];
337
+ for (const candidate of drizzleCandidates) {
338
+ try {
339
+ const content = await readFile(join(projectDir, candidate), "utf-8");
340
+ let match;
341
+ const re = new RegExp(DRIZZLE_TABLE_RE.source, "g");
342
+ while ((match = re.exec(content)) !== null) {
343
+ models.push({ name: match[1], file: candidate, source: "drizzle" });
344
+ }
345
+ }
346
+ catch { /* not found */ }
347
+ }
348
+ // Mongoose — look for model files
349
+ const mongooseDirs = ["src/models", "models", "src/db/models"];
350
+ for (const dir of mongooseDirs) {
351
+ try {
352
+ const files = await readdir(join(projectDir, dir));
353
+ for (const file of files) {
354
+ if (!isCodeFile(file))
355
+ continue;
356
+ const content = await readFile(join(projectDir, dir, file), "utf-8");
357
+ let match;
358
+ const re = new RegExp(MONGOOSE_MODEL_RE.source, "g");
359
+ while ((match = re.exec(content)) !== null) {
360
+ models.push({ name: match[1], file: join(dir, file), source: "mongoose" });
361
+ }
362
+ }
363
+ }
364
+ catch { /* not found */ }
365
+ }
366
+ return models;
367
+ }
368
+ const EXTERNAL_SERVICE_MARKERS = {
369
+ stripe: "Stripe",
370
+ "@stripe/stripe-js": "Stripe",
371
+ "@supabase/supabase-js": "Supabase",
372
+ firebase: "Firebase",
373
+ "firebase-admin": "Firebase Admin",
374
+ "@aws-sdk": "AWS",
375
+ "@azure": "Azure",
376
+ "@google-cloud": "Google Cloud",
377
+ "@sendgrid/mail": "SendGrid",
378
+ resend: "Resend",
379
+ "@clerk/nextjs": "Clerk Auth",
380
+ "@auth/core": "Auth.js",
381
+ "next-auth": "NextAuth",
382
+ "@lucia-auth/core": "Lucia Auth",
383
+ "@upstash/redis": "Upstash Redis",
384
+ ioredis: "Redis",
385
+ "@sentry/node": "Sentry",
386
+ posthog: "PostHog",
387
+ "@vercel/analytics": "Vercel Analytics",
388
+ openai: "OpenAI",
389
+ "@anthropic-ai/sdk": "Anthropic",
390
+ "@pinecone-database/pinecone": "Pinecone",
391
+ "@linear/sdk": "Linear",
392
+ };
393
+ const DB_TYPE_MARKERS = {
394
+ "@prisma/client": "PostgreSQL (Prisma)",
395
+ pg: "PostgreSQL",
396
+ mysql2: "MySQL",
397
+ "better-sqlite3": "SQLite",
398
+ "@libsql/client": "SQLite (Turso)",
399
+ mongoose: "MongoDB",
400
+ mongodb: "MongoDB",
401
+ "@neondatabase/serverless": "PostgreSQL (Neon)",
402
+ "@planetscale/database": "MySQL (PlanetScale)",
403
+ };
404
+ export async function scanDataAPIs(projectDir) {
405
+ const pkg = await readJson(join(projectDir, "package.json"));
406
+ const allDeps = {
407
+ ...(typeof pkg?.dependencies === "object" ? pkg.dependencies : {}),
408
+ ...(typeof pkg?.devDependencies === "object" ? pkg.devDependencies : {}),
409
+ };
410
+ // External services
411
+ const externalServices = [];
412
+ for (const [dep, label] of Object.entries(EXTERNAL_SERVICE_MARKERS)) {
413
+ const found = dep.startsWith("@")
414
+ ? Object.keys(allDeps).some(d => d.startsWith(dep))
415
+ : dep in allDeps;
416
+ if (found) {
417
+ externalServices.push(label);
418
+ }
419
+ }
420
+ // Database type
421
+ let databaseType = null;
422
+ for (const [dep, label] of Object.entries(DB_TYPE_MARKERS)) {
423
+ if (dep in allDeps) {
424
+ databaseType = label;
425
+ break;
426
+ }
427
+ }
428
+ // API endpoints
429
+ const apiEndpoints = [];
430
+ for (const apiDir of API_DIRS) {
431
+ const fullPath = join(projectDir, apiDir);
432
+ if (!(await exists(fullPath)))
433
+ continue;
434
+ const files = await walkDir(fullPath, fullPath, 4);
435
+ for (const file of files) {
436
+ if (file.endsWith("/"))
437
+ continue;
438
+ if (!isCodeFile(file))
439
+ continue;
440
+ const name = basename(file).toLowerCase();
441
+ if (name.includes(".test.") || name.includes(".spec."))
442
+ continue;
443
+ const eps = await extractAPIEndpoints(projectDir, join(apiDir, file));
444
+ apiEndpoints.push(...eps);
445
+ }
446
+ }
447
+ // Also check for standalone server files
448
+ const serverFiles = ["src/server.ts", "server.ts", "src/app.ts", "app.ts", "src/index.ts"];
449
+ for (const sf of serverFiles) {
450
+ if (await exists(join(projectDir, sf))) {
451
+ const eps = await extractAPIEndpoints(projectDir, sf);
452
+ apiEndpoints.push(...eps);
453
+ }
454
+ }
455
+ // Data models
456
+ const dataModels = await extractDataModels(projectDir);
457
+ return {
458
+ apiEndpoints,
459
+ dataModels,
460
+ externalServices: [...new Set(externalServices)],
461
+ databaseType,
462
+ };
463
+ }
464
+ // ── Combined Scan ──────────────────────────────────────────────────────────
465
+ export async function scanAll(projectDir) {
466
+ const [structure, routes, dataAPIs] = await Promise.all([
467
+ scanStructure(projectDir),
468
+ scanRoutes(projectDir),
469
+ scanDataAPIs(projectDir),
470
+ ]);
471
+ return { structure, routes, dataAPIs };
472
+ }
473
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["../../src/spec/scanner.ts"],"names":[],"mappings":"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"}