sammy-sdk 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.
- package/README.md +75 -0
- package/dist/cli/commands/dev.d.ts +3 -0
- package/dist/cli/commands/dev.d.ts.map +1 -0
- package/dist/cli/commands/dev.js +13 -0
- package/dist/cli/commands/dev.js.map +1 -0
- package/dist/cli/commands/eval.d.ts +3 -0
- package/dist/cli/commands/eval.d.ts.map +1 -0
- package/dist/cli/commands/eval.js +28 -0
- package/dist/cli/commands/eval.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +3 -0
- package/dist/cli/commands/generate.d.ts.map +1 -0
- package/dist/cli/commands/generate.js +10 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +9 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +17 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cloud/sammy-cloud.d.ts +10 -0
- package/dist/cloud/sammy-cloud.d.ts.map +1 -0
- package/dist/cloud/sammy-cloud.js +113 -0
- package/dist/cloud/sammy-cloud.js.map +1 -0
- package/dist/dev/chat-ui.d.ts +6 -0
- package/dist/dev/chat-ui.d.ts.map +1 -0
- package/dist/dev/chat-ui.js +95 -0
- package/dist/dev/chat-ui.js.map +1 -0
- package/dist/dev/server.d.ts +5 -0
- package/dist/dev/server.d.ts.map +1 -0
- package/dist/dev/server.js +87 -0
- package/dist/dev/server.js.map +1 -0
- package/dist/dev/watcher.d.ts +2 -0
- package/dist/dev/watcher.d.ts.map +1 -0
- package/dist/dev/watcher.js +19 -0
- package/dist/dev/watcher.js.map +1 -0
- package/dist/discovery/ast/call-route-finder.d.ts +16 -0
- package/dist/discovery/ast/call-route-finder.d.ts.map +1 -0
- package/dist/discovery/ast/call-route-finder.js +106 -0
- package/dist/discovery/ast/call-route-finder.js.map +1 -0
- package/dist/discovery/ast/handler-detector.d.ts +8 -0
- package/dist/discovery/ast/handler-detector.d.ts.map +1 -0
- package/dist/discovery/ast/handler-detector.js +56 -0
- package/dist/discovery/ast/handler-detector.js.map +1 -0
- package/dist/discovery/ast/named-export-finder.d.ts +7 -0
- package/dist/discovery/ast/named-export-finder.d.ts.map +1 -0
- package/dist/discovery/ast/named-export-finder.js +21 -0
- package/dist/discovery/ast/named-export-finder.js.map +1 -0
- package/dist/discovery/ast/param-extractor.d.ts +7 -0
- package/dist/discovery/ast/param-extractor.d.ts.map +1 -0
- package/dist/discovery/ast/param-extractor.js +236 -0
- package/dist/discovery/ast/param-extractor.js.map +1 -0
- package/dist/discovery/ast/project.d.ts +8 -0
- package/dist/discovery/ast/project.d.ts.map +1 -0
- package/dist/discovery/ast/project.js +66 -0
- package/dist/discovery/ast/project.js.map +1 -0
- package/dist/discovery/ast/resolve.d.ts +5 -0
- package/dist/discovery/ast/resolve.d.ts.map +1 -0
- package/dist/discovery/ast/resolve.js +60 -0
- package/dist/discovery/ast/resolve.js.map +1 -0
- package/dist/discovery/ast/side-effect-tracer.d.ts +4 -0
- package/dist/discovery/ast/side-effect-tracer.d.ts.map +1 -0
- package/dist/discovery/ast/side-effect-tracer.js +100 -0
- package/dist/discovery/ast/side-effect-tracer.js.map +1 -0
- package/dist/discovery/ast/source-files.d.ts +3 -0
- package/dist/discovery/ast/source-files.d.ts.map +1 -0
- package/dist/discovery/ast/source-files.js +37 -0
- package/dist/discovery/ast/source-files.js.map +1 -0
- package/dist/discovery/config-generator.d.ts +5 -0
- package/dist/discovery/config-generator.d.ts.map +1 -0
- package/dist/discovery/config-generator.js +71 -0
- package/dist/discovery/config-generator.js.map +1 -0
- package/dist/discovery/extractors/auth-detector.d.ts +3 -0
- package/dist/discovery/extractors/auth-detector.d.ts.map +1 -0
- package/dist/discovery/extractors/auth-detector.js +97 -0
- package/dist/discovery/extractors/auth-detector.js.map +1 -0
- package/dist/discovery/extractors/http-call-extractor.d.ts +5 -0
- package/dist/discovery/extractors/http-call-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/http-call-extractor.js +122 -0
- package/dist/discovery/extractors/http-call-extractor.js.map +1 -0
- package/dist/discovery/extractors/model-extractor.d.ts +4 -0
- package/dist/discovery/extractors/model-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/model-extractor.js +256 -0
- package/dist/discovery/extractors/model-extractor.js.map +1 -0
- package/dist/discovery/extractors/nestjs-extractor.d.ts +4 -0
- package/dist/discovery/extractors/nestjs-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/nestjs-extractor.js +156 -0
- package/dist/discovery/extractors/nestjs-extractor.js.map +1 -0
- package/dist/discovery/extractors/remix-extractor.d.ts +5 -0
- package/dist/discovery/extractors/remix-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/remix-extractor.js +118 -0
- package/dist/discovery/extractors/remix-extractor.js.map +1 -0
- package/dist/discovery/extractors/route-extractor.d.ts +4 -0
- package/dist/discovery/extractors/route-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/route-extractor.js +108 -0
- package/dist/discovery/extractors/route-extractor.js.map +1 -0
- package/dist/discovery/extractors/server-action-extractor.d.ts +4 -0
- package/dist/discovery/extractors/server-action-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/server-action-extractor.js +129 -0
- package/dist/discovery/extractors/server-action-extractor.js.map +1 -0
- package/dist/discovery/extractors/service-detector.d.ts +3 -0
- package/dist/discovery/extractors/service-detector.d.ts.map +1 -0
- package/dist/discovery/extractors/service-detector.js +114 -0
- package/dist/discovery/extractors/service-detector.js.map +1 -0
- package/dist/discovery/extractors/sveltekit-extractor.d.ts +5 -0
- package/dist/discovery/extractors/sveltekit-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/sveltekit-extractor.js +129 -0
- package/dist/discovery/extractors/sveltekit-extractor.js.map +1 -0
- package/dist/discovery/extractors/trpc-extractor.d.ts +4 -0
- package/dist/discovery/extractors/trpc-extractor.d.ts.map +1 -0
- package/dist/discovery/extractors/trpc-extractor.js +191 -0
- package/dist/discovery/extractors/trpc-extractor.js.map +1 -0
- package/dist/discovery/framework-detector.d.ts +9 -0
- package/dist/discovery/framework-detector.d.ts.map +1 -0
- package/dist/discovery/framework-detector.js +68 -0
- package/dist/discovery/framework-detector.js.map +1 -0
- package/dist/discovery/init.d.ts +4 -0
- package/dist/discovery/init.d.ts.map +1 -0
- package/dist/discovery/init.js +102 -0
- package/dist/discovery/init.js.map +1 -0
- package/dist/discovery/llm-analyzer.d.ts +32 -0
- package/dist/discovery/llm-analyzer.d.ts.map +1 -0
- package/dist/discovery/llm-analyzer.js +162 -0
- package/dist/discovery/llm-analyzer.js.map +1 -0
- package/dist/discovery/orchestrator.d.ts +4 -0
- package/dist/discovery/orchestrator.d.ts.map +1 -0
- package/dist/discovery/orchestrator.js +47 -0
- package/dist/discovery/orchestrator.js.map +1 -0
- package/dist/discovery/scanners/express-scanner.d.ts +3 -0
- package/dist/discovery/scanners/express-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/express-scanner.js +10 -0
- package/dist/discovery/scanners/express-scanner.js.map +1 -0
- package/dist/discovery/scanners/fastify-scanner.d.ts +3 -0
- package/dist/discovery/scanners/fastify-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/fastify-scanner.js +10 -0
- package/dist/discovery/scanners/fastify-scanner.js.map +1 -0
- package/dist/discovery/scanners/hono-scanner.d.ts +3 -0
- package/dist/discovery/scanners/hono-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/hono-scanner.js +10 -0
- package/dist/discovery/scanners/hono-scanner.js.map +1 -0
- package/dist/discovery/scanners/nestjs-scanner.d.ts +3 -0
- package/dist/discovery/scanners/nestjs-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/nestjs-scanner.js +10 -0
- package/dist/discovery/scanners/nestjs-scanner.js.map +1 -0
- package/dist/discovery/scanners/nextjs-scanner.d.ts +3 -0
- package/dist/discovery/scanners/nextjs-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/nextjs-scanner.js +15 -0
- package/dist/discovery/scanners/nextjs-scanner.js.map +1 -0
- package/dist/discovery/scanners/registry.d.ts +3 -0
- package/dist/discovery/scanners/registry.d.ts.map +1 -0
- package/dist/discovery/scanners/registry.js +22 -0
- package/dist/discovery/scanners/registry.js.map +1 -0
- package/dist/discovery/scanners/remix-scanner.d.ts +3 -0
- package/dist/discovery/scanners/remix-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/remix-scanner.js +13 -0
- package/dist/discovery/scanners/remix-scanner.js.map +1 -0
- package/dist/discovery/scanners/sveltekit-scanner.d.ts +3 -0
- package/dist/discovery/scanners/sveltekit-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/sveltekit-scanner.js +10 -0
- package/dist/discovery/scanners/sveltekit-scanner.js.map +1 -0
- package/dist/discovery/scanners/trpc-scanner.d.ts +3 -0
- package/dist/discovery/scanners/trpc-scanner.d.ts.map +1 -0
- package/dist/discovery/scanners/trpc-scanner.js +21 -0
- package/dist/discovery/scanners/trpc-scanner.js.map +1 -0
- package/dist/discovery/scanners/types.d.ts +18 -0
- package/dist/discovery/scanners/types.d.ts.map +1 -0
- package/dist/discovery/scanners/types.js +2 -0
- package/dist/discovery/scanners/types.js.map +1 -0
- package/dist/discovery/types.d.ts +60 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +2 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/eval/diagnoser.d.ts +4 -0
- package/dist/eval/diagnoser.d.ts.map +1 -0
- package/dist/eval/diagnoser.js +97 -0
- package/dist/eval/diagnoser.js.map +1 -0
- package/dist/eval/judge.d.ts +8 -0
- package/dist/eval/judge.d.ts.map +1 -0
- package/dist/eval/judge.js +71 -0
- package/dist/eval/judge.js.map +1 -0
- package/dist/eval/loop-guard.d.ts +12 -0
- package/dist/eval/loop-guard.d.ts.map +1 -0
- package/dist/eval/loop-guard.js +45 -0
- package/dist/eval/loop-guard.js.map +1 -0
- package/dist/eval/refiner.d.ts +5 -0
- package/dist/eval/refiner.d.ts.map +1 -0
- package/dist/eval/refiner.js +149 -0
- package/dist/eval/refiner.js.map +1 -0
- package/dist/eval/runner.d.ts +27 -0
- package/dist/eval/runner.d.ts.map +1 -0
- package/dist/eval/runner.js +198 -0
- package/dist/eval/runner.js.map +1 -0
- package/dist/eval/scenario-generator.d.ts +5 -0
- package/dist/eval/scenario-generator.d.ts.map +1 -0
- package/dist/eval/scenario-generator.js +185 -0
- package/dist/eval/scenario-generator.js.map +1 -0
- package/dist/eval/scorer.d.ts +9 -0
- package/dist/eval/scorer.d.ts.map +1 -0
- package/dist/eval/scorer.js +189 -0
- package/dist/eval/scorer.js.map +1 -0
- package/dist/eval/types.d.ts +135 -0
- package/dist/eval/types.d.ts.map +1 -0
- package/dist/eval/types.js +37 -0
- package/dist/eval/types.js.map +1 -0
- package/dist/generator/agent-generator.d.ts +3 -0
- package/dist/generator/agent-generator.d.ts.map +1 -0
- package/dist/generator/agent-generator.js +29 -0
- package/dist/generator/agent-generator.js.map +1 -0
- package/dist/generator/generate.d.ts +5 -0
- package/dist/generator/generate.d.ts.map +1 -0
- package/dist/generator/generate.js +119 -0
- package/dist/generator/generate.js.map +1 -0
- package/dist/generator/handler-generator.d.ts +3 -0
- package/dist/generator/handler-generator.d.ts.map +1 -0
- package/dist/generator/handler-generator.js +66 -0
- package/dist/generator/handler-generator.js.map +1 -0
- package/dist/generator/index-generator.d.ts +3 -0
- package/dist/generator/index-generator.d.ts.map +1 -0
- package/dist/generator/index-generator.js +28 -0
- package/dist/generator/index-generator.js.map +1 -0
- package/dist/generator/merge-logic.d.ts +15 -0
- package/dist/generator/merge-logic.d.ts.map +1 -0
- package/dist/generator/merge-logic.js +52 -0
- package/dist/generator/merge-logic.js.map +1 -0
- package/dist/generator/router-generator.d.ts +3 -0
- package/dist/generator/router-generator.d.ts.map +1 -0
- package/dist/generator/router-generator.js +55 -0
- package/dist/generator/router-generator.js.map +1 -0
- package/dist/generator/schema-generator.d.ts +3 -0
- package/dist/generator/schema-generator.d.ts.map +1 -0
- package/dist/generator/schema-generator.js +58 -0
- package/dist/generator/schema-generator.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/agent-orchestrator.d.ts +19 -0
- package/dist/runtime/agent-orchestrator.d.ts.map +1 -0
- package/dist/runtime/agent-orchestrator.js +96 -0
- package/dist/runtime/agent-orchestrator.js.map +1 -0
- package/dist/runtime/agent-runner.d.ts +22 -0
- package/dist/runtime/agent-runner.d.ts.map +1 -0
- package/dist/runtime/agent-runner.js +59 -0
- package/dist/runtime/agent-runner.js.map +1 -0
- package/dist/runtime/config-loader.d.ts +12 -0
- package/dist/runtime/config-loader.d.ts.map +1 -0
- package/dist/runtime/config-loader.js +42 -0
- package/dist/runtime/config-loader.js.map +1 -0
- package/dist/runtime/conversation-manager.d.ts +16 -0
- package/dist/runtime/conversation-manager.d.ts.map +1 -0
- package/dist/runtime/conversation-manager.js +33 -0
- package/dist/runtime/conversation-manager.js.map +1 -0
- package/dist/runtime/sammy.d.ts +17 -0
- package/dist/runtime/sammy.d.ts.map +1 -0
- package/dist/runtime/sammy.js +97 -0
- package/dist/runtime/sammy.js.map +1 -0
- package/dist/runtime/tool-executor.d.ts +14 -0
- package/dist/runtime/tool-executor.d.ts.map +1 -0
- package/dist/runtime/tool-executor.js +58 -0
- package/dist/runtime/tool-executor.js.map +1 -0
- package/dist/runtime/tool-types.d.ts +26 -0
- package/dist/runtime/tool-types.d.ts.map +1 -0
- package/dist/runtime/tool-types.js +2 -0
- package/dist/runtime/tool-types.js.map +1 -0
- package/dist/runtime/types.d.ts +100 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +2 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/runtime/zod-to-json-schema.d.ts +3 -0
- package/dist/runtime/zod-to-json-schema.d.ts.map +1 -0
- package/dist/runtime/zod-to-json-schema.js +82 -0
- package/dist/runtime/zod-to-json-schema.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { createAstContext } from "./ast/project.js";
|
|
2
|
+
import { extractModels } from "./extractors/model-extractor.js";
|
|
3
|
+
import { detectServices } from "./extractors/service-detector.js";
|
|
4
|
+
import { detectAuth } from "./extractors/auth-detector.js";
|
|
5
|
+
// Single fan-out point for discovery. Runs every detected framework scanner
|
|
6
|
+
// plus the always-on (framework-agnostic) model/service/auth extractors over
|
|
7
|
+
// one shared ts-morph project, then merges the contributions.
|
|
8
|
+
export async function runScan(projectRoot, framework, scanners, deps) {
|
|
9
|
+
const ast = createAstContext(projectRoot);
|
|
10
|
+
const [contributions, models, externalServices, auth] = await Promise.all([
|
|
11
|
+
// One failing scanner must never kill the whole scan.
|
|
12
|
+
Promise.all(scanners.map((s) => s.extract(projectRoot, ast, deps).catch(() => ({})))),
|
|
13
|
+
extractModels(projectRoot, ast),
|
|
14
|
+
detectServices(projectRoot),
|
|
15
|
+
detectAuth(projectRoot),
|
|
16
|
+
]);
|
|
17
|
+
const routes = dedupeRoutes(contributions.flatMap((c) => c.routes ?? []));
|
|
18
|
+
const serverActions = dedupeActions(contributions.flatMap((c) => c.serverActions ?? []));
|
|
19
|
+
return { framework, routes, serverActions, models, externalServices, auth };
|
|
20
|
+
}
|
|
21
|
+
// A route is unique by method+path+file. Composite stacks (e.g. Next + tRPC)
|
|
22
|
+
// can surface the same mount twice; keep the first occurrence.
|
|
23
|
+
function dedupeRoutes(routes) {
|
|
24
|
+
const seen = new Set();
|
|
25
|
+
const out = [];
|
|
26
|
+
for (const r of routes) {
|
|
27
|
+
const key = `${r.method}\0${r.path}\0${r.filePath}`;
|
|
28
|
+
if (seen.has(key))
|
|
29
|
+
continue;
|
|
30
|
+
seen.add(key);
|
|
31
|
+
out.push(r);
|
|
32
|
+
}
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function dedupeActions(actions) {
|
|
36
|
+
const seen = new Set();
|
|
37
|
+
const out = [];
|
|
38
|
+
for (const a of actions) {
|
|
39
|
+
const key = `${a.name}\0${a.filePath}`;
|
|
40
|
+
if (seen.has(key))
|
|
41
|
+
continue;
|
|
42
|
+
seen.add(key);
|
|
43
|
+
out.push(a);
|
|
44
|
+
}
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/discovery/orchestrator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAE3D,4EAA4E;AAC5E,6EAA6E;AAC7E,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,WAAmB,EACnB,SAAwB,EACxB,QAA4B,EAC5B,IAA4B;IAE5B,MAAM,GAAG,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;IAE1C,MAAM,CAAC,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACxE,sDAAsD;QACtD,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,GAAqB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACvG,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC;QAC/B,cAAc,CAAC,WAAW,CAAC;QAC3B,UAAU,CAAC,WAAW,CAAC;KACxB,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1E,MAAM,aAAa,GAAG,aAAa,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC;IAEzF,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;AAC9E,CAAC;AAED,6EAA6E;AAC7E,+DAA+D;AAC/D,SAAS,YAAY,CAAC,MAAyB;IAC7C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QACpD,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,aAAa,CAAC,OAAiC;IACtD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,MAAM,GAAG,GAA6B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/express-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,cAAc,EAAE,gBAO5B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { extractHttpCallRoutes } from "../extractors/http-call-extractor.js";
|
|
2
|
+
export const expressScanner = {
|
|
3
|
+
id: "express",
|
|
4
|
+
label: "Express",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["express"]),
|
|
6
|
+
async extract(projectRoot, ast) {
|
|
7
|
+
return { routes: extractHttpCallRoutes(projectRoot, ast, "express") };
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=express-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/express-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C,EAAE,EAAE,SAAS;IACb,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,OAAO,EAAE,MAAM,EAAE,qBAAqB,CAAC,WAAW,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC;IACxE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/fastify-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,cAAc,EAAE,gBAO5B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { extractHttpCallRoutes } from "../extractors/http-call-extractor.js";
|
|
2
|
+
export const fastifyScanner = {
|
|
3
|
+
id: "fastify",
|
|
4
|
+
label: "Fastify",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["fastify"]),
|
|
6
|
+
async extract(projectRoot, ast) {
|
|
7
|
+
return { routes: extractHttpCallRoutes(projectRoot, ast, "fastify") };
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=fastify-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fastify-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/fastify-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,CAAC,MAAM,cAAc,GAAqB;IAC9C,EAAE,EAAE,SAAS;IACb,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC9C,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,OAAO,EAAE,MAAM,EAAE,qBAAqB,CAAC,WAAW,EAAE,GAAG,EAAE,SAAS,CAAC,EAAE,CAAC;IACxE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/hono-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,WAAW,EAAE,gBAOzB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { extractHttpCallRoutes } from "../extractors/http-call-extractor.js";
|
|
2
|
+
export const honoScanner = {
|
|
3
|
+
id: "hono",
|
|
4
|
+
label: "Hono",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["hono"]),
|
|
6
|
+
async extract(projectRoot, ast) {
|
|
7
|
+
return { routes: extractHttpCallRoutes(projectRoot, ast, "hono") };
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=hono-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hono-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/hono-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAE7E,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,OAAO,EAAE,MAAM,EAAE,qBAAqB,CAAC,WAAW,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC;IACrE,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/nestjs-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,aAAa,EAAE,gBAO3B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { extractNestRoutes } from "../extractors/nestjs-extractor.js";
|
|
2
|
+
export const nestjsScanner = {
|
|
3
|
+
id: "nestjs",
|
|
4
|
+
label: "NestJS",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["@nestjs/core"] || deps["@nestjs/common"]),
|
|
6
|
+
async extract(projectRoot, ast) {
|
|
7
|
+
return { routes: extractNestRoutes(projectRoot, ast) };
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=nestjs-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nestjs-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/nestjs-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,MAAM,CAAC,MAAM,aAAa,GAAqB;IAC7C,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,QAAQ;IACf,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC;IAC7E,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC;IACzD,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/nextjs-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAInD,eAAO,MAAM,aAAa,EAAE,gBAW3B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { extractRoutes } from "../extractors/route-extractor.js";
|
|
2
|
+
import { extractServerActions } from "../extractors/server-action-extractor.js";
|
|
3
|
+
export const nextjsScanner = {
|
|
4
|
+
id: "nextjs",
|
|
5
|
+
label: "Next.js",
|
|
6
|
+
detect: ({ deps }) => Boolean(deps["next"]),
|
|
7
|
+
async extract(projectRoot, ast) {
|
|
8
|
+
const [routes, serverActions] = await Promise.all([
|
|
9
|
+
extractRoutes(projectRoot, ast),
|
|
10
|
+
extractServerActions(projectRoot, ast),
|
|
11
|
+
]);
|
|
12
|
+
return { routes, serverActions };
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=nextjs-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nextjs-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/nextjs-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAEhF,MAAM,CAAC,MAAM,aAAa,GAAqB;IAC7C,EAAE,EAAE,QAAQ;IACZ,KAAK,EAAE,SAAS;IAChB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAChD,aAAa,CAAC,WAAW,EAAE,GAAG,CAAC;YAC/B,oBAAoB,CAAC,WAAW,EAAE,GAAG,CAAC;SACvC,CAAC,CAAC;QACH,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACnC,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAanD,eAAO,MAAM,QAAQ,EAAE,gBAAgB,EAStC,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { nestjsScanner } from "./nestjs-scanner.js";
|
|
2
|
+
import { nextjsScanner } from "./nextjs-scanner.js";
|
|
3
|
+
import { remixScanner } from "./remix-scanner.js";
|
|
4
|
+
import { sveltekitScanner } from "./sveltekit-scanner.js";
|
|
5
|
+
import { expressScanner } from "./express-scanner.js";
|
|
6
|
+
import { fastifyScanner } from "./fastify-scanner.js";
|
|
7
|
+
import { honoScanner } from "./hono-scanner.js";
|
|
8
|
+
import { trpcScanner } from "./trpc-scanner.js";
|
|
9
|
+
// Scanners in primary-framework priority order: the first match supplies the
|
|
10
|
+
// display `framework` field. Layered transports (e.g. tRPC) belong last — they
|
|
11
|
+
// run on top of a host framework and should never be chosen as "primary".
|
|
12
|
+
export const SCANNERS = [
|
|
13
|
+
nestjsScanner,
|
|
14
|
+
nextjsScanner,
|
|
15
|
+
remixScanner,
|
|
16
|
+
sveltekitScanner,
|
|
17
|
+
expressScanner,
|
|
18
|
+
fastifyScanner,
|
|
19
|
+
honoScanner,
|
|
20
|
+
trpcScanner,
|
|
21
|
+
];
|
|
22
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/discovery/scanners/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,6EAA6E;AAC7E,+EAA+E;AAC/E,0EAA0E;AAC1E,MAAM,CAAC,MAAM,QAAQ,GAAuB;IAC1C,aAAa;IACb,aAAa;IACb,YAAY;IACZ,gBAAgB;IAChB,cAAc;IACd,cAAc;IACd,WAAW;IACX,WAAW;CACZ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remix-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/remix-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,YAAY,EAAE,gBAa1B,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { extractRemixRoutes } from "../extractors/remix-extractor.js";
|
|
2
|
+
export const remixScanner = {
|
|
3
|
+
id: "remix",
|
|
4
|
+
label: "Remix",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["@remix-run/node"] ||
|
|
6
|
+
deps["@remix-run/server-runtime"] ||
|
|
7
|
+
deps["@remix-run/react"] ||
|
|
8
|
+
deps["@react-router/dev"]),
|
|
9
|
+
async extract(projectRoot, ast) {
|
|
10
|
+
return { routes: extractRemixRoutes(projectRoot, ast) };
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=remix-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remix-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/remix-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AAEtE,MAAM,CAAC,MAAM,YAAY,GAAqB;IAC5C,EAAE,EAAE,OAAO;IACX,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CACnB,OAAO,CACL,IAAI,CAAC,iBAAiB,CAAC;QACrB,IAAI,CAAC,2BAA2B,CAAC;QACjC,IAAI,CAAC,kBAAkB,CAAC;QACxB,IAAI,CAAC,mBAAmB,CAAC,CAC5B;IACH,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,OAAO,EAAE,MAAM,EAAE,kBAAkB,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC;IAC1D,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sveltekit-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/sveltekit-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,gBAAgB,EAAE,gBAO9B,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { extractSvelteKitRoutes } from "../extractors/sveltekit-extractor.js";
|
|
2
|
+
export const sveltekitScanner = {
|
|
3
|
+
id: "sveltekit",
|
|
4
|
+
label: "SvelteKit",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["@sveltejs/kit"]),
|
|
6
|
+
async extract(projectRoot, ast) {
|
|
7
|
+
return { routes: extractSvelteKitRoutes(projectRoot, ast) };
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=sveltekit-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sveltekit-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/sveltekit-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAE9E,MAAM,CAAC,MAAM,gBAAgB,GAAqB;IAChD,EAAE,EAAE,WAAW;IACf,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;IACpD,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG;QAC5B,OAAO,EAAE,MAAM,EAAE,sBAAsB,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC;IAC9D,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trpc-scanner.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/trpc-scanner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,eAAO,MAAM,WAAW,EAAE,gBAWzB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { extractTrpcRoutes } from "../extractors/trpc-extractor.js";
|
|
2
|
+
export const trpcScanner = {
|
|
3
|
+
id: "trpc",
|
|
4
|
+
label: "tRPC",
|
|
5
|
+
detect: ({ deps }) => Boolean(deps["@trpc/server"] || deps["@trpc/next"]),
|
|
6
|
+
async extract(projectRoot, ast, deps) {
|
|
7
|
+
// Only the v10/v11 chain API is supported; v9's string-key router API
|
|
8
|
+
// (`createRouter().query("name", {...})`) is a different shape.
|
|
9
|
+
const major = majorVersion(deps["@trpc/server"] || deps["@trpc/next"]);
|
|
10
|
+
if (major !== null && major < 10)
|
|
11
|
+
return {};
|
|
12
|
+
return { routes: extractTrpcRoutes(projectRoot, ast) };
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
function majorVersion(range) {
|
|
16
|
+
if (!range)
|
|
17
|
+
return null;
|
|
18
|
+
const m = range.match(/(\d+)/);
|
|
19
|
+
return m ? parseInt(m[1], 10) : null;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=trpc-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trpc-scanner.js","sourceRoot":"","sources":["../../../src/discovery/scanners/trpc-scanner.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,iCAAiC,CAAC;AAEpE,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C,EAAE,EAAE,MAAM;IACV,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC;IACzE,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,EAAE,IAAI;QAClC,sEAAsE;QACtE,gEAAgE;QAChE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;QACvE,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,GAAG,EAAE;YAAE,OAAO,EAAE,CAAC;QAC5C,OAAO,EAAE,MAAM,EAAE,iBAAiB,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,CAAC;IACzD,CAAC;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,KAAyB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AstContext } from "../ast/project.js";
|
|
2
|
+
import type { RouteCapability, ServerActionCapability } from "../types.js";
|
|
3
|
+
export interface DetectInput {
|
|
4
|
+
projectRoot: string;
|
|
5
|
+
deps: Record<string, string>;
|
|
6
|
+
hasDir: (rel: string) => boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ScanContribution {
|
|
9
|
+
routes?: RouteCapability[];
|
|
10
|
+
serverActions?: ServerActionCapability[];
|
|
11
|
+
}
|
|
12
|
+
export interface FrameworkScanner {
|
|
13
|
+
id: string;
|
|
14
|
+
label: string;
|
|
15
|
+
detect(input: DetectInput): boolean;
|
|
16
|
+
extract(projectRoot: string, ast: AstContext, deps: Record<string, string>): Promise<ScanContribution>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/discovery/scanners/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAG3E,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;CAClC;AAID,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,sBAAsB,EAAE,CAAC;CAC1C;AAID,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC;IACpC,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;CACxG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/discovery/scanners/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export interface FrameworkInfo {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
router: string | null;
|
|
5
|
+
}
|
|
6
|
+
export interface RawCapabilityMap {
|
|
7
|
+
framework: FrameworkInfo;
|
|
8
|
+
routes: RouteCapability[];
|
|
9
|
+
serverActions: ServerActionCapability[];
|
|
10
|
+
models: ModelCapability[];
|
|
11
|
+
externalServices: ExternalServiceCapability[];
|
|
12
|
+
auth: AuthCapability;
|
|
13
|
+
}
|
|
14
|
+
export interface RouteCapability {
|
|
15
|
+
path: string;
|
|
16
|
+
method: string;
|
|
17
|
+
filePath: string;
|
|
18
|
+
parameters: ParameterDef[];
|
|
19
|
+
auth: string | null;
|
|
20
|
+
sideEffects: string[];
|
|
21
|
+
}
|
|
22
|
+
export interface ServerActionCapability {
|
|
23
|
+
name: string;
|
|
24
|
+
filePath: string;
|
|
25
|
+
parameters: ParameterDef[];
|
|
26
|
+
sideEffects: string[];
|
|
27
|
+
}
|
|
28
|
+
export interface ModelCapability {
|
|
29
|
+
name: string;
|
|
30
|
+
fields: FieldDef[];
|
|
31
|
+
relations: RelationDef[];
|
|
32
|
+
source: "prisma" | "drizzle" | "mongoose" | "sql";
|
|
33
|
+
}
|
|
34
|
+
export interface ExternalServiceCapability {
|
|
35
|
+
name: string;
|
|
36
|
+
sdkImport: string;
|
|
37
|
+
envVars: string[];
|
|
38
|
+
usedIn: string[];
|
|
39
|
+
}
|
|
40
|
+
export interface AuthCapability {
|
|
41
|
+
provider: string;
|
|
42
|
+
roles: string[];
|
|
43
|
+
}
|
|
44
|
+
export interface ParameterDef {
|
|
45
|
+
name: string;
|
|
46
|
+
type: string;
|
|
47
|
+
required: boolean;
|
|
48
|
+
description?: string;
|
|
49
|
+
}
|
|
50
|
+
export interface FieldDef {
|
|
51
|
+
name: string;
|
|
52
|
+
type: string;
|
|
53
|
+
optional: boolean;
|
|
54
|
+
}
|
|
55
|
+
export interface RelationDef {
|
|
56
|
+
name: string;
|
|
57
|
+
type: string;
|
|
58
|
+
model: string;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,aAAa,EAAE,sBAAsB,EAAE,CAAC;IACxC,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,gBAAgB,EAAE,yBAAyB,EAAE,CAAC;IAC9C,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,YAAY,EAAE,CAAC;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,SAAS,EAAE,WAAW,EAAE,CAAC;IACzB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,KAAK,CAAC;CACnD;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/discovery/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SammyCloudClient } from "../cloud/sammy-cloud.js";
|
|
2
|
+
import type { EvaluationScorecard, DiagnosisReport, EvalConfig } from "./types.js";
|
|
3
|
+
export declare function diagnoseFailures(scorecard: EvaluationScorecard, cloud: SammyCloudClient, evalConfig: EvalConfig, iteration: number, projectRoot: string): Promise<DiagnosisReport>;
|
|
4
|
+
//# sourceMappingURL=diagnoser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnoser.d.ts","sourceRoot":"","sources":["../../src/eval/diagnoser.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EACV,mBAAmB,EAAE,eAAe,EACR,UAAU,EACvC,MAAM,YAAY,CAAC;AAiBpB,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,mBAAmB,EAC9B,KAAK,EAAE,gBAAgB,EACvB,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,eAAe,CAAC,CAwF1B"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
const rootCauseSchema = z.object({
|
|
5
|
+
type: z.enum(["PROMPT_CLARITY", "TOOL_DESCRIPTION", "ROUTING_AMBIGUITY", "MODEL_CAPABILITY", "SCHEMA_MISMATCH", "ARCHITECTURE", "CODE_ISSUE"]),
|
|
6
|
+
tool: z.string().optional(),
|
|
7
|
+
dimension: z.string(),
|
|
8
|
+
scenario: z.string(),
|
|
9
|
+
detail: z.string(),
|
|
10
|
+
suggestedFix: z.string(),
|
|
11
|
+
confidence: z.number(),
|
|
12
|
+
autoFixable: z.boolean(),
|
|
13
|
+
});
|
|
14
|
+
const diagnosisSchema = z.object({
|
|
15
|
+
rootCauses: z.array(rootCauseSchema),
|
|
16
|
+
});
|
|
17
|
+
export async function diagnoseFailures(scorecard, cloud, evalConfig, iteration, projectRoot) {
|
|
18
|
+
const failedDimensions = Object.entries(scorecard.dimensions)
|
|
19
|
+
.filter(([_, d]) => !d.passed)
|
|
20
|
+
.map(([name]) => name);
|
|
21
|
+
if (failedDimensions.length === 0) {
|
|
22
|
+
return { agent: scorecard.agent, iteration, failedDimensions: [], rootCauses: [], escalations: [] };
|
|
23
|
+
}
|
|
24
|
+
// Collect all failures across failing dimensions
|
|
25
|
+
const failureDetails = failedDimensions.map(dim => {
|
|
26
|
+
const d = scorecard.dimensions[dim];
|
|
27
|
+
return `Dimension: ${dim} (score: ${d.score.toFixed(3)}, threshold: ${d.threshold})
|
|
28
|
+
Failures:
|
|
29
|
+
${d.failures.map(f => ` - ${f.scenarioName}: expected=${f.expected}, actual=${f.actual}, detail=${f.detail}`).join("\n")}`;
|
|
30
|
+
}).join("\n\n");
|
|
31
|
+
const prompt = `Analyze these evaluation failures and classify each root cause.
|
|
32
|
+
|
|
33
|
+
${failureDetails}
|
|
34
|
+
|
|
35
|
+
For each failure, classify into one of:
|
|
36
|
+
- PROMPT_CLARITY: Agent didn't understand when to use a tool → fix system prompt
|
|
37
|
+
- TOOL_DESCRIPTION: Tool description was ambiguous → rewrite description
|
|
38
|
+
- ROUTING_AMBIGUITY: Router confused between domains → refine router prompt
|
|
39
|
+
- MODEL_CAPABILITY: Model not capable enough → upgrade model tier
|
|
40
|
+
- SCHEMA_MISMATCH: Parameter schema wrong or too permissive → tighten Zod schema
|
|
41
|
+
- ARCHITECTURE: Domain/agent boundaries wrong → restructure
|
|
42
|
+
- CODE_ISSUE: Handler code bug → escalate to developer (autoFixable: false)
|
|
43
|
+
|
|
44
|
+
Return JSON: { "rootCauses": [{ type, tool?, dimension, scenario, detail, suggestedFix, confidence (0-1), autoFixable }] }`;
|
|
45
|
+
let rootCauses = [];
|
|
46
|
+
try {
|
|
47
|
+
const response = await cloud.completion({
|
|
48
|
+
tier: "powerful",
|
|
49
|
+
purpose: "eval",
|
|
50
|
+
messages: [
|
|
51
|
+
{ role: "system", content: "You diagnose AI agent evaluation failures. Return ONLY valid JSON." },
|
|
52
|
+
{ role: "user", content: prompt },
|
|
53
|
+
],
|
|
54
|
+
temperature: 0,
|
|
55
|
+
responseFormat: "json",
|
|
56
|
+
});
|
|
57
|
+
const parsed = diagnosisSchema.parse(JSON.parse(response.content));
|
|
58
|
+
rootCauses = parsed.rootCauses;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
// Fallback: create generic root causes for each failure
|
|
62
|
+
for (const dim of failedDimensions) {
|
|
63
|
+
for (const failure of scorecard.dimensions[dim].failures) {
|
|
64
|
+
rootCauses.push({
|
|
65
|
+
type: "PROMPT_CLARITY",
|
|
66
|
+
dimension: dim,
|
|
67
|
+
scenario: failure.scenarioName,
|
|
68
|
+
detail: failure.detail,
|
|
69
|
+
suggestedFix: "Review and improve agent prompt",
|
|
70
|
+
confidence: 0.5,
|
|
71
|
+
autoFixable: true,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const escalations = rootCauses
|
|
77
|
+
.filter(rc => rc.type === "CODE_ISSUE")
|
|
78
|
+
.map(rc => ({
|
|
79
|
+
type: "CODE_ISSUE",
|
|
80
|
+
detail: rc.detail,
|
|
81
|
+
filePath: rc.tool || "unknown",
|
|
82
|
+
suggestion: rc.suggestedFix,
|
|
83
|
+
}));
|
|
84
|
+
const report = {
|
|
85
|
+
agent: scorecard.agent,
|
|
86
|
+
iteration,
|
|
87
|
+
failedDimensions,
|
|
88
|
+
rootCauses: rootCauses.filter(rc => rc.autoFixable),
|
|
89
|
+
escalations,
|
|
90
|
+
};
|
|
91
|
+
// Save diagnosis
|
|
92
|
+
const dir = path.join(projectRoot, ".sammy", "eval", "diagnoses");
|
|
93
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
94
|
+
fs.writeFileSync(path.join(dir, `iteration-${iteration}-diagnosis.json`), JSON.stringify(report, null, 2));
|
|
95
|
+
return report;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=diagnoser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnoser.js","sourceRoot":"","sources":["../../src/eval/diagnoser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SammyCloudClient } from "../cloud/sammy-cloud.js";
|
|
2
|
+
import type { JudgeVerdict, EvalConfig, EvalScenario } from "./types.js";
|
|
3
|
+
export declare function judgeResponse(scenario: EvalScenario, agentResponse: string, toolsUsed: Array<{
|
|
4
|
+
name: string;
|
|
5
|
+
params: Record<string, unknown>;
|
|
6
|
+
}>, evalConfig: EvalConfig, cloud: SammyCloudClient): Promise<JudgeVerdict>;
|
|
7
|
+
export declare function saveVerdict(verdict: JudgeVerdict, scenario: EvalScenario, iteration: number, projectRoot: string): void;
|
|
8
|
+
//# sourceMappingURL=judge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/eval/judge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAazE,wBAAsB,aAAa,CACjC,QAAQ,EAAE,YAAY,EACtB,aAAa,EAAE,MAAM,EACrB,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,EACnE,UAAU,EAAE,UAAU,EACtB,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,YAAY,CAAC,CAoDvB;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,YAAY,EACrB,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,IAAI,CAIN"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
const verdictSchema = z.object({
|
|
5
|
+
relevance: z.number().min(1).max(10),
|
|
6
|
+
accuracy: z.number().min(1).max(10),
|
|
7
|
+
completeness: z.number().min(1).max(10),
|
|
8
|
+
conciseness: z.number().min(1).max(10),
|
|
9
|
+
tone: z.number().min(1).max(10),
|
|
10
|
+
overall: z.number().min(1).max(10),
|
|
11
|
+
reasoning: z.string(),
|
|
12
|
+
suggestions: z.array(z.string()),
|
|
13
|
+
});
|
|
14
|
+
export async function judgeResponse(scenario, agentResponse, toolsUsed, evalConfig, cloud) {
|
|
15
|
+
const prompt = `You are evaluating an AI agent's response quality. Score each criterion from 1-10.
|
|
16
|
+
|
|
17
|
+
## Scenario
|
|
18
|
+
Name: ${scenario.name}
|
|
19
|
+
User message: ${scenario.conversation.map(m => `${m.role}: ${m.content}`).join("\n")}
|
|
20
|
+
Expected behavior: ${scenario.expectedBehavior || "respond helpfully"}
|
|
21
|
+
|
|
22
|
+
## Agent's Response
|
|
23
|
+
${agentResponse}
|
|
24
|
+
|
|
25
|
+
## Tools Used
|
|
26
|
+
${toolsUsed.length > 0 ? toolsUsed.map(t => `- ${t.name}(${JSON.stringify(t.params)})`).join("\n") : "None"}
|
|
27
|
+
|
|
28
|
+
## Scoring Criteria
|
|
29
|
+
- relevance: Does the response directly address the user's question?
|
|
30
|
+
- accuracy: Is the information factually correct based on tool results?
|
|
31
|
+
- completeness: Did the response include all necessary information?
|
|
32
|
+
- conciseness: Is it appropriately concise without omitting key details?
|
|
33
|
+
- tone: Is the tone professional and appropriate for a business tool?
|
|
34
|
+
|
|
35
|
+
Return JSON:
|
|
36
|
+
{
|
|
37
|
+
"relevance": <1-10>,
|
|
38
|
+
"accuracy": <1-10>,
|
|
39
|
+
"completeness": <1-10>,
|
|
40
|
+
"conciseness": <1-10>,
|
|
41
|
+
"tone": <1-10>,
|
|
42
|
+
"overall": <weighted average>,
|
|
43
|
+
"reasoning": "<why you scored this way>",
|
|
44
|
+
"suggestions": ["<specific improvement>", ...]
|
|
45
|
+
}`;
|
|
46
|
+
const response = await cloud.completion({
|
|
47
|
+
tier: evalConfig.judge.model,
|
|
48
|
+
purpose: "judge",
|
|
49
|
+
messages: [
|
|
50
|
+
{ role: "system", content: "You are an impartial AI response quality judge. Score strictly and fairly. Return ONLY valid JSON." },
|
|
51
|
+
{ role: "user", content: prompt },
|
|
52
|
+
],
|
|
53
|
+
temperature: evalConfig.judge.temperature,
|
|
54
|
+
responseFormat: "json",
|
|
55
|
+
});
|
|
56
|
+
try {
|
|
57
|
+
return verdictSchema.parse(JSON.parse(response.content));
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return {
|
|
61
|
+
relevance: 5, accuracy: 5, completeness: 5, conciseness: 5, tone: 5,
|
|
62
|
+
overall: 5, reasoning: "Failed to parse judge response", suggestions: [],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function saveVerdict(verdict, scenario, iteration, projectRoot) {
|
|
67
|
+
const dir = path.join(projectRoot, ".sammy", "eval", "judge-verdicts", `iteration-${iteration}`);
|
|
68
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
69
|
+
fs.writeFileSync(path.join(dir, `${scenario.id}.json`), JSON.stringify(verdict, null, 2));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=judge.js.map
|