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.
Files changed (274) hide show
  1. package/README.md +75 -0
  2. package/dist/cli/commands/dev.d.ts +3 -0
  3. package/dist/cli/commands/dev.d.ts.map +1 -0
  4. package/dist/cli/commands/dev.js +13 -0
  5. package/dist/cli/commands/dev.js.map +1 -0
  6. package/dist/cli/commands/eval.d.ts +3 -0
  7. package/dist/cli/commands/eval.d.ts.map +1 -0
  8. package/dist/cli/commands/eval.js +28 -0
  9. package/dist/cli/commands/eval.js.map +1 -0
  10. package/dist/cli/commands/generate.d.ts +3 -0
  11. package/dist/cli/commands/generate.d.ts.map +1 -0
  12. package/dist/cli/commands/generate.js +10 -0
  13. package/dist/cli/commands/generate.js.map +1 -0
  14. package/dist/cli/commands/init.d.ts +3 -0
  15. package/dist/cli/commands/init.d.ts.map +1 -0
  16. package/dist/cli/commands/init.js +9 -0
  17. package/dist/cli/commands/init.js.map +1 -0
  18. package/dist/cli/index.d.ts +3 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +17 -0
  21. package/dist/cli/index.js.map +1 -0
  22. package/dist/cloud/sammy-cloud.d.ts +10 -0
  23. package/dist/cloud/sammy-cloud.d.ts.map +1 -0
  24. package/dist/cloud/sammy-cloud.js +113 -0
  25. package/dist/cloud/sammy-cloud.js.map +1 -0
  26. package/dist/dev/chat-ui.d.ts +6 -0
  27. package/dist/dev/chat-ui.d.ts.map +1 -0
  28. package/dist/dev/chat-ui.js +95 -0
  29. package/dist/dev/chat-ui.js.map +1 -0
  30. package/dist/dev/server.d.ts +5 -0
  31. package/dist/dev/server.d.ts.map +1 -0
  32. package/dist/dev/server.js +87 -0
  33. package/dist/dev/server.js.map +1 -0
  34. package/dist/dev/watcher.d.ts +2 -0
  35. package/dist/dev/watcher.d.ts.map +1 -0
  36. package/dist/dev/watcher.js +19 -0
  37. package/dist/dev/watcher.js.map +1 -0
  38. package/dist/discovery/ast/call-route-finder.d.ts +16 -0
  39. package/dist/discovery/ast/call-route-finder.d.ts.map +1 -0
  40. package/dist/discovery/ast/call-route-finder.js +106 -0
  41. package/dist/discovery/ast/call-route-finder.js.map +1 -0
  42. package/dist/discovery/ast/handler-detector.d.ts +8 -0
  43. package/dist/discovery/ast/handler-detector.d.ts.map +1 -0
  44. package/dist/discovery/ast/handler-detector.js +56 -0
  45. package/dist/discovery/ast/handler-detector.js.map +1 -0
  46. package/dist/discovery/ast/named-export-finder.d.ts +7 -0
  47. package/dist/discovery/ast/named-export-finder.d.ts.map +1 -0
  48. package/dist/discovery/ast/named-export-finder.js +21 -0
  49. package/dist/discovery/ast/named-export-finder.js.map +1 -0
  50. package/dist/discovery/ast/param-extractor.d.ts +7 -0
  51. package/dist/discovery/ast/param-extractor.d.ts.map +1 -0
  52. package/dist/discovery/ast/param-extractor.js +236 -0
  53. package/dist/discovery/ast/param-extractor.js.map +1 -0
  54. package/dist/discovery/ast/project.d.ts +8 -0
  55. package/dist/discovery/ast/project.d.ts.map +1 -0
  56. package/dist/discovery/ast/project.js +66 -0
  57. package/dist/discovery/ast/project.js.map +1 -0
  58. package/dist/discovery/ast/resolve.d.ts +5 -0
  59. package/dist/discovery/ast/resolve.d.ts.map +1 -0
  60. package/dist/discovery/ast/resolve.js +60 -0
  61. package/dist/discovery/ast/resolve.js.map +1 -0
  62. package/dist/discovery/ast/side-effect-tracer.d.ts +4 -0
  63. package/dist/discovery/ast/side-effect-tracer.d.ts.map +1 -0
  64. package/dist/discovery/ast/side-effect-tracer.js +100 -0
  65. package/dist/discovery/ast/side-effect-tracer.js.map +1 -0
  66. package/dist/discovery/ast/source-files.d.ts +3 -0
  67. package/dist/discovery/ast/source-files.d.ts.map +1 -0
  68. package/dist/discovery/ast/source-files.js +37 -0
  69. package/dist/discovery/ast/source-files.js.map +1 -0
  70. package/dist/discovery/config-generator.d.ts +5 -0
  71. package/dist/discovery/config-generator.d.ts.map +1 -0
  72. package/dist/discovery/config-generator.js +71 -0
  73. package/dist/discovery/config-generator.js.map +1 -0
  74. package/dist/discovery/extractors/auth-detector.d.ts +3 -0
  75. package/dist/discovery/extractors/auth-detector.d.ts.map +1 -0
  76. package/dist/discovery/extractors/auth-detector.js +97 -0
  77. package/dist/discovery/extractors/auth-detector.js.map +1 -0
  78. package/dist/discovery/extractors/http-call-extractor.d.ts +5 -0
  79. package/dist/discovery/extractors/http-call-extractor.d.ts.map +1 -0
  80. package/dist/discovery/extractors/http-call-extractor.js +122 -0
  81. package/dist/discovery/extractors/http-call-extractor.js.map +1 -0
  82. package/dist/discovery/extractors/model-extractor.d.ts +4 -0
  83. package/dist/discovery/extractors/model-extractor.d.ts.map +1 -0
  84. package/dist/discovery/extractors/model-extractor.js +256 -0
  85. package/dist/discovery/extractors/model-extractor.js.map +1 -0
  86. package/dist/discovery/extractors/nestjs-extractor.d.ts +4 -0
  87. package/dist/discovery/extractors/nestjs-extractor.d.ts.map +1 -0
  88. package/dist/discovery/extractors/nestjs-extractor.js +156 -0
  89. package/dist/discovery/extractors/nestjs-extractor.js.map +1 -0
  90. package/dist/discovery/extractors/remix-extractor.d.ts +5 -0
  91. package/dist/discovery/extractors/remix-extractor.d.ts.map +1 -0
  92. package/dist/discovery/extractors/remix-extractor.js +118 -0
  93. package/dist/discovery/extractors/remix-extractor.js.map +1 -0
  94. package/dist/discovery/extractors/route-extractor.d.ts +4 -0
  95. package/dist/discovery/extractors/route-extractor.d.ts.map +1 -0
  96. package/dist/discovery/extractors/route-extractor.js +108 -0
  97. package/dist/discovery/extractors/route-extractor.js.map +1 -0
  98. package/dist/discovery/extractors/server-action-extractor.d.ts +4 -0
  99. package/dist/discovery/extractors/server-action-extractor.d.ts.map +1 -0
  100. package/dist/discovery/extractors/server-action-extractor.js +129 -0
  101. package/dist/discovery/extractors/server-action-extractor.js.map +1 -0
  102. package/dist/discovery/extractors/service-detector.d.ts +3 -0
  103. package/dist/discovery/extractors/service-detector.d.ts.map +1 -0
  104. package/dist/discovery/extractors/service-detector.js +114 -0
  105. package/dist/discovery/extractors/service-detector.js.map +1 -0
  106. package/dist/discovery/extractors/sveltekit-extractor.d.ts +5 -0
  107. package/dist/discovery/extractors/sveltekit-extractor.d.ts.map +1 -0
  108. package/dist/discovery/extractors/sveltekit-extractor.js +129 -0
  109. package/dist/discovery/extractors/sveltekit-extractor.js.map +1 -0
  110. package/dist/discovery/extractors/trpc-extractor.d.ts +4 -0
  111. package/dist/discovery/extractors/trpc-extractor.d.ts.map +1 -0
  112. package/dist/discovery/extractors/trpc-extractor.js +191 -0
  113. package/dist/discovery/extractors/trpc-extractor.js.map +1 -0
  114. package/dist/discovery/framework-detector.d.ts +9 -0
  115. package/dist/discovery/framework-detector.d.ts.map +1 -0
  116. package/dist/discovery/framework-detector.js +68 -0
  117. package/dist/discovery/framework-detector.js.map +1 -0
  118. package/dist/discovery/init.d.ts +4 -0
  119. package/dist/discovery/init.d.ts.map +1 -0
  120. package/dist/discovery/init.js +102 -0
  121. package/dist/discovery/init.js.map +1 -0
  122. package/dist/discovery/llm-analyzer.d.ts +32 -0
  123. package/dist/discovery/llm-analyzer.d.ts.map +1 -0
  124. package/dist/discovery/llm-analyzer.js +162 -0
  125. package/dist/discovery/llm-analyzer.js.map +1 -0
  126. package/dist/discovery/orchestrator.d.ts +4 -0
  127. package/dist/discovery/orchestrator.d.ts.map +1 -0
  128. package/dist/discovery/orchestrator.js +47 -0
  129. package/dist/discovery/orchestrator.js.map +1 -0
  130. package/dist/discovery/scanners/express-scanner.d.ts +3 -0
  131. package/dist/discovery/scanners/express-scanner.d.ts.map +1 -0
  132. package/dist/discovery/scanners/express-scanner.js +10 -0
  133. package/dist/discovery/scanners/express-scanner.js.map +1 -0
  134. package/dist/discovery/scanners/fastify-scanner.d.ts +3 -0
  135. package/dist/discovery/scanners/fastify-scanner.d.ts.map +1 -0
  136. package/dist/discovery/scanners/fastify-scanner.js +10 -0
  137. package/dist/discovery/scanners/fastify-scanner.js.map +1 -0
  138. package/dist/discovery/scanners/hono-scanner.d.ts +3 -0
  139. package/dist/discovery/scanners/hono-scanner.d.ts.map +1 -0
  140. package/dist/discovery/scanners/hono-scanner.js +10 -0
  141. package/dist/discovery/scanners/hono-scanner.js.map +1 -0
  142. package/dist/discovery/scanners/nestjs-scanner.d.ts +3 -0
  143. package/dist/discovery/scanners/nestjs-scanner.d.ts.map +1 -0
  144. package/dist/discovery/scanners/nestjs-scanner.js +10 -0
  145. package/dist/discovery/scanners/nestjs-scanner.js.map +1 -0
  146. package/dist/discovery/scanners/nextjs-scanner.d.ts +3 -0
  147. package/dist/discovery/scanners/nextjs-scanner.d.ts.map +1 -0
  148. package/dist/discovery/scanners/nextjs-scanner.js +15 -0
  149. package/dist/discovery/scanners/nextjs-scanner.js.map +1 -0
  150. package/dist/discovery/scanners/registry.d.ts +3 -0
  151. package/dist/discovery/scanners/registry.d.ts.map +1 -0
  152. package/dist/discovery/scanners/registry.js +22 -0
  153. package/dist/discovery/scanners/registry.js.map +1 -0
  154. package/dist/discovery/scanners/remix-scanner.d.ts +3 -0
  155. package/dist/discovery/scanners/remix-scanner.d.ts.map +1 -0
  156. package/dist/discovery/scanners/remix-scanner.js +13 -0
  157. package/dist/discovery/scanners/remix-scanner.js.map +1 -0
  158. package/dist/discovery/scanners/sveltekit-scanner.d.ts +3 -0
  159. package/dist/discovery/scanners/sveltekit-scanner.d.ts.map +1 -0
  160. package/dist/discovery/scanners/sveltekit-scanner.js +10 -0
  161. package/dist/discovery/scanners/sveltekit-scanner.js.map +1 -0
  162. package/dist/discovery/scanners/trpc-scanner.d.ts +3 -0
  163. package/dist/discovery/scanners/trpc-scanner.d.ts.map +1 -0
  164. package/dist/discovery/scanners/trpc-scanner.js +21 -0
  165. package/dist/discovery/scanners/trpc-scanner.js.map +1 -0
  166. package/dist/discovery/scanners/types.d.ts +18 -0
  167. package/dist/discovery/scanners/types.d.ts.map +1 -0
  168. package/dist/discovery/scanners/types.js +2 -0
  169. package/dist/discovery/scanners/types.js.map +1 -0
  170. package/dist/discovery/types.d.ts +60 -0
  171. package/dist/discovery/types.d.ts.map +1 -0
  172. package/dist/discovery/types.js +2 -0
  173. package/dist/discovery/types.js.map +1 -0
  174. package/dist/eval/diagnoser.d.ts +4 -0
  175. package/dist/eval/diagnoser.d.ts.map +1 -0
  176. package/dist/eval/diagnoser.js +97 -0
  177. package/dist/eval/diagnoser.js.map +1 -0
  178. package/dist/eval/judge.d.ts +8 -0
  179. package/dist/eval/judge.d.ts.map +1 -0
  180. package/dist/eval/judge.js +71 -0
  181. package/dist/eval/judge.js.map +1 -0
  182. package/dist/eval/loop-guard.d.ts +12 -0
  183. package/dist/eval/loop-guard.d.ts.map +1 -0
  184. package/dist/eval/loop-guard.js +45 -0
  185. package/dist/eval/loop-guard.js.map +1 -0
  186. package/dist/eval/refiner.d.ts +5 -0
  187. package/dist/eval/refiner.d.ts.map +1 -0
  188. package/dist/eval/refiner.js +149 -0
  189. package/dist/eval/refiner.js.map +1 -0
  190. package/dist/eval/runner.d.ts +27 -0
  191. package/dist/eval/runner.d.ts.map +1 -0
  192. package/dist/eval/runner.js +198 -0
  193. package/dist/eval/runner.js.map +1 -0
  194. package/dist/eval/scenario-generator.d.ts +5 -0
  195. package/dist/eval/scenario-generator.d.ts.map +1 -0
  196. package/dist/eval/scenario-generator.js +185 -0
  197. package/dist/eval/scenario-generator.js.map +1 -0
  198. package/dist/eval/scorer.d.ts +9 -0
  199. package/dist/eval/scorer.d.ts.map +1 -0
  200. package/dist/eval/scorer.js +189 -0
  201. package/dist/eval/scorer.js.map +1 -0
  202. package/dist/eval/types.d.ts +135 -0
  203. package/dist/eval/types.d.ts.map +1 -0
  204. package/dist/eval/types.js +37 -0
  205. package/dist/eval/types.js.map +1 -0
  206. package/dist/generator/agent-generator.d.ts +3 -0
  207. package/dist/generator/agent-generator.d.ts.map +1 -0
  208. package/dist/generator/agent-generator.js +29 -0
  209. package/dist/generator/agent-generator.js.map +1 -0
  210. package/dist/generator/generate.d.ts +5 -0
  211. package/dist/generator/generate.d.ts.map +1 -0
  212. package/dist/generator/generate.js +119 -0
  213. package/dist/generator/generate.js.map +1 -0
  214. package/dist/generator/handler-generator.d.ts +3 -0
  215. package/dist/generator/handler-generator.d.ts.map +1 -0
  216. package/dist/generator/handler-generator.js +66 -0
  217. package/dist/generator/handler-generator.js.map +1 -0
  218. package/dist/generator/index-generator.d.ts +3 -0
  219. package/dist/generator/index-generator.d.ts.map +1 -0
  220. package/dist/generator/index-generator.js +28 -0
  221. package/dist/generator/index-generator.js.map +1 -0
  222. package/dist/generator/merge-logic.d.ts +15 -0
  223. package/dist/generator/merge-logic.d.ts.map +1 -0
  224. package/dist/generator/merge-logic.js +52 -0
  225. package/dist/generator/merge-logic.js.map +1 -0
  226. package/dist/generator/router-generator.d.ts +3 -0
  227. package/dist/generator/router-generator.d.ts.map +1 -0
  228. package/dist/generator/router-generator.js +55 -0
  229. package/dist/generator/router-generator.js.map +1 -0
  230. package/dist/generator/schema-generator.d.ts +3 -0
  231. package/dist/generator/schema-generator.d.ts.map +1 -0
  232. package/dist/generator/schema-generator.js +58 -0
  233. package/dist/generator/schema-generator.js.map +1 -0
  234. package/dist/index.d.ts +4 -0
  235. package/dist/index.d.ts.map +1 -0
  236. package/dist/index.js +2 -0
  237. package/dist/index.js.map +1 -0
  238. package/dist/runtime/agent-orchestrator.d.ts +19 -0
  239. package/dist/runtime/agent-orchestrator.d.ts.map +1 -0
  240. package/dist/runtime/agent-orchestrator.js +96 -0
  241. package/dist/runtime/agent-orchestrator.js.map +1 -0
  242. package/dist/runtime/agent-runner.d.ts +22 -0
  243. package/dist/runtime/agent-runner.d.ts.map +1 -0
  244. package/dist/runtime/agent-runner.js +59 -0
  245. package/dist/runtime/agent-runner.js.map +1 -0
  246. package/dist/runtime/config-loader.d.ts +12 -0
  247. package/dist/runtime/config-loader.d.ts.map +1 -0
  248. package/dist/runtime/config-loader.js +42 -0
  249. package/dist/runtime/config-loader.js.map +1 -0
  250. package/dist/runtime/conversation-manager.d.ts +16 -0
  251. package/dist/runtime/conversation-manager.d.ts.map +1 -0
  252. package/dist/runtime/conversation-manager.js +33 -0
  253. package/dist/runtime/conversation-manager.js.map +1 -0
  254. package/dist/runtime/sammy.d.ts +17 -0
  255. package/dist/runtime/sammy.d.ts.map +1 -0
  256. package/dist/runtime/sammy.js +97 -0
  257. package/dist/runtime/sammy.js.map +1 -0
  258. package/dist/runtime/tool-executor.d.ts +14 -0
  259. package/dist/runtime/tool-executor.d.ts.map +1 -0
  260. package/dist/runtime/tool-executor.js +58 -0
  261. package/dist/runtime/tool-executor.js.map +1 -0
  262. package/dist/runtime/tool-types.d.ts +26 -0
  263. package/dist/runtime/tool-types.d.ts.map +1 -0
  264. package/dist/runtime/tool-types.js +2 -0
  265. package/dist/runtime/tool-types.js.map +1 -0
  266. package/dist/runtime/types.d.ts +100 -0
  267. package/dist/runtime/types.d.ts.map +1 -0
  268. package/dist/runtime/types.js +2 -0
  269. package/dist/runtime/types.js.map +1 -0
  270. package/dist/runtime/zod-to-json-schema.d.ts +3 -0
  271. package/dist/runtime/zod-to-json-schema.d.ts.map +1 -0
  272. package/dist/runtime/zod-to-json-schema.js +82 -0
  273. package/dist/runtime/zod-to-json-schema.js.map +1 -0
  274. package/package.json +82 -0
@@ -0,0 +1,191 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { SyntaxKind } from "ts-morph";
4
+ import { addFile } from "../ast/project.js";
5
+ import { listProjectSourceFiles } from "../ast/source-files.js";
6
+ import { resolveDefinitions, functionLikeFromExpression } from "../ast/resolve.js";
7
+ import { traceSideEffects } from "../ast/side-effect-tracer.js";
8
+ import { extractParamsFromZodSchemaExpr } from "../ast/param-extractor.js";
9
+ const TERMINALS = new Set(["query", "mutation", "subscription"]);
10
+ const TRPC_HINT = /router\s*\(|createTRPCRouter|procedure/i;
11
+ // Discover tRPC v10/v11 procedures. Routers are walked top-down from their
12
+ // roots so the dotted procedure path (e.g. "user.create") is built correctly,
13
+ // resolving nested routers referenced across files (the common t3-app layout).
14
+ export function extractTrpcRoutes(projectRoot, ast) {
15
+ const routerDefs = [];
16
+ for (const filePath of listProjectSourceFiles(projectRoot)) {
17
+ let content;
18
+ try {
19
+ content = fs.readFileSync(filePath, "utf-8");
20
+ }
21
+ catch {
22
+ continue;
23
+ }
24
+ if (!TRPC_HINT.test(content))
25
+ continue;
26
+ try {
27
+ const sourceFile = addFile(ast, filePath);
28
+ if (!sourceFile)
29
+ continue;
30
+ for (const vd of sourceFile.getVariableDeclarations()) {
31
+ const obj = routerObjectFromCall(vd.getInitializer());
32
+ if (obj)
33
+ routerDefs.push({ decl: vd, obj });
34
+ }
35
+ }
36
+ catch {
37
+ continue;
38
+ }
39
+ }
40
+ // A router referenced as a property value of another router is "nested" and
41
+ // must not be treated as a root (its procedures are reached via the parent).
42
+ const childKeys = new Set();
43
+ for (const def of routerDefs) {
44
+ for (const pa of propertyAssignments(def.obj)) {
45
+ const init = pa.getInitializer();
46
+ if (init?.getKind() !== SyntaxKind.Identifier)
47
+ continue;
48
+ for (const d of resolveDefinitions(init)) {
49
+ const vd = d.asKind(SyntaxKind.VariableDeclaration);
50
+ if (vd && routerObjectFromCall(vd.getInitializer()))
51
+ childKeys.add(keyOf(vd));
52
+ }
53
+ }
54
+ }
55
+ let roots = routerDefs.filter((d) => !childKeys.has(keyOf(d.decl)));
56
+ if (roots.length === 0)
57
+ roots = routerDefs; // cyclic/odd layout — best effort
58
+ const routes = [];
59
+ const visited = new Set();
60
+ for (const root of roots)
61
+ traverse(root.obj, "", routes, visited, projectRoot);
62
+ return routes;
63
+ }
64
+ function traverse(obj, prefix, routes, visited, projectRoot) {
65
+ const key = keyOf(obj);
66
+ if (visited.has(key))
67
+ return;
68
+ visited.add(key);
69
+ for (const pa of propertyAssignments(obj)) {
70
+ const name = pa.getName().replace(/['"]/g, "");
71
+ const value = pa.getInitializer();
72
+ if (!value)
73
+ continue;
74
+ const proc = asProcedure(value);
75
+ if (proc) {
76
+ routes.push(buildRoute(prefix + name, proc.method, proc.call, projectRoot));
77
+ continue;
78
+ }
79
+ const nested = resolveRouterObject(value);
80
+ if (nested)
81
+ traverse(nested, `${prefix + name}.`, routes, visited, projectRoot);
82
+ }
83
+ }
84
+ function buildRoute(procPath, method, call, projectRoot) {
85
+ const callExpr = call.asKind(SyntaxKind.CallExpression);
86
+ const resolverBody = lastFunctionArg(callExpr);
87
+ const inputSchema = findInputSchema(callExpr);
88
+ const chainText = callExpr.getExpression().asKind(SyntaxKind.PropertyAccessExpression)?.getExpression().getText() ?? "";
89
+ let parameters = [];
90
+ let sideEffects = [];
91
+ try {
92
+ parameters = extractParamsFromZodSchemaExpr(inputSchema);
93
+ sideEffects = traceSideEffects(resolverBody, "route");
94
+ }
95
+ catch {
96
+ // best-effort
97
+ }
98
+ const filePath = path.relative(projectRoot, callExpr.getSourceFile().getFilePath()).replace(/\\/g, "/");
99
+ const auth = /protected|authed|private/i.test(chainText) ? "trpc-protected" : null;
100
+ return { path: procPath, method, filePath, parameters, auth, sideEffects };
101
+ }
102
+ // A procedure is a `.query()/.mutation()/.subscription()` call whose builder
103
+ // chain mentions a "procedure" (publicProcedure, protectedProcedure, t.procedure…).
104
+ function asProcedure(value) {
105
+ const call = value.asKind(SyntaxKind.CallExpression);
106
+ if (!call)
107
+ return undefined;
108
+ const prop = call.getExpression().asKind(SyntaxKind.PropertyAccessExpression);
109
+ if (!prop || !TERMINALS.has(prop.getName()))
110
+ return undefined;
111
+ if (!/procedure/i.test(prop.getExpression().getText()))
112
+ return undefined;
113
+ return { method: prop.getName(), call };
114
+ }
115
+ // Walk the builder chain (not the resolver) for a `.input(schema)` call.
116
+ function findInputSchema(call) {
117
+ let node = call.asKind(SyntaxKind.CallExpression)?.getExpression().asKind(SyntaxKind.PropertyAccessExpression)?.getExpression();
118
+ while (node) {
119
+ const c = node.asKind(SyntaxKind.CallExpression);
120
+ if (c) {
121
+ const p = c.getExpression().asKind(SyntaxKind.PropertyAccessExpression);
122
+ if (p?.getName() === "input")
123
+ return c.getArguments()[0];
124
+ node = p?.getExpression();
125
+ continue;
126
+ }
127
+ const pa = node.asKind(SyntaxKind.PropertyAccessExpression);
128
+ if (pa) {
129
+ node = pa.getExpression();
130
+ continue;
131
+ }
132
+ break;
133
+ }
134
+ return undefined;
135
+ }
136
+ function lastFunctionArg(call) {
137
+ const args = call.asKind(SyntaxKind.CallExpression)?.getArguments() ?? [];
138
+ for (let i = args.length - 1; i >= 0; i--) {
139
+ const body = functionLikeFromExpression(args[i]);
140
+ if (body)
141
+ return body;
142
+ }
143
+ return undefined;
144
+ }
145
+ // An inline `router({...})` call, or an identifier resolving to a router var.
146
+ function resolveRouterObject(value) {
147
+ const inline = routerObjectFromCall(value);
148
+ if (inline)
149
+ return inline;
150
+ if (value.getKind() === SyntaxKind.Identifier) {
151
+ for (const def of resolveDefinitions(value)) {
152
+ const vd = def.asKind(SyntaxKind.VariableDeclaration);
153
+ const obj = vd && routerObjectFromCall(vd.getInitializer());
154
+ if (obj)
155
+ return obj;
156
+ }
157
+ }
158
+ return undefined;
159
+ }
160
+ function routerObjectFromCall(node) {
161
+ const call = node?.asKind(SyntaxKind.CallExpression);
162
+ if (!call)
163
+ return undefined;
164
+ if (!isRouterCallee(call.getExpression()))
165
+ return undefined;
166
+ return call.getArguments()[0]?.asKind(SyntaxKind.ObjectLiteralExpression);
167
+ }
168
+ // `t.router(...)` or `createTRPCRouter(...)` / `router(...)`.
169
+ function isRouterCallee(expr) {
170
+ const prop = expr.asKind(SyntaxKind.PropertyAccessExpression);
171
+ if (prop)
172
+ return prop.getName() === "router";
173
+ const id = expr.asKind(SyntaxKind.Identifier);
174
+ if (!id)
175
+ return false;
176
+ const name = id.getText();
177
+ return name === "router" || name === "createTRPCRouter" || /router$/i.test(name);
178
+ }
179
+ function propertyAssignments(obj) {
180
+ const lit = obj.asKind(SyntaxKind.ObjectLiteralExpression);
181
+ if (!lit)
182
+ return [];
183
+ return lit.getProperties().flatMap((p) => {
184
+ const pa = p.asKind(SyntaxKind.PropertyAssignment);
185
+ return pa ? [pa] : [];
186
+ });
187
+ }
188
+ function keyOf(node) {
189
+ return `${node.getSourceFile().getFilePath()}:${node.getStart()}`;
190
+ }
191
+ //# sourceMappingURL=trpc-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trpc-extractor.js","sourceRoot":"","sources":["../../../src/discovery/extractors/trpc-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FrameworkScanner } from "./scanners/types.js";
2
+ import type { FrameworkInfo } from "./types.js";
3
+ export interface DetectionResult {
4
+ framework: FrameworkInfo;
5
+ scanners: FrameworkScanner[];
6
+ deps: Record<string, string>;
7
+ }
8
+ export declare function detectFramework(projectRoot: string): DetectionResult;
9
+ //# sourceMappingURL=framework-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-detector.d.ts","sourceRoot":"","sources":["../../src/discovery/framework-detector.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,aAAa,CAAC;IACzB,QAAQ,EAAE,gBAAgB,EAAE,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAiBD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAwBpE"}
@@ -0,0 +1,68 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import { SCANNERS } from "./scanners/registry.js";
4
+ // Representative package whose version stands in for each framework id.
5
+ const VERSION_DEP = {
6
+ nextjs: "next",
7
+ trpc: "@trpc/server",
8
+ nestjs: "@nestjs/core",
9
+ express: "express",
10
+ fastify: "fastify",
11
+ hono: "hono",
12
+ remix: "@remix-run/node",
13
+ sveltekit: "@sveltejs/kit",
14
+ };
15
+ // Detect every applicable framework. Never throws: an unknown stack yields an
16
+ // empty scanner list and a generic "node" framework so discovery degrades to
17
+ // models/services/auth instead of failing.
18
+ export function detectFramework(projectRoot) {
19
+ const pkgPath = path.join(projectRoot, "package.json");
20
+ const pkg = fs.existsSync(pkgPath) ? safeJson(fs.readFileSync(pkgPath, "utf-8")) : {};
21
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
22
+ const dirCache = new Map();
23
+ const hasDir = (rel) => {
24
+ if (!dirCache.has(rel))
25
+ dirCache.set(rel, fs.existsSync(path.join(projectRoot, rel)));
26
+ return dirCache.get(rel);
27
+ };
28
+ const input = { projectRoot, deps, hasDir };
29
+ const scanners = SCANNERS.filter((s) => s.detect(input));
30
+ const primary = scanners[0];
31
+ const framework = primary
32
+ ? {
33
+ name: primary.id,
34
+ version: depVersion(deps, primary.id),
35
+ router: routerHint(primary.id, hasDir),
36
+ }
37
+ : { name: "node", version: "", router: null };
38
+ return { framework, scanners, deps };
39
+ }
40
+ function depVersion(deps, id) {
41
+ const dep = VERSION_DEP[id];
42
+ const raw = dep ? deps[dep] : undefined;
43
+ if (!raw)
44
+ return "";
45
+ // Prefer the first concrete version token (handles ranges like ">=14 <15");
46
+ // fall back to stripping leading range operators for plain "^14.2.0".
47
+ const token = raw.match(/\d+(?:\.\d+){0,2}(?:-[\w.]+)?/);
48
+ return token ? token[0] : raw.replace(/^[\^~>=<\s]+/, "");
49
+ }
50
+ // Next.js is the only framework with an app/pages router distinction.
51
+ function routerHint(id, hasDir) {
52
+ if (id !== "nextjs")
53
+ return null;
54
+ if (hasDir("app") || hasDir("src/app"))
55
+ return "app";
56
+ if (hasDir("pages") || hasDir("src/pages"))
57
+ return "pages";
58
+ return "app";
59
+ }
60
+ function safeJson(text) {
61
+ try {
62
+ return JSON.parse(text);
63
+ }
64
+ catch {
65
+ return {};
66
+ }
67
+ }
68
+ //# sourceMappingURL=framework-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"framework-detector.js","sourceRoot":"","sources":["../../src/discovery/framework-detector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function runInit(options: {
2
+ force?: boolean;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/discovery/init.ts"],"names":[],"mappings":"AAYA,wBAAsB,OAAO,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,iBAoGzD"}
@@ -0,0 +1,102 @@
1
+ import * as fs from "node:fs";
2
+ import * as path from "node:path";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import dotenv from "dotenv";
6
+ import { detectFramework } from "./framework-detector.js";
7
+ import { runScan } from "./orchestrator.js";
8
+ import { analyzeSemantically } from "./llm-analyzer.js";
9
+ import { generateConfig } from "./config-generator.js";
10
+ import { SammyCloudClient } from "../cloud/sammy-cloud.js";
11
+ import { API_BASE_URL } from "sammy-sdk-shared";
12
+ export async function runInit(options) {
13
+ const projectRoot = process.cwd();
14
+ console.log(chalk.bold("\n Sammy v0.1.0\n"));
15
+ // Check for existing config
16
+ const configPath = path.join(projectRoot, "sammy.config.json");
17
+ if (fs.existsSync(configPath) && !options.force) {
18
+ console.log(chalk.yellow(" sammy.config.json already exists."));
19
+ console.log(chalk.dim(" Use --force to overwrite.\n"));
20
+ return;
21
+ }
22
+ // Load API key
23
+ dotenv.config({ path: path.join(projectRoot, ".env.local") });
24
+ dotenv.config({ path: path.join(projectRoot, ".env") });
25
+ const apiKey = process.env.SAMMY_API_KEY;
26
+ if (!apiKey) {
27
+ console.log(chalk.red(" Missing SAMMY_API_KEY."));
28
+ console.log(chalk.dim(" Set it in .env.local or sign up at sammy.dev\n"));
29
+ process.exit(1);
30
+ }
31
+ const apiUrl = process.env.SAMMY_API_URL || API_BASE_URL;
32
+ const cloud = new SammyCloudClient(apiKey, apiUrl);
33
+ // Step 1: Validate API key
34
+ const keySpinner = ora("Validating API key...").start();
35
+ try {
36
+ const keyInfo = await cloud.validateKey();
37
+ if (!keyInfo.valid) {
38
+ keySpinner.fail("Invalid API key");
39
+ process.exit(1);
40
+ }
41
+ keySpinner.succeed(`API key valid (${keyInfo.plan} plan)`);
42
+ }
43
+ catch {
44
+ keySpinner.fail("Could not validate API key — continuing offline");
45
+ }
46
+ // Step 2: Detect framework(s)
47
+ const fwSpinner = ora("Detecting framework...").start();
48
+ const { framework, scanners, deps } = detectFramework(projectRoot);
49
+ if (scanners.length === 0) {
50
+ fwSpinner.warn("No supported framework detected — scanning models, services, and auth only");
51
+ }
52
+ else {
53
+ const routerSuffix = framework.router ? ` (${framework.router === "app" ? "App" : framework.router === "pages" ? "Pages" : framework.router} Router)` : "";
54
+ fwSpinner.succeed(`${scanners.map((s) => s.label).join(" + ")}${routerSuffix} detected`);
55
+ }
56
+ // Step 3: Scan codebase
57
+ console.log();
58
+ const scanSpinner = ora("Scanning codebase...").start();
59
+ const capabilityMap = await runScan(projectRoot, framework, scanners, deps);
60
+ scanSpinner.succeed("Codebase scanned");
61
+ // Print scan summary
62
+ console.log(chalk.dim(` ├── Routes: ${capabilityMap.routes.length} route handlers`));
63
+ console.log(chalk.dim(` ├── Server actions: ${capabilityMap.serverActions.length} server actions`));
64
+ console.log(chalk.dim(` ├── Models: ${capabilityMap.models.length} models`));
65
+ console.log(chalk.dim(` ├── Services: ${capabilityMap.externalServices.length} external services`));
66
+ if (capabilityMap.externalServices.length > 0) {
67
+ for (const svc of capabilityMap.externalServices) {
68
+ console.log(chalk.dim(` │ └── ${svc.name} (${svc.envVars.join(", ") || svc.sdkImport})`));
69
+ }
70
+ }
71
+ console.log(chalk.dim(` └── Auth: ${capabilityMap.auth.provider !== "none" ? capabilityMap.auth.provider : "none detected"}`));
72
+ // Step 4: LLM analysis
73
+ console.log();
74
+ const llmSpinner = ora("Analyzing with AI...").start();
75
+ let analysis;
76
+ try {
77
+ analysis = await analyzeSemantically(capabilityMap, cloud);
78
+ llmSpinner.succeed("AI analysis complete");
79
+ }
80
+ catch (err) {
81
+ llmSpinner.fail(`AI analysis failed: ${err.message}`);
82
+ process.exit(1);
83
+ }
84
+ // Print domain summary
85
+ for (const domain of analysis.domains) {
86
+ const toolCount = domain.tools.length;
87
+ console.log(chalk.dim(` ├── ${domain.name.padEnd(16)} (${toolCount} tools) — ${domain.description}`));
88
+ }
89
+ console.log(chalk.dim(` └── Architecture: ${analysis.architecture.type}`));
90
+ // Step 5: Generate config
91
+ console.log();
92
+ const genSpinner = ora("Generating config...").start();
93
+ const config = generateConfig(analysis, capabilityMap);
94
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
95
+ genSpinner.succeed("Created sammy.config.json");
96
+ // Next steps
97
+ console.log(chalk.green("\n ✓ Initialization complete\n"));
98
+ console.log(" Next steps:");
99
+ console.log(chalk.dim(" 1. Review sammy.config.json — adjust domains, tools, models as needed"));
100
+ console.log(chalk.dim(" 2. Run: npx sammy generate\n"));
101
+ }
102
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/discovery/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { RawCapabilityMap } from "./types.js";
2
+ import type { SammyCloudClient } from "../cloud/sammy-cloud.js";
3
+ import type { ArchitectureType } from "sammy-sdk-shared";
4
+ export interface AnalysisResult {
5
+ domains: DomainAnalysis[];
6
+ architecture: {
7
+ type: ArchitectureType;
8
+ reasoning: string;
9
+ };
10
+ }
11
+ export interface DomainAnalysis {
12
+ name: string;
13
+ description: string;
14
+ sourcePatterns: string[];
15
+ models: string[];
16
+ externalServices: string[];
17
+ tools: ToolAnalysis[];
18
+ }
19
+ export interface ToolAnalysis {
20
+ name: string;
21
+ description: string;
22
+ type: "query" | "mutation";
23
+ permission: "read" | "write" | "admin";
24
+ handler: string;
25
+ parameters: Record<string, {
26
+ type: string;
27
+ required: boolean;
28
+ description?: string;
29
+ }>;
30
+ }
31
+ export declare function analyzeSemantically(capabilityMap: RawCapabilityMap, cloud: SammyCloudClient): Promise<AnalysisResult>;
32
+ //# sourceMappingURL=llm-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-analyzer.d.ts","sourceRoot":"","sources":["../../src/discovery/llm-analyzer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAIzD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,YAAY,EAAE;QACZ,IAAI,EAAE,gBAAgB,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,GAAG,UAAU,CAAC;IAC3B,UAAU,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvF;AAoCD,wBAAsB,mBAAmB,CACvC,aAAa,EAAE,gBAAgB,EAC/B,KAAK,EAAE,gBAAgB,GACtB,OAAO,CAAC,cAAc,CAAC,CAiCzB"}
@@ -0,0 +1,162 @@
1
+ import { z } from "zod";
2
+ // --- Validation schema ---
3
+ const toolSchema = z.object({
4
+ name: z.string(),
5
+ description: z.string(),
6
+ type: z.enum(["query", "mutation"]),
7
+ permission: z.enum(["read", "write", "admin"]),
8
+ handler: z.string(),
9
+ parameters: z.record(z.object({
10
+ type: z.string(),
11
+ required: z.boolean(),
12
+ description: z.string().optional(),
13
+ })),
14
+ });
15
+ const domainSchema = z.object({
16
+ name: z.string(),
17
+ description: z.string(),
18
+ sourcePatterns: z.array(z.string()),
19
+ models: z.array(z.string()),
20
+ externalServices: z.array(z.string()),
21
+ tools: z.array(toolSchema),
22
+ });
23
+ const analysisSchema = z.object({
24
+ domains: z.array(domainSchema),
25
+ architecture: z.object({
26
+ type: z.enum(["single-agent", "multi-agent", "hierarchical"]),
27
+ reasoning: z.string(),
28
+ }),
29
+ });
30
+ // --- Main function ---
31
+ export async function analyzeSemantically(capabilityMap, cloud) {
32
+ const prompt = buildPrompt(capabilityMap);
33
+ const response = await cloud.completion({
34
+ tier: "powerful",
35
+ purpose: "discovery",
36
+ messages: [
37
+ { role: "system", content: SYSTEM_PROMPT },
38
+ { role: "user", content: prompt },
39
+ ],
40
+ temperature: 0.2,
41
+ responseFormat: "json",
42
+ });
43
+ try {
44
+ const parsed = JSON.parse(response.content);
45
+ return analysisSchema.parse(parsed);
46
+ }
47
+ catch {
48
+ // Retry once on parse failure
49
+ const retryResponse = await cloud.completion({
50
+ tier: "powerful",
51
+ purpose: "discovery",
52
+ messages: [
53
+ { role: "system", content: SYSTEM_PROMPT },
54
+ { role: "user", content: prompt + "\n\nIMPORTANT: Your previous response was not valid JSON. Return ONLY valid JSON matching the schema, no markdown fences." },
55
+ ],
56
+ temperature: 0,
57
+ responseFormat: "json",
58
+ });
59
+ const parsed = JSON.parse(retryResponse.content);
60
+ return analysisSchema.parse(parsed);
61
+ }
62
+ }
63
+ // --- Prompt construction ---
64
+ const SYSTEM_PROMPT = `You are an expert software architect specializing in AI agent system design. Your job is to analyze a codebase's capabilities and organize them into business domains with tools that AI agents can use.
65
+
66
+ You must respond with ONLY valid JSON — no markdown, no explanation, no code fences. The JSON must match this exact schema:
67
+
68
+ {
69
+ "domains": [
70
+ {
71
+ "name": "camelCaseDomainName",
72
+ "description": "One sentence describing what this domain handles",
73
+ "sourcePatterns": ["src/app/api/domain/**"],
74
+ "models": ["ModelName"],
75
+ "externalServices": ["serviceName"],
76
+ "tools": [
77
+ {
78
+ "name": "camelCaseToolName",
79
+ "description": "What this tool does, when to use it, what it returns",
80
+ "type": "query | mutation",
81
+ "permission": "read | write | admin",
82
+ "handler": "src/path/to/file.ts:functionName",
83
+ "parameters": {
84
+ "paramName": { "type": "string", "required": true, "description": "what this param is" }
85
+ }
86
+ }
87
+ ]
88
+ }
89
+ ],
90
+ "architecture": {
91
+ "type": "single-agent | multi-agent | hierarchical",
92
+ "reasoning": "Why this architecture was chosen"
93
+ }
94
+ }
95
+
96
+ Rules:
97
+ - Each domain should have 2-10 tools
98
+ - Domain names must be camelCase
99
+ - Tool names must be camelCase
100
+ - GET-style operations are "query" type with "read" permission
101
+ - POST/PUT/DELETE operations are "mutation" type with "write" or "admin" permission
102
+ - Destructive or sensitive operations should be "admin" permission
103
+ - Architecture: use "single-agent" for 1-2 domains, "multi-agent" for 3-6, "hierarchical" for 7+
104
+ - handler should point to the most relevant source file and likely function name`;
105
+ function buildPrompt(map) {
106
+ const sections = [];
107
+ sections.push(`# Project Analysis Request
108
+
109
+ Framework: ${map.framework.name} ${map.framework.version}${map.framework.router ? ` (${map.framework.router} router)` : ""}`);
110
+ // Routes
111
+ if (map.routes.length > 0) {
112
+ sections.push("\n## API Routes\n");
113
+ for (const route of map.routes) {
114
+ let line = `${route.method} ${route.path} — ${route.filePath}`;
115
+ if (route.auth)
116
+ line += ` [auth: ${route.auth}]`;
117
+ if (route.sideEffects.length > 0)
118
+ line += ` [effects: ${route.sideEffects.join(", ")}]`;
119
+ if (route.parameters.length > 0) {
120
+ const params = route.parameters.map((p) => `${p.name}: ${p.type}${p.required ? "" : "?"}`).join(", ");
121
+ line += ` (${params})`;
122
+ }
123
+ sections.push(line);
124
+ }
125
+ }
126
+ // Server actions
127
+ if (map.serverActions.length > 0) {
128
+ sections.push("\n## Server Actions\n");
129
+ for (const action of map.serverActions) {
130
+ let line = `${action.name} — ${action.filePath}`;
131
+ if (action.sideEffects.length > 0)
132
+ line += ` [effects: ${action.sideEffects.join(", ")}]`;
133
+ sections.push(line);
134
+ }
135
+ }
136
+ // Models
137
+ if (map.models.length > 0) {
138
+ sections.push("\n## Database Models\n");
139
+ for (const model of map.models) {
140
+ const fields = model.fields.map((f) => `${f.name}: ${f.type}${f.optional ? "?" : ""}`).join(", ");
141
+ const relations = model.relations.map((r) => `${r.name} → ${r.model} (${r.type})`).join(", ");
142
+ sections.push(`${model.name}: { ${fields} }${relations ? ` relations: [${relations}]` : ""}`);
143
+ }
144
+ }
145
+ // External services
146
+ if (map.externalServices.length > 0) {
147
+ sections.push("\n## External Services\n");
148
+ for (const svc of map.externalServices) {
149
+ sections.push(`${svc.name} (${svc.sdkImport}) — env: ${svc.envVars.join(", ") || "none"}`);
150
+ }
151
+ }
152
+ // Auth
153
+ if (map.auth.provider !== "none") {
154
+ sections.push(`\n## Auth\nProvider: ${map.auth.provider}`);
155
+ if (map.auth.roles.length > 0) {
156
+ sections.push(`Roles: ${map.auth.roles.join(", ")}`);
157
+ }
158
+ }
159
+ sections.push("\nAnalyze this codebase and return the JSON response.");
160
+ return sections.join("\n");
161
+ }
162
+ //# sourceMappingURL=llm-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-analyzer.js","sourceRoot":"","sources":["../../src/discovery/llm-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { RawCapabilityMap, FrameworkInfo } from "./types.js";
2
+ import type { FrameworkScanner } from "./scanners/types.js";
3
+ export declare function runScan(projectRoot: string, framework: FrameworkInfo, scanners: FrameworkScanner[], deps: Record<string, string>): Promise<RawCapabilityMap>;
4
+ //# sourceMappingURL=orchestrator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../src/discovery/orchestrator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAA2C,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3G,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,qBAAqB,CAAC;AAS9E,wBAAsB,OAAO,CAC3B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,gBAAgB,EAAE,EAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CAe3B"}