@vedangiitb/qwintly-core 1.0.2

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 (226) hide show
  1. package/README.md +8 -0
  2. package/dist/ai/ai.d.ts +2 -0
  3. package/dist/ai/ai.d.ts.map +1 -0
  4. package/dist/ai/ai.js +2 -0
  5. package/dist/ai/ai.js.map +1 -0
  6. package/dist/ai/generate/gemini.client.d.ts +15 -0
  7. package/dist/ai/generate/gemini.client.d.ts.map +1 -0
  8. package/dist/ai/generate/gemini.client.js +39 -0
  9. package/dist/ai/generate/gemini.client.js.map +1 -0
  10. package/dist/ai/generate/generateClient.d.ts +3 -0
  11. package/dist/ai/generate/generateClient.d.ts.map +1 -0
  12. package/dist/ai/generate/generateClient.js +8 -0
  13. package/dist/ai/generate/generateClient.js.map +1 -0
  14. package/dist/ai/toolLoop/toolLoopContext.d.ts +33 -0
  15. package/dist/ai/toolLoop/toolLoopContext.d.ts.map +1 -0
  16. package/dist/ai/toolLoop/toolLoopContext.js +112 -0
  17. package/dist/ai/toolLoop/toolLoopContext.js.map +1 -0
  18. package/dist/ai/toolLoop/toolLoopRunner.d.ts +43 -0
  19. package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -0
  20. package/dist/ai/toolLoop/toolLoopRunner.js +227 -0
  21. package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -0
  22. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts +51 -0
  23. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +1 -0
  24. package/dist/ai/toolLoop/toolLoopRunnerUtils.js +164 -0
  25. package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +1 -0
  26. package/dist/ai/tools/helpers/applyPatch.helpers.d.ts +36 -0
  27. package/dist/ai/tools/helpers/applyPatch.helpers.d.ts.map +1 -0
  28. package/dist/ai/tools/helpers/applyPatch.helpers.js +307 -0
  29. package/dist/ai/tools/helpers/applyPatch.helpers.js.map +1 -0
  30. package/dist/ai/tools/helpers/applyPatch.helpers.test.d.ts +2 -0
  31. package/dist/ai/tools/helpers/applyPatch.helpers.test.d.ts.map +1 -0
  32. package/dist/ai/tools/helpers/applyPatch.helpers.test.js +50 -0
  33. package/dist/ai/tools/helpers/applyPatch.helpers.test.js.map +1 -0
  34. package/dist/ai/tools/helpers/fileSystem.helpers.d.ts +2 -0
  35. package/dist/ai/tools/helpers/fileSystem.helpers.d.ts.map +1 -0
  36. package/dist/ai/tools/helpers/fileSystem.helpers.js +45 -0
  37. package/dist/ai/tools/helpers/fileSystem.helpers.js.map +1 -0
  38. package/dist/ai/tools/helpers/fileSystem.helpers.test.d.ts +2 -0
  39. package/dist/ai/tools/helpers/fileSystem.helpers.test.d.ts.map +1 -0
  40. package/dist/ai/tools/helpers/fileSystem.helpers.test.js +15 -0
  41. package/dist/ai/tools/helpers/fileSystem.helpers.test.js.map +1 -0
  42. package/dist/ai/tools/helpers/format.helpers.d.ts +2 -0
  43. package/dist/ai/tools/helpers/format.helpers.d.ts.map +1 -0
  44. package/dist/ai/tools/helpers/format.helpers.js +14 -0
  45. package/dist/ai/tools/helpers/format.helpers.js.map +1 -0
  46. package/dist/ai/tools/helpers/nextRouteFilePolicy.d.ts +8 -0
  47. package/dist/ai/tools/helpers/nextRouteFilePolicy.d.ts.map +1 -0
  48. package/dist/ai/tools/helpers/nextRouteFilePolicy.js +26 -0
  49. package/dist/ai/tools/helpers/nextRouteFilePolicy.js.map +1 -0
  50. package/dist/ai/tools/implementations/applyPatch.impl.d.ts +53 -0
  51. package/dist/ai/tools/implementations/applyPatch.impl.d.ts.map +1 -0
  52. package/dist/ai/tools/implementations/applyPatch.impl.js +242 -0
  53. package/dist/ai/tools/implementations/applyPatch.impl.js.map +1 -0
  54. package/dist/ai/tools/implementations/applyPatch.impl.test.d.ts +2 -0
  55. package/dist/ai/tools/implementations/applyPatch.impl.test.d.ts.map +1 -0
  56. package/dist/ai/tools/implementations/applyPatch.impl.test.js +72 -0
  57. package/dist/ai/tools/implementations/applyPatch.impl.test.js.map +1 -0
  58. package/dist/ai/tools/implementations/factories.d.ts +90 -0
  59. package/dist/ai/tools/implementations/factories.d.ts.map +1 -0
  60. package/dist/ai/tools/implementations/factories.js +26 -0
  61. package/dist/ai/tools/implementations/factories.js.map +1 -0
  62. package/dist/ai/tools/implementations/listDir.impl.d.ts +3 -0
  63. package/dist/ai/tools/implementations/listDir.impl.d.ts.map +1 -0
  64. package/dist/ai/tools/implementations/listDir.impl.js +47 -0
  65. package/dist/ai/tools/implementations/listDir.impl.js.map +1 -0
  66. package/dist/ai/tools/implementations/readFile.impl.d.ts +3 -0
  67. package/dist/ai/tools/implementations/readFile.impl.d.ts.map +1 -0
  68. package/dist/ai/tools/implementations/readFile.impl.js +23 -0
  69. package/dist/ai/tools/implementations/readFile.impl.js.map +1 -0
  70. package/dist/ai/tools/implementations/search.impl.d.ts +18 -0
  71. package/dist/ai/tools/implementations/search.impl.d.ts.map +1 -0
  72. package/dist/ai/tools/implementations/search.impl.js +74 -0
  73. package/dist/ai/tools/implementations/search.impl.js.map +1 -0
  74. package/dist/ai/tools/implementations/workspaceDeps.d.ts +22 -0
  75. package/dist/ai/tools/implementations/workspaceDeps.d.ts.map +1 -0
  76. package/dist/ai/tools/implementations/workspaceDeps.js +2 -0
  77. package/dist/ai/tools/implementations/workspaceDeps.js.map +1 -0
  78. package/dist/ai/tools/implementations/writeFile.impl.d.ts +27 -0
  79. package/dist/ai/tools/implementations/writeFile.impl.d.ts.map +1 -0
  80. package/dist/ai/tools/implementations/writeFile.impl.js +62 -0
  81. package/dist/ai/tools/implementations/writeFile.impl.js.map +1 -0
  82. package/dist/ai/tools/schemas/applyPatch.schema.d.ts +16 -0
  83. package/dist/ai/tools/schemas/applyPatch.schema.d.ts.map +1 -0
  84. package/dist/ai/tools/schemas/applyPatch.schema.js +17 -0
  85. package/dist/ai/tools/schemas/applyPatch.schema.js.map +1 -0
  86. package/dist/ai/tools/schemas/listDir.schema.d.ts +22 -0
  87. package/dist/ai/tools/schemas/listDir.schema.d.ts.map +1 -0
  88. package/dist/ai/tools/schemas/listDir.schema.js +22 -0
  89. package/dist/ai/tools/schemas/listDir.schema.js.map +1 -0
  90. package/dist/ai/tools/schemas/readFile.schema.d.ts +26 -0
  91. package/dist/ai/tools/schemas/readFile.schema.d.ts.map +1 -0
  92. package/dist/ai/tools/schemas/readFile.schema.js +26 -0
  93. package/dist/ai/tools/schemas/readFile.schema.js.map +1 -0
  94. package/dist/ai/tools/schemas/search.schema.d.ts +16 -0
  95. package/dist/ai/tools/schemas/search.schema.d.ts.map +1 -0
  96. package/dist/ai/tools/schemas/search.schema.js +16 -0
  97. package/dist/ai/tools/schemas/search.schema.js.map +1 -0
  98. package/dist/ai/tools/schemas/submitCodegenDone.schema.d.ts +16 -0
  99. package/dist/ai/tools/schemas/submitCodegenDone.schema.d.ts.map +1 -0
  100. package/dist/ai/tools/schemas/submitCodegenDone.schema.js +16 -0
  101. package/dist/ai/tools/schemas/submitCodegenDone.schema.js.map +1 -0
  102. package/dist/ai/tools/schemas/submitPlannerTasks.schema.d.ts +33 -0
  103. package/dist/ai/tools/schemas/submitPlannerTasks.schema.d.ts.map +1 -0
  104. package/dist/ai/tools/schemas/submitPlannerTasks.schema.js +31 -0
  105. package/dist/ai/tools/schemas/submitPlannerTasks.schema.js.map +1 -0
  106. package/dist/ai/tools/schemas/writeFile.schema.d.ts +20 -0
  107. package/dist/ai/tools/schemas/writeFile.schema.d.ts.map +1 -0
  108. package/dist/ai/tools/schemas/writeFile.schema.js +23 -0
  109. package/dist/ai/tools/schemas/writeFile.schema.js.map +1 -0
  110. package/dist/ai/tools/toolsets/codegenTools.d.ts +3 -0
  111. package/dist/ai/tools/toolsets/codegenTools.d.ts.map +1 -0
  112. package/dist/ai/tools/toolsets/codegenTools.js +17 -0
  113. package/dist/ai/tools/toolsets/codegenTools.js.map +1 -0
  114. package/dist/ai/tools/toolsets/plannerTools.d.ts +3 -0
  115. package/dist/ai/tools/toolsets/plannerTools.d.ts.map +1 -0
  116. package/dist/ai/tools/toolsets/plannerTools.js +17 -0
  117. package/dist/ai/tools/toolsets/plannerTools.js.map +1 -0
  118. package/dist/core.d.ts +44 -0
  119. package/dist/core.d.ts.map +1 -0
  120. package/dist/core.js +80 -0
  121. package/dist/core.js.map +1 -0
  122. package/dist/index.d.ts +2 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +3 -0
  125. package/dist/index.js.map +1 -0
  126. package/dist/indexer/codegenIndex.d.ts +3 -0
  127. package/dist/indexer/codegenIndex.d.ts.map +1 -0
  128. package/dist/indexer/codegenIndex.js +17 -0
  129. package/dist/indexer/codegenIndex.js.map +1 -0
  130. package/dist/indexer/data/configs.constants.d.ts +85 -0
  131. package/dist/indexer/data/configs.constants.d.ts.map +1 -0
  132. package/dist/indexer/data/configs.constants.js +136 -0
  133. package/dist/indexer/data/configs.constants.js.map +1 -0
  134. package/dist/indexer/helpers/buildFolderTree.d.ts +2 -0
  135. package/dist/indexer/helpers/buildFolderTree.d.ts.map +1 -0
  136. package/dist/indexer/helpers/buildFolderTree.js +40 -0
  137. package/dist/indexer/helpers/buildFolderTree.js.map +1 -0
  138. package/dist/indexer/plannerIndex.d.ts +3 -0
  139. package/dist/indexer/plannerIndex.d.ts.map +1 -0
  140. package/dist/indexer/plannerIndex.js +20 -0
  141. package/dist/indexer/plannerIndex.js.map +1 -0
  142. package/dist/indexer/projectInfoIndex.d.ts +3 -0
  143. package/dist/indexer/projectInfoIndex.d.ts.map +1 -0
  144. package/dist/indexer/projectInfoIndex.js +257 -0
  145. package/dist/indexer/projectInfoIndex.js.map +1 -0
  146. package/dist/indexer/validatorIndex.d.ts +3 -0
  147. package/dist/indexer/validatorIndex.d.ts.map +1 -0
  148. package/dist/indexer/validatorIndex.js +14 -0
  149. package/dist/indexer/validatorIndex.js.map +1 -0
  150. package/dist/lib/redis.d.ts +3 -0
  151. package/dist/lib/redis.d.ts.map +1 -0
  152. package/dist/lib/redis.js +7 -0
  153. package/dist/lib/redis.js.map +1 -0
  154. package/dist/lib/supabase.d.ts +2 -0
  155. package/dist/lib/supabase.d.ts.map +1 -0
  156. package/dist/lib/supabase.js +4 -0
  157. package/dist/lib/supabase.js.map +1 -0
  158. package/dist/logging/genStatus.service.d.ts +14 -0
  159. package/dist/logging/genStatus.service.d.ts.map +1 -0
  160. package/dist/logging/genStatus.service.js +36 -0
  161. package/dist/logging/genStatus.service.js.map +1 -0
  162. package/dist/logging/logging.utils.d.ts +12 -0
  163. package/dist/logging/logging.utils.d.ts.map +1 -0
  164. package/dist/logging/logging.utils.js +15 -0
  165. package/dist/logging/logging.utils.js.map +1 -0
  166. package/dist/logging/redis.service.d.ts +11 -0
  167. package/dist/logging/redis.service.d.ts.map +1 -0
  168. package/dist/logging/redis.service.js +26 -0
  169. package/dist/logging/redis.service.js.map +1 -0
  170. package/dist/repository/context.repository.d.ts +8 -0
  171. package/dist/repository/context.repository.d.ts.map +1 -0
  172. package/dist/repository/context.repository.js +59 -0
  173. package/dist/repository/context.repository.js.map +1 -0
  174. package/dist/repository/genStatus.repository.d.ts +13 -0
  175. package/dist/repository/genStatus.repository.d.ts.map +1 -0
  176. package/dist/repository/genStatus.repository.js +18 -0
  177. package/dist/repository/genStatus.repository.js.map +1 -0
  178. package/dist/repository/planTasks.repository.d.ts +9 -0
  179. package/dist/repository/planTasks.repository.d.ts.map +1 -0
  180. package/dist/repository/planTasks.repository.js +24 -0
  181. package/dist/repository/planTasks.repository.js.map +1 -0
  182. package/dist/repository/repository.d.ts +5 -0
  183. package/dist/repository/repository.d.ts.map +1 -0
  184. package/dist/repository/repository.js +7 -0
  185. package/dist/repository/repository.js.map +1 -0
  186. package/dist/types/context.types.d.ts +64 -0
  187. package/dist/types/context.types.d.ts.map +1 -0
  188. package/dist/types/context.types.js +55 -0
  189. package/dist/types/context.types.js.map +1 -0
  190. package/dist/types/events.d.ts +16 -0
  191. package/dist/types/events.d.ts.map +1 -0
  192. package/dist/types/events.js +14 -0
  193. package/dist/types/events.js.map +1 -0
  194. package/dist/types/index/configs.types.d.ts +28 -0
  195. package/dist/types/index/configs.types.d.ts.map +1 -0
  196. package/dist/types/index/configs.types.js +2 -0
  197. package/dist/types/index/configs.types.js.map +1 -0
  198. package/dist/types/index/conventions.types.d.ts +40 -0
  199. package/dist/types/index/conventions.types.d.ts.map +1 -0
  200. package/dist/types/index/conventions.types.js +2 -0
  201. package/dist/types/index/conventions.types.js.map +1 -0
  202. package/dist/types/index/index.types.d.ts +16 -0
  203. package/dist/types/index/index.types.d.ts.map +1 -0
  204. package/dist/types/index/index.types.js +2 -0
  205. package/dist/types/index/index.types.js.map +1 -0
  206. package/dist/types/index/indexing.types.d.ts +9 -0
  207. package/dist/types/index/indexing.types.d.ts.map +1 -0
  208. package/dist/types/index/indexing.types.js +2 -0
  209. package/dist/types/index/indexing.types.js.map +1 -0
  210. package/dist/types/projectInfo.types.d.ts +16 -0
  211. package/dist/types/projectInfo.types.d.ts.map +1 -0
  212. package/dist/types/projectInfo.types.js +2 -0
  213. package/dist/types/projectInfo.types.js.map +1 -0
  214. package/dist/types/updatePlan.types.d.ts +34 -0
  215. package/dist/types/updatePlan.types.d.ts.map +1 -0
  216. package/dist/types/updatePlan.types.js +18 -0
  217. package/dist/types/updatePlan.types.js.map +1 -0
  218. package/dist/utils/utils.d.ts +2 -0
  219. package/dist/utils/utils.d.ts.map +1 -0
  220. package/dist/utils/utils.js +6 -0
  221. package/dist/utils/utils.js.map +1 -0
  222. package/dist/utils/workspace.d.ts +13 -0
  223. package/dist/utils/workspace.d.ts.map +1 -0
  224. package/dist/utils/workspace.js +92 -0
  225. package/dist/utils/workspace.js.map +1 -0
  226. package/package.json +58 -0
@@ -0,0 +1,85 @@
1
+ export declare const projectConfigs: {
2
+ readonly frameworkConfig: {
3
+ readonly name: "Next.js";
4
+ readonly router: "App Router";
5
+ readonly language: "TypeScript";
6
+ readonly styling: "Tailwind CSS";
7
+ readonly ui: "shadcn/ui";
8
+ readonly stateManagement: "React Context + local state";
9
+ };
10
+ readonly runtimeConfig: {
11
+ readonly target: "frontend-only";
12
+ readonly rendering: "server-components-by-default (use 'use client' only when needed)";
13
+ readonly serverActions: "disabled";
14
+ readonly apiRoutes: "disabled";
15
+ readonly dataFetching: "client-side (fetch or mocked)";
16
+ };
17
+ readonly toolingConfig: {
18
+ readonly packageManager: "npm";
19
+ readonly linting: "eslint";
20
+ readonly formatting: "prettier";
21
+ readonly typecheck: "tsc --noEmit";
22
+ readonly testing: "none";
23
+ };
24
+ };
25
+ export declare const indexing: {
26
+ readonly includeExtensions: readonly [".ts", ".tsx", ".js", ".jsx", ".json", ".md", ".mdx", ".css", ".scss", ".sass"];
27
+ readonly excludeDirectories: readonly ["node_modules", ".next", "dist", "build", "out", "coverage", ".git"];
28
+ readonly maxFileBytes: 200000;
29
+ readonly chunkSize: 900;
30
+ readonly chunkOverlap: 150;
31
+ };
32
+ export declare const projectConventions: {
33
+ readonly shadcn: {
34
+ readonly installed: readonly ["avatar", "badge", "button", "card", "dialog", "dropdown-menu", "input", "sheet", "table", "tabs", "tooltip"];
35
+ readonly location: "components/ui/{component}.tsx";
36
+ readonly notes: "TooltipProvider is wired in app/layout.tsx";
37
+ };
38
+ readonly folderConventions: {
39
+ readonly "app/": "routes, layouts, metadata, globals.css";
40
+ readonly "app/{route}/": "Each route defines UI via page.config.ts and renders via page.tsx (no JSX UI in page.tsx).";
41
+ readonly "components/": "UI sections + shared components";
42
+ readonly "components/ui/": "shadcn/ui primitives";
43
+ readonly "lib/": "shared config + utilities (cn, site config, etc.)";
44
+ readonly "public/": "static assets";
45
+ readonly "hooks/": "optional (add when you introduce reusable client hooks)";
46
+ readonly "services/": "optional (client-side wrappers for fetch / browser APIs)";
47
+ readonly "utils/": "optional (pure helpers if they outgrow lib/utils.ts)";
48
+ };
49
+ readonly importsConventions: {
50
+ readonly alias: "@/* -> repo root (tsconfig paths)";
51
+ readonly order: readonly ["next/react", "third-party", "@/*", "relative", "styles"];
52
+ };
53
+ readonly routingConventions: {
54
+ readonly required: readonly ["app/layout.tsx", "app/page.tsx", "app/page.config.ts", "app/not-found.tsx", "app/globals.css"];
55
+ readonly requiredPerRoute: readonly ["app/{route}/page.tsx", "app/{route}/page.config.ts"];
56
+ readonly optionalPerRoute: readonly ["app/{route}/layout.tsx", "app/{route}/loading.tsx", "app/{route}/error.tsx"];
57
+ readonly routeGroups: "app/(group)/... (optional)";
58
+ readonly dynamicSegments: "app/{route}/[param] (optional)";
59
+ };
60
+ readonly namingConventions: {
61
+ readonly components: "PascalCase";
62
+ readonly folders: "kebab-case";
63
+ readonly hooks: "useCamelCase";
64
+ };
65
+ readonly uiArchitecture: {
66
+ readonly pattern: "config-driven UI";
67
+ readonly rule: readonly ["UI MUST be defined in page.config.ts using BuilderElement[]", "page.tsx MUST only render config via the shared renderer (no hardcoded JSX UI)", "Use only supported ElementType values; do not invent new types"];
68
+ readonly configStructure: {
69
+ readonly root: "export const config = { elements: BuilderElement[] }";
70
+ readonly elementTypes: {
71
+ readonly fragment: "{ id, type: 'fragment', children: BuilderElement[] }";
72
+ readonly div: "{ id, type: 'div', className?, children?: BuilderElement[] }";
73
+ readonly text: "{ id, type: 'text', props: { text: string } }";
74
+ readonly image: "{ id, type: 'image', props: { src: string, alt? } }";
75
+ readonly button: "{ id, type: 'button', props?: { text? }, children?: BuilderElement[] }";
76
+ readonly input: "{ id, type: 'input', props?: { placeholder?, value?, type? }, className? }";
77
+ readonly textarea: "{ id, type: 'textarea', props?: { placeholder?, value? }, className? }";
78
+ readonly link: "{ id, type: 'link', props?: { href?, text?, target?, rel? }, children?: BuilderElement[] }";
79
+ readonly icon: "{ id, type: 'icon', props?: { name?, size?, color?, strokeWidth? }, meta?: { name? }, className? }";
80
+ };
81
+ readonly rules: readonly ["Elements MUST follow the BuilderElement schema (id, type, optional props/children/className/meta/visible).", "The top-level element SHOULD be { id: 'root', type: 'div', children: [...] }.", "Text content MUST be in props.text (not a top-level 'text' field).", "Use className for Tailwind-only styling (no inline styles).", "IDs must be unique per page."];
82
+ };
83
+ };
84
+ };
85
+ //# sourceMappingURL=configs.constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configs.constants.d.ts","sourceRoot":"","sources":["../../../src/indexer/data/configs.constants.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;CAwBc,CAAC;AAE1C,eAAO,MAAM,QAAQ;;;;;;CAyBc,CAAC;AAEpC,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4Fc,CAAC"}
@@ -0,0 +1,136 @@
1
+ export const projectConfigs = {
2
+ frameworkConfig: {
3
+ name: "Next.js",
4
+ router: "App Router",
5
+ language: "TypeScript",
6
+ styling: "Tailwind CSS",
7
+ ui: "shadcn/ui",
8
+ stateManagement: "React Context + local state",
9
+ },
10
+ runtimeConfig: {
11
+ target: "frontend-only",
12
+ rendering: "server-components-by-default (use 'use client' only when needed)",
13
+ serverActions: "disabled",
14
+ apiRoutes: "disabled",
15
+ dataFetching: "client-side (fetch or mocked)",
16
+ },
17
+ toolingConfig: {
18
+ packageManager: "npm",
19
+ linting: "eslint",
20
+ formatting: "prettier",
21
+ typecheck: "tsc --noEmit",
22
+ testing: "none",
23
+ },
24
+ };
25
+ export const indexing = {
26
+ includeExtensions: [
27
+ ".ts",
28
+ ".tsx",
29
+ ".js",
30
+ ".jsx",
31
+ ".json",
32
+ ".md",
33
+ ".mdx",
34
+ ".css",
35
+ ".scss",
36
+ ".sass",
37
+ ],
38
+ excludeDirectories: [
39
+ "node_modules",
40
+ ".next",
41
+ "dist",
42
+ "build",
43
+ "out",
44
+ "coverage",
45
+ ".git",
46
+ ],
47
+ maxFileBytes: 200000,
48
+ chunkSize: 900,
49
+ chunkOverlap: 150,
50
+ };
51
+ export const projectConventions = {
52
+ shadcn: {
53
+ installed: [
54
+ "avatar",
55
+ "badge",
56
+ "button",
57
+ "card",
58
+ "dialog",
59
+ "dropdown-menu",
60
+ "input",
61
+ "sheet",
62
+ "table",
63
+ "tabs",
64
+ "tooltip",
65
+ ],
66
+ location: "components/ui/{component}.tsx",
67
+ notes: "TooltipProvider is wired in app/layout.tsx",
68
+ },
69
+ folderConventions: {
70
+ "app/": "routes, layouts, metadata, globals.css",
71
+ "app/{route}/": "Each route defines UI via page.config.ts and renders via page.tsx (no JSX UI in page.tsx).",
72
+ "components/": "UI sections + shared components",
73
+ "components/ui/": "shadcn/ui primitives",
74
+ "lib/": "shared config + utilities (cn, site config, etc.)",
75
+ "public/": "static assets",
76
+ "hooks/": "optional (add when you introduce reusable client hooks)",
77
+ "services/": "optional (client-side wrappers for fetch / browser APIs)",
78
+ "utils/": "optional (pure helpers if they outgrow lib/utils.ts)",
79
+ },
80
+ importsConventions: {
81
+ alias: "@/* -> repo root (tsconfig paths)",
82
+ order: ["next/react", "third-party", "@/*", "relative", "styles"],
83
+ },
84
+ routingConventions: {
85
+ required: [
86
+ "app/layout.tsx",
87
+ "app/page.tsx",
88
+ "app/page.config.ts",
89
+ "app/not-found.tsx",
90
+ "app/globals.css",
91
+ ],
92
+ requiredPerRoute: ["app/{route}/page.tsx", "app/{route}/page.config.ts"],
93
+ optionalPerRoute: [
94
+ "app/{route}/layout.tsx",
95
+ "app/{route}/loading.tsx",
96
+ "app/{route}/error.tsx",
97
+ ],
98
+ routeGroups: "app/(group)/... (optional)",
99
+ dynamicSegments: "app/{route}/[param] (optional)",
100
+ },
101
+ namingConventions: {
102
+ components: "PascalCase",
103
+ folders: "kebab-case",
104
+ hooks: "useCamelCase",
105
+ },
106
+ uiArchitecture: {
107
+ pattern: "config-driven UI",
108
+ rule: [
109
+ "UI MUST be defined in page.config.ts using BuilderElement[]",
110
+ "page.tsx MUST only render config via the shared renderer (no hardcoded JSX UI)",
111
+ "Use only supported ElementType values; do not invent new types",
112
+ ],
113
+ configStructure: {
114
+ root: "export const config = { elements: BuilderElement[] }",
115
+ elementTypes: {
116
+ fragment: "{ id, type: 'fragment', children: BuilderElement[] }",
117
+ div: "{ id, type: 'div', className?, children?: BuilderElement[] }",
118
+ text: "{ id, type: 'text', props: { text: string } }",
119
+ image: "{ id, type: 'image', props: { src: string, alt? } }",
120
+ button: "{ id, type: 'button', props?: { text? }, children?: BuilderElement[] }",
121
+ input: "{ id, type: 'input', props?: { placeholder?, value?, type? }, className? }",
122
+ textarea: "{ id, type: 'textarea', props?: { placeholder?, value? }, className? }",
123
+ link: "{ id, type: 'link', props?: { href?, text?, target?, rel? }, children?: BuilderElement[] }",
124
+ icon: "{ id, type: 'icon', props?: { name?, size?, color?, strokeWidth? }, meta?: { name? }, className? }",
125
+ },
126
+ rules: [
127
+ "Elements MUST follow the BuilderElement schema (id, type, optional props/children/className/meta/visible).",
128
+ "The top-level element SHOULD be { id: 'root', type: 'div', children: [...] }.",
129
+ "Text content MUST be in props.text (not a top-level 'text' field).",
130
+ "Use className for Tailwind-only styling (no inline styles).",
131
+ "IDs must be unique per page.",
132
+ ],
133
+ },
134
+ },
135
+ };
136
+ //# sourceMappingURL=configs.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configs.constants.js","sourceRoot":"","sources":["../../../src/indexer/data/configs.constants.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe,EAAE;QACf,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,YAAY;QACpB,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,cAAc;QACvB,EAAE,EAAE,WAAW;QACf,eAAe,EAAE,6BAA6B;KAC/C;IACD,aAAa,EAAE;QACb,MAAM,EAAE,eAAe;QACvB,SAAS,EACP,kEAAkE;QACpE,aAAa,EAAE,UAAU;QACzB,SAAS,EAAE,UAAU;QACrB,YAAY,EAAE,+BAA+B;KAC9C;IACD,aAAa,EAAE;QACb,cAAc,EAAE,KAAK;QACrB,OAAO,EAAE,QAAQ;QACjB,UAAU,EAAE,UAAU;QACtB,SAAS,EAAE,cAAc;QACzB,OAAO,EAAE,MAAM;KAChB;CACsC,CAAC;AAE1C,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,iBAAiB,EAAE;QACjB,KAAK;QACL,MAAM;QACN,KAAK;QACL,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,OAAO;QACP,OAAO;KACR;IACD,kBAAkB,EAAE;QAClB,cAAc;QACd,OAAO;QACP,MAAM;QACN,OAAO;QACP,KAAK;QACL,UAAU;QACV,MAAM;KACP;IACD,YAAY,EAAE,MAAO;IACrB,SAAS,EAAE,GAAG;IACd,YAAY,EAAE,GAAG;CACgB,CAAC;AAEpC,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE;QACN,SAAS,EAAE;YACT,QAAQ;YACR,OAAO;YACP,QAAQ;YACR,MAAM;YACN,QAAQ;YACR,eAAe;YACf,OAAO;YACP,OAAO;YACP,OAAO;YACP,MAAM;YACN,SAAS;SACV;QACD,QAAQ,EAAE,+BAA+B;QACzC,KAAK,EAAE,4CAA4C;KACpD;IACD,iBAAiB,EAAE;QACjB,MAAM,EAAE,wCAAwC;QAChD,cAAc,EACZ,4FAA4F;QAC9F,aAAa,EAAE,iCAAiC;QAChD,gBAAgB,EAAE,sBAAsB;QACxC,MAAM,EAAE,mDAAmD;QAC3D,SAAS,EAAE,eAAe;QAC1B,QAAQ,EAAE,yDAAyD;QACnE,WAAW,EAAE,0DAA0D;QACvE,QAAQ,EAAE,sDAAsD;KACjE;IACD,kBAAkB,EAAE;QAClB,KAAK,EAAE,mCAAmC;QAC1C,KAAK,EAAE,CAAC,YAAY,EAAE,aAAa,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,CAAC;KAClE;IACD,kBAAkB,EAAE;QAClB,QAAQ,EAAE;YACR,gBAAgB;YAChB,cAAc;YACd,oBAAoB;YACpB,mBAAmB;YACnB,iBAAiB;SAClB;QACD,gBAAgB,EAAE,CAAC,sBAAsB,EAAE,4BAA4B,CAAC;QACxE,gBAAgB,EAAE;YAChB,wBAAwB;YACxB,yBAAyB;YACzB,uBAAuB;SACxB;QACD,WAAW,EAAE,4BAA4B;QACzC,eAAe,EAAE,gCAAgC;KAClD;IACD,iBAAiB,EAAE;QACjB,UAAU,EAAE,YAAY;QACxB,OAAO,EAAE,YAAY;QACrB,KAAK,EAAE,cAAc;KACtB;IACD,cAAc,EAAE;QACd,OAAO,EAAE,kBAAkB;QAE3B,IAAI,EAAE;YACJ,6DAA6D;YAC7D,gFAAgF;YAChF,gEAAgE;SACjE;QAED,eAAe,EAAE;YACf,IAAI,EAAE,sDAAsD;YAE5D,YAAY,EAAE;gBACZ,QAAQ,EAAE,sDAAsD;gBAChE,GAAG,EAAE,8DAA8D;gBACnE,IAAI,EAAE,+CAA+C;gBACrD,KAAK,EAAE,qDAAqD;gBAC5D,MAAM,EACJ,wEAAwE;gBAC1E,KAAK,EACH,4EAA4E;gBAC9E,QAAQ,EACN,wEAAwE;gBAC1E,IAAI,EAAE,4FAA4F;gBAClG,IAAI,EAAE,oGAAoG;aAC3G;YAED,KAAK,EAAE;gBACL,4GAA4G;gBAC5G,+EAA+E;gBAC/E,oEAAoE;gBACpE,6DAA6D;gBAC7D,8BAA8B;aAC/B;SACF;KACF;CAC0C,CAAC","sourcesContent":["import { ProjectConfigsConfig } from \"../../types/index/configs.types.js\";\nimport { ProjectConventionsConfig } from \"../../types/index/conventions.types.js\";\nimport { IndexingConfig } from \"../../types/index/indexing.types.js\";\n\nexport const projectConfigs = {\n frameworkConfig: {\n name: \"Next.js\",\n router: \"App Router\",\n language: \"TypeScript\",\n styling: \"Tailwind CSS\",\n ui: \"shadcn/ui\",\n stateManagement: \"React Context + local state\",\n },\n runtimeConfig: {\n target: \"frontend-only\",\n rendering:\n \"server-components-by-default (use 'use client' only when needed)\",\n serverActions: \"disabled\",\n apiRoutes: \"disabled\",\n dataFetching: \"client-side (fetch or mocked)\",\n },\n toolingConfig: {\n packageManager: \"npm\",\n linting: \"eslint\",\n formatting: \"prettier\",\n typecheck: \"tsc --noEmit\",\n testing: \"none\",\n },\n} as const satisfies ProjectConfigsConfig;\n\nexport const indexing = {\n includeExtensions: [\n \".ts\",\n \".tsx\",\n \".js\",\n \".jsx\",\n \".json\",\n \".md\",\n \".mdx\",\n \".css\",\n \".scss\",\n \".sass\",\n ],\n excludeDirectories: [\n \"node_modules\",\n \".next\",\n \"dist\",\n \"build\",\n \"out\",\n \"coverage\",\n \".git\",\n ],\n maxFileBytes: 200_000,\n chunkSize: 900,\n chunkOverlap: 150,\n} as const satisfies IndexingConfig;\n\nexport const projectConventions = {\n shadcn: {\n installed: [\n \"avatar\",\n \"badge\",\n \"button\",\n \"card\",\n \"dialog\",\n \"dropdown-menu\",\n \"input\",\n \"sheet\",\n \"table\",\n \"tabs\",\n \"tooltip\",\n ],\n location: \"components/ui/{component}.tsx\",\n notes: \"TooltipProvider is wired in app/layout.tsx\",\n },\n folderConventions: {\n \"app/\": \"routes, layouts, metadata, globals.css\",\n \"app/{route}/\":\n \"Each route defines UI via page.config.ts and renders via page.tsx (no JSX UI in page.tsx).\",\n \"components/\": \"UI sections + shared components\",\n \"components/ui/\": \"shadcn/ui primitives\",\n \"lib/\": \"shared config + utilities (cn, site config, etc.)\",\n \"public/\": \"static assets\",\n \"hooks/\": \"optional (add when you introduce reusable client hooks)\",\n \"services/\": \"optional (client-side wrappers for fetch / browser APIs)\",\n \"utils/\": \"optional (pure helpers if they outgrow lib/utils.ts)\",\n },\n importsConventions: {\n alias: \"@/* -> repo root (tsconfig paths)\",\n order: [\"next/react\", \"third-party\", \"@/*\", \"relative\", \"styles\"],\n },\n routingConventions: {\n required: [\n \"app/layout.tsx\",\n \"app/page.tsx\",\n \"app/page.config.ts\",\n \"app/not-found.tsx\",\n \"app/globals.css\",\n ],\n requiredPerRoute: [\"app/{route}/page.tsx\", \"app/{route}/page.config.ts\"],\n optionalPerRoute: [\n \"app/{route}/layout.tsx\",\n \"app/{route}/loading.tsx\",\n \"app/{route}/error.tsx\",\n ],\n routeGroups: \"app/(group)/... (optional)\",\n dynamicSegments: \"app/{route}/[param] (optional)\",\n },\n namingConventions: {\n components: \"PascalCase\",\n folders: \"kebab-case\",\n hooks: \"useCamelCase\",\n },\n uiArchitecture: {\n pattern: \"config-driven UI\",\n\n rule: [\n \"UI MUST be defined in page.config.ts using BuilderElement[]\",\n \"page.tsx MUST only render config via the shared renderer (no hardcoded JSX UI)\",\n \"Use only supported ElementType values; do not invent new types\",\n ],\n\n configStructure: {\n root: \"export const config = { elements: BuilderElement[] }\",\n\n elementTypes: {\n fragment: \"{ id, type: 'fragment', children: BuilderElement[] }\",\n div: \"{ id, type: 'div', className?, children?: BuilderElement[] }\",\n text: \"{ id, type: 'text', props: { text: string } }\",\n image: \"{ id, type: 'image', props: { src: string, alt? } }\",\n button:\n \"{ id, type: 'button', props?: { text? }, children?: BuilderElement[] }\",\n input:\n \"{ id, type: 'input', props?: { placeholder?, value?, type? }, className? }\",\n textarea:\n \"{ id, type: 'textarea', props?: { placeholder?, value? }, className? }\",\n link: \"{ id, type: 'link', props?: { href?, text?, target?, rel? }, children?: BuilderElement[] }\",\n icon: \"{ id, type: 'icon', props?: { name?, size?, color?, strokeWidth? }, meta?: { name? }, className? }\",\n },\n\n rules: [\n \"Elements MUST follow the BuilderElement schema (id, type, optional props/children/className/meta/visible).\",\n \"The top-level element SHOULD be { id: 'root', type: 'div', children: [...] }.\",\n \"Text content MUST be in props.text (not a top-level 'text' field).\",\n \"Use className for Tailwind-only styling (no inline styles).\",\n \"IDs must be unique per page.\",\n ],\n },\n },\n} as const satisfies ProjectConventionsConfig;\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const buildFolderTree: (rootDir: string) => Promise<string>;
2
+ //# sourceMappingURL=buildFolderTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildFolderTree.d.ts","sourceRoot":"","sources":["../../../src/indexer/helpers/buildFolderTree.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,eAAe,GAAU,SAAS,MAAM,KAAG,OAAO,CAAC,MAAM,CAoCrE,CAAC"}
@@ -0,0 +1,40 @@
1
+ import path from "node:path";
2
+ import { safeReadDir } from "../../utils/workspace.js";
3
+ import { indexing } from "../data/configs.constants.js";
4
+ const INCLUDED_EXTENSIONS = new Set(indexing.includeExtensions.map((ext) => ext.toLowerCase()));
5
+ const EXCLUDED_DIRS = new Set(indexing.excludeDirectories.map((dir) => dir.toLowerCase()));
6
+ const isExcludedDir = (dirName) => EXCLUDED_DIRS.has(dirName.toLowerCase());
7
+ const toPosixRel = (rootDir, fullPath) => path.relative(rootDir, fullPath).replace(/\\/g, "/");
8
+ export const buildFolderTree = async (rootDir) => {
9
+ const effectiveRoot = rootDir;
10
+ const lines = [];
11
+ const indentForDepth = (depth) => (depth <= 1 ? "" : " ");
12
+ const walk = async (dir, depth) => {
13
+ const dirEntries = await safeReadDir(dir);
14
+ for (const entry of dirEntries) {
15
+ if (!entry.isDirectory() && !entry.isFile())
16
+ continue;
17
+ const fullPath = path.join(dir, entry.name);
18
+ const indent = indentForDepth(depth);
19
+ if (entry.isDirectory()) {
20
+ if (isExcludedDir(entry.name))
21
+ continue;
22
+ const rel = toPosixRel(effectiveRoot, fullPath);
23
+ if (!rel)
24
+ continue;
25
+ lines.push(`${indent}/${rel}`);
26
+ if (depth === 1) {
27
+ await walk(fullPath, 2);
28
+ }
29
+ continue;
30
+ }
31
+ const ext = path.extname(entry.name).toLowerCase();
32
+ if (!INCLUDED_EXTENSIONS.has(ext))
33
+ continue;
34
+ lines.push(`${indent}${entry.name}`);
35
+ }
36
+ };
37
+ await walk(effectiveRoot, 1);
38
+ return lines.join("\n");
39
+ };
40
+ //# sourceMappingURL=buildFolderTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildFolderTree.js","sourceRoot":"","sources":["../../../src/indexer/helpers/buildFolderTree.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,8BAA8B,CAAC;AAExD,MAAM,mBAAmB,GAAG,IAAI,GAAG,CACjC,QAAQ,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAC3D,CAAC;AAEF,MAAM,aAAa,GAAG,IAAI,GAAG,CAC3B,QAAQ,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAC5D,CAAC;AAEF,MAAM,aAAa,GAAG,CAAC,OAAe,EAAE,EAAE,CACxC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;AAE3C,MAAM,UAAU,GAAG,CAAC,OAAe,EAAE,QAAgB,EAAE,EAAE,CACvD,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AAEvD,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAAE,OAAe,EAAmB,EAAE;IACxE,MAAM,aAAa,GAAG,OAAO,CAAC;IAE9B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,cAAc,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAEnE,MAAM,IAAI,GAAG,KAAK,EAAE,GAAW,EAAE,KAAY,EAAE,EAAE;QAC/C,MAAM,UAAU,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAE1C,KAAK,MAAM,KAAK,IAAI,UAAU,EAAE,CAAC;YAC/B,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE;gBAAE,SAAS;YAEtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;YAErC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,IAAI,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC;oBAAE,SAAS;gBACxC,MAAM,GAAG,GAAG,UAAU,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;gBAChD,IAAI,CAAC,GAAG;oBAAE,SAAS;gBACnB,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC;gBAE/B,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;oBAChB,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;gBAC1B,CAAC;gBAED,SAAS;YACX,CAAC;YAED,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,CAAC;YACnD,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,SAAS;YAC5C,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACvC,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC;IAC7B,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC,CAAC","sourcesContent":["import path from \"node:path\";\nimport { safeReadDir } from \"../../utils/workspace.js\";\nimport { indexing } from \"../data/configs.constants.js\";\n\nconst INCLUDED_EXTENSIONS = new Set(\n indexing.includeExtensions.map((ext) => ext.toLowerCase()),\n);\n\nconst EXCLUDED_DIRS = new Set(\n indexing.excludeDirectories.map((dir) => dir.toLowerCase()),\n);\n\nconst isExcludedDir = (dirName: string) =>\n EXCLUDED_DIRS.has(dirName.toLowerCase());\n\nconst toPosixRel = (rootDir: string, fullPath: string) =>\n path.relative(rootDir, fullPath).replace(/\\\\/g, \"/\");\n\nexport const buildFolderTree = async (rootDir: string): Promise<string> => {\n const effectiveRoot = rootDir;\n\n const lines: string[] = [];\n const indentForDepth = (depth: number) => (depth <= 1 ? \"\" : \" \");\n\n const walk = async (dir: string, depth: 1 | 2) => {\n const dirEntries = await safeReadDir(dir);\n\n for (const entry of dirEntries) {\n if (!entry.isDirectory() && !entry.isFile()) continue;\n\n const fullPath = path.join(dir, entry.name);\n const indent = indentForDepth(depth);\n\n if (entry.isDirectory()) {\n if (isExcludedDir(entry.name)) continue;\n const rel = toPosixRel(effectiveRoot, fullPath);\n if (!rel) continue;\n lines.push(`${indent}/${rel}`);\n\n if (depth === 1) {\n await walk(fullPath, 2);\n }\n\n continue;\n }\n\n const ext = path.extname(entry.name).toLowerCase();\n if (!INCLUDED_EXTENSIONS.has(ext)) continue;\n lines.push(`${indent}${entry.name}`);\n }\n };\n\n await walk(effectiveRoot, 1);\n return lines.join(\"\\n\");\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import { PlannerIndex } from "../types/index/index.types.js";
2
+ export declare const buildPlannerIndex: (rootDir: string) => Promise<PlannerIndex>;
3
+ //# sourceMappingURL=plannerIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plannerIndex.d.ts","sourceRoot":"","sources":["../../src/indexer/plannerIndex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAO7D,eAAO,MAAM,iBAAiB,GAC5B,SAAS,MAAM,KACd,OAAO,CAAC,YAAY,CAiBtB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { projectConfigs, projectConventions, } from "./data/configs.constants.js";
2
+ import { buildFolderTree } from "./helpers/buildFolderTree.js";
3
+ export const buildPlannerIndex = async (rootDir) => {
4
+ const folderTree = await buildFolderTree(rootDir);
5
+ return {
6
+ folderTree,
7
+ projectConfigs: {
8
+ frameworkConfig: projectConfigs.frameworkConfig,
9
+ runtimeConfig: projectConfigs.runtimeConfig,
10
+ toolingConfig: projectConfigs.toolingConfig,
11
+ },
12
+ projectConventions: {
13
+ folderConventions: projectConventions.folderConventions,
14
+ importsConventions: projectConventions.importsConventions,
15
+ routingConventions: projectConventions.routingConventions,
16
+ namingConventions: projectConventions.namingConventions,
17
+ },
18
+ };
19
+ };
20
+ //# sourceMappingURL=plannerIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plannerIndex.js","sourceRoot":"","sources":["../../src/indexer/plannerIndex.ts"],"names":[],"mappings":"AACA,OAAO,EACL,cAAc,EACd,kBAAkB,GACnB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE/D,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EACpC,OAAe,EACQ,EAAE;IACzB,MAAM,UAAU,GAAG,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC;IAElD,OAAO;QACL,UAAU;QACV,cAAc,EAAE;YACd,eAAe,EAAE,cAAc,CAAC,eAAe;YAC/C,aAAa,EAAE,cAAc,CAAC,aAAa;YAC3C,aAAa,EAAE,cAAc,CAAC,aAAa;SAC5C;QACD,kBAAkB,EAAE;YAClB,iBAAiB,EAAE,kBAAkB,CAAC,iBAAiB;YACvD,kBAAkB,EAAE,kBAAkB,CAAC,kBAAkB;YACzD,kBAAkB,EAAE,kBAAkB,CAAC,kBAAkB;YACzD,iBAAiB,EAAE,kBAAkB,CAAC,iBAAiB;SACxD;KACF,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { PlannerIndex } from \"../types/index/index.types.js\";\nimport {\n projectConfigs,\n projectConventions,\n} from \"./data/configs.constants.js\";\nimport { buildFolderTree } from \"./helpers/buildFolderTree.js\";\n\nexport const buildPlannerIndex = async (\n rootDir: string,\n): Promise<PlannerIndex> => {\n const folderTree = await buildFolderTree(rootDir);\n\n return {\n folderTree,\n projectConfigs: {\n frameworkConfig: projectConfigs.frameworkConfig,\n runtimeConfig: projectConfigs.runtimeConfig,\n toolingConfig: projectConfigs.toolingConfig,\n },\n projectConventions: {\n folderConventions: projectConventions.folderConventions,\n importsConventions: projectConventions.importsConventions,\n routingConventions: projectConventions.routingConventions,\n namingConventions: projectConventions.namingConventions,\n },\n };\n};\n"]}
@@ -0,0 +1,3 @@
1
+ import { ProjectInfo } from "../types/projectInfo.types.js";
2
+ export declare function computeProjectInfo(rootDir: string): Promise<ProjectInfo>;
3
+ //# sourceMappingURL=projectInfoIndex.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectInfoIndex.d.ts","sourceRoot":"","sources":["../../src/indexer/projectInfoIndex.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAuQ5D,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,CAAC,CAkDtB"}
@@ -0,0 +1,257 @@
1
+ import path from "node:path";
2
+ import { readFile, safeReadDir } from "../utils/workspace.js";
3
+ const isRouteGroup = (segment) => segment.startsWith("(") && segment.endsWith(")");
4
+ const isParallelRoute = (segment) => segment.startsWith("@");
5
+ const toPosixPath = (p) => p.replace(/\\/g, "/");
6
+ const extractQuotedString = (match) => {
7
+ if (!match)
8
+ return "";
9
+ return String(match[1] ?? match[2] ?? match[3] ?? "").trim();
10
+ };
11
+ const extractPropString = (objText, prop) => {
12
+ const re = prop === "id"
13
+ ? /\bid\s*:\s*(?:"([^"]+)"|'([^']+)'|`([^`]+)`)/
14
+ : /\btype\s*:\s*(?:"([^"]+)"|'([^']+)'|`([^`]+)`)/;
15
+ return extractQuotedString(objText.match(re));
16
+ };
17
+ const sectionNameFromId = (id) => {
18
+ if (!id)
19
+ return "";
20
+ if (id.endsWith("-section"))
21
+ return id.slice(0, -"-section".length);
22
+ if (id.endsWith("-container"))
23
+ return id.slice(0, -"-container".length);
24
+ return id;
25
+ };
26
+ const extractDirectContainerIdsFromArrayText = (arrayText) => {
27
+ const seen = new Set();
28
+ const results = [];
29
+ let bracketDepth = 0;
30
+ const objectStartStack = [];
31
+ let inString = null;
32
+ for (let i = 0; i < arrayText.length; i++) {
33
+ const ch = arrayText[i];
34
+ if (inString) {
35
+ if (inString !== "`" && ch === "\\") {
36
+ i += 1;
37
+ continue;
38
+ }
39
+ if (ch === inString)
40
+ inString = null;
41
+ continue;
42
+ }
43
+ if (ch === '"' || ch === "'" || ch === "`") {
44
+ inString = ch;
45
+ continue;
46
+ }
47
+ if (ch === "[") {
48
+ bracketDepth += 1;
49
+ continue;
50
+ }
51
+ if (ch === "]") {
52
+ bracketDepth -= 1;
53
+ continue;
54
+ }
55
+ if (ch === "{") {
56
+ if (bracketDepth >= 1)
57
+ objectStartStack.push(i);
58
+ continue;
59
+ }
60
+ if (ch === "}") {
61
+ const start = objectStartStack.pop();
62
+ if (start === undefined)
63
+ continue;
64
+ // only consider objects that are direct children of the current array
65
+ if (bracketDepth !== 1 || objectStartStack.length !== 0)
66
+ continue;
67
+ const objText = arrayText.slice(start, i + 1);
68
+ const id = extractPropString(objText, "id");
69
+ const type = extractPropString(objText, "type");
70
+ if (type === "div" && id && id !== "root" && !seen.has(id)) {
71
+ seen.add(id);
72
+ results.push(id);
73
+ }
74
+ continue;
75
+ }
76
+ }
77
+ return results;
78
+ };
79
+ const extractRootChildSectionNames = (rootObjText) => {
80
+ const childrenKey = rootObjText.indexOf("children");
81
+ if (childrenKey < 0)
82
+ return [];
83
+ const arrayStart = rootObjText.indexOf("[", childrenKey);
84
+ if (arrayStart < 0)
85
+ return [];
86
+ // isolate the children array text (including brackets)
87
+ let bracketDepth = 0;
88
+ let inString = null;
89
+ for (let i = arrayStart; i < rootObjText.length; i++) {
90
+ const ch = rootObjText[i];
91
+ if (inString) {
92
+ if (inString !== "`" && ch === "\\") {
93
+ i += 1;
94
+ continue;
95
+ }
96
+ if (ch === inString)
97
+ inString = null;
98
+ continue;
99
+ }
100
+ if (ch === '"' || ch === "'" || ch === "`") {
101
+ inString = ch;
102
+ continue;
103
+ }
104
+ if (ch === "[")
105
+ bracketDepth += 1;
106
+ if (ch === "]") {
107
+ bracketDepth -= 1;
108
+ if (bracketDepth === 0) {
109
+ const arrayText = rootObjText.slice(arrayStart, i + 1);
110
+ const ids = extractDirectContainerIdsFromArrayText(arrayText);
111
+ return ids.map(sectionNameFromId).filter(Boolean);
112
+ }
113
+ }
114
+ }
115
+ return [];
116
+ };
117
+ const extractSectionNamesFromConfig = (content) => {
118
+ if (!content)
119
+ return [];
120
+ const elementsKey = content.indexOf("elements");
121
+ if (elementsKey < 0)
122
+ return [];
123
+ const arrayStart = content.indexOf("[", elementsKey);
124
+ if (arrayStart < 0)
125
+ return [];
126
+ const seen = new Set();
127
+ const results = [];
128
+ let bracketDepth = 0;
129
+ const objectStartStack = [];
130
+ let inString = null;
131
+ for (let i = arrayStart; i < content.length; i++) {
132
+ const ch = content[i];
133
+ if (inString) {
134
+ if (inString !== "`" && ch === "\\") {
135
+ i += 1;
136
+ continue;
137
+ }
138
+ if (ch === inString) {
139
+ inString = null;
140
+ }
141
+ continue;
142
+ }
143
+ if (ch === '"' || ch === "'" || ch === "`") {
144
+ inString = ch;
145
+ continue;
146
+ }
147
+ if (ch === "[") {
148
+ bracketDepth += 1;
149
+ continue;
150
+ }
151
+ if (ch === "]") {
152
+ bracketDepth -= 1;
153
+ if (bracketDepth <= 0)
154
+ break;
155
+ continue;
156
+ }
157
+ if (ch === "{") {
158
+ if (bracketDepth >= 1) {
159
+ objectStartStack.push(i);
160
+ }
161
+ continue;
162
+ }
163
+ if (ch === "}") {
164
+ const objectStart = objectStartStack.pop();
165
+ if (bracketDepth >= 1 && objectStart !== undefined) {
166
+ const objText = content.slice(objectStart, i + 1);
167
+ const id = extractPropString(objText, "id");
168
+ const type = extractPropString(objText, "type");
169
+ if (type === "div" && id === "root") {
170
+ const rootSections = extractRootChildSectionNames(objText);
171
+ if (rootSections.length > 0) {
172
+ return rootSections;
173
+ }
174
+ }
175
+ if (type === "div" &&
176
+ id &&
177
+ id !== "root" &&
178
+ (id.endsWith("-section") || id.endsWith("-container"))) {
179
+ const sectionName = sectionNameFromId(id);
180
+ if (sectionName && !seen.has(sectionName)) {
181
+ seen.add(sectionName);
182
+ results.push(sectionName);
183
+ }
184
+ }
185
+ }
186
+ continue;
187
+ }
188
+ }
189
+ return results;
190
+ };
191
+ const computePageRouteFromSegments = (segments) => {
192
+ const filtered = segments.filter((s) => s && !isRouteGroup(s) && !isParallelRoute(s));
193
+ if (filtered.length === 0)
194
+ return "/";
195
+ return `/${filtered.join("/")}`;
196
+ };
197
+ const computePageNameFromRoute = (pageRoute) => {
198
+ if (pageRoute === "/")
199
+ return "root";
200
+ return pageRoute.slice(1).split("/").join("-");
201
+ };
202
+ const findPageConfigFiles = async (dir) => {
203
+ const entries = await safeReadDir(dir);
204
+ const results = [];
205
+ for (const entry of entries) {
206
+ if (!entry.isDirectory() && !entry.isFile())
207
+ continue;
208
+ const fullPath = path.join(dir, entry.name);
209
+ if (entry.isDirectory()) {
210
+ results.push(...(await findPageConfigFiles(fullPath)));
211
+ continue;
212
+ }
213
+ if (entry.name === "page.config.ts") {
214
+ results.push(fullPath);
215
+ }
216
+ }
217
+ return results;
218
+ };
219
+ export async function computeProjectInfo(rootDir) {
220
+ const effectiveRoot = rootDir;
221
+ const appDir = path.join(effectiveRoot, "app");
222
+ const pageConfigFiles = await findPageConfigFiles(appDir);
223
+ const uiPages = [];
224
+ for (const filePath of pageConfigFiles) {
225
+ const relFromApp = toPosixPath(path.relative(appDir, filePath));
226
+ const relDir = path.posix.dirname(relFromApp);
227
+ const segments = relDir === "." ? [] : relDir.split("/").filter(Boolean);
228
+ if (segments.some(isParallelRoute)) {
229
+ continue;
230
+ }
231
+ const pageRoute = computePageRouteFromSegments(segments);
232
+ const pageName = computePageNameFromRoute(pageRoute);
233
+ const description = `${pageName} page for this project`;
234
+ const content = await readFile(filePath);
235
+ const sectionNames = extractSectionNamesFromConfig(content);
236
+ const page = {
237
+ pageRoute,
238
+ pageName,
239
+ description,
240
+ };
241
+ if (sectionNames.length > 0) {
242
+ page.sections = sectionNames.map((sectionName) => ({
243
+ sectionName,
244
+ description: `${sectionName} section for this page`,
245
+ }));
246
+ }
247
+ uiPages.push(page);
248
+ }
249
+ uiPages.sort((a, b) => a.pageRoute.localeCompare(b.pageRoute, undefined, {
250
+ sensitivity: "base",
251
+ }));
252
+ return {
253
+ uiPages,
254
+ lastUpdatedPlanVersion: 1,
255
+ };
256
+ }
257
+ //# sourceMappingURL=projectInfoIndex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projectInfoIndex.js","sourceRoot":"","sources":["../../src/indexer/projectInfoIndex.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\nimport { ContextRepository } from \"../repository/context.repository.js\";\nimport { ProjectInfo } from \"../types/projectInfo.types.js\";\nimport { readFile, safeReadDir } from \"../utils/workspace.js\";\n\ntype UiPage = ProjectInfo[\"uiPages\"][number];\n\nconst isRouteGroup = (segment: string) =>\n segment.startsWith(\"(\") && segment.endsWith(\")\");\n\nconst isParallelRoute = (segment: string) => segment.startsWith(\"@\");\n\nconst toPosixPath = (p: string) => p.replace(/\\\\/g, \"/\");\n\nconst extractQuotedString = (match: RegExpMatchArray | null): string => {\n if (!match) return \"\";\n return String(match[1] ?? match[2] ?? match[3] ?? \"\").trim();\n};\n\nconst extractPropString = (objText: string, prop: \"id\" | \"type\"): string => {\n const re =\n prop === \"id\"\n ? /\\bid\\s*:\\s*(?:\"([^\"]+)\"|'([^']+)'|`([^`]+)`)/\n : /\\btype\\s*:\\s*(?:\"([^\"]+)\"|'([^']+)'|`([^`]+)`)/;\n\n return extractQuotedString(objText.match(re));\n};\n\nconst sectionNameFromId = (id: string): string => {\n if (!id) return \"\";\n if (id.endsWith(\"-section\")) return id.slice(0, -\"-section\".length);\n if (id.endsWith(\"-container\")) return id.slice(0, -\"-container\".length);\n return id;\n};\n\nconst extractDirectContainerIdsFromArrayText = (\n arrayText: string,\n): string[] => {\n const seen = new Set<string>();\n const results: string[] = [];\n\n let bracketDepth = 0;\n const objectStartStack: number[] = [];\n let inString: '\"' | \"'\" | \"`\" | null = null;\n\n for (let i = 0; i < arrayText.length; i++) {\n const ch = arrayText[i]!;\n\n if (inString) {\n if (inString !== \"`\" && ch === \"\\\\\") {\n i += 1;\n continue;\n }\n if (ch === inString) inString = null;\n continue;\n }\n\n if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n inString = ch;\n continue;\n }\n\n if (ch === \"[\") {\n bracketDepth += 1;\n continue;\n }\n if (ch === \"]\") {\n bracketDepth -= 1;\n continue;\n }\n\n if (ch === \"{\") {\n if (bracketDepth >= 1) objectStartStack.push(i);\n continue;\n }\n\n if (ch === \"}\") {\n const start = objectStartStack.pop();\n if (start === undefined) continue;\n\n // only consider objects that are direct children of the current array\n if (bracketDepth !== 1 || objectStartStack.length !== 0) continue;\n\n const objText = arrayText.slice(start, i + 1);\n const id = extractPropString(objText, \"id\");\n const type = extractPropString(objText, \"type\");\n\n if (type === \"div\" && id && id !== \"root\" && !seen.has(id)) {\n seen.add(id);\n results.push(id);\n }\n\n continue;\n }\n }\n\n return results;\n};\n\nconst extractRootChildSectionNames = (rootObjText: string): string[] => {\n const childrenKey = rootObjText.indexOf(\"children\");\n if (childrenKey < 0) return [];\n\n const arrayStart = rootObjText.indexOf(\"[\", childrenKey);\n if (arrayStart < 0) return [];\n\n // isolate the children array text (including brackets)\n let bracketDepth = 0;\n let inString: '\"' | \"'\" | \"`\" | null = null;\n\n for (let i = arrayStart; i < rootObjText.length; i++) {\n const ch = rootObjText[i]!;\n\n if (inString) {\n if (inString !== \"`\" && ch === \"\\\\\") {\n i += 1;\n continue;\n }\n if (ch === inString) inString = null;\n continue;\n }\n\n if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n inString = ch;\n continue;\n }\n\n if (ch === \"[\") bracketDepth += 1;\n if (ch === \"]\") {\n bracketDepth -= 1;\n if (bracketDepth === 0) {\n const arrayText = rootObjText.slice(arrayStart, i + 1);\n const ids = extractDirectContainerIdsFromArrayText(arrayText);\n return ids.map(sectionNameFromId).filter(Boolean);\n }\n }\n }\n\n return [];\n};\n\nconst extractSectionNamesFromConfig = (content: string): string[] => {\n if (!content) return [];\n\n const elementsKey = content.indexOf(\"elements\");\n if (elementsKey < 0) return [];\n\n const arrayStart = content.indexOf(\"[\", elementsKey);\n if (arrayStart < 0) return [];\n\n const seen = new Set<string>();\n const results: string[] = [];\n\n let bracketDepth = 0;\n const objectStartStack: number[] = [];\n let inString: '\"' | \"'\" | \"`\" | null = null;\n\n for (let i = arrayStart; i < content.length; i++) {\n const ch = content[i]!;\n\n if (inString) {\n if (inString !== \"`\" && ch === \"\\\\\") {\n i += 1;\n continue;\n }\n\n if (ch === inString) {\n inString = null;\n }\n\n continue;\n }\n\n if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n inString = ch;\n continue;\n }\n\n if (ch === \"[\") {\n bracketDepth += 1;\n continue;\n }\n\n if (ch === \"]\") {\n bracketDepth -= 1;\n if (bracketDepth <= 0) break;\n continue;\n }\n\n if (ch === \"{\") {\n if (bracketDepth >= 1) {\n objectStartStack.push(i);\n }\n continue;\n }\n\n if (ch === \"}\") {\n const objectStart = objectStartStack.pop();\n if (bracketDepth >= 1 && objectStart !== undefined) {\n const objText = content.slice(objectStart, i + 1);\n const id = extractPropString(objText, \"id\");\n const type = extractPropString(objText, \"type\");\n\n if (type === \"div\" && id === \"root\") {\n const rootSections = extractRootChildSectionNames(objText);\n if (rootSections.length > 0) {\n return rootSections;\n }\n }\n\n if (\n type === \"div\" &&\n id &&\n id !== \"root\" &&\n (id.endsWith(\"-section\") || id.endsWith(\"-container\"))\n ) {\n const sectionName = sectionNameFromId(id);\n if (sectionName && !seen.has(sectionName)) {\n seen.add(sectionName);\n results.push(sectionName);\n }\n }\n }\n continue;\n }\n }\n\n return results;\n};\n\nconst computePageRouteFromSegments = (segments: string[]): string => {\n const filtered = segments.filter(\n (s) => s && !isRouteGroup(s) && !isParallelRoute(s),\n );\n\n if (filtered.length === 0) return \"/\";\n return `/${filtered.join(\"/\")}`;\n};\n\nconst computePageNameFromRoute = (pageRoute: string): string => {\n if (pageRoute === \"/\") return \"root\";\n return pageRoute.slice(1).split(\"/\").join(\"-\");\n};\n\nconst findPageConfigFiles = async (dir: string): Promise<string[]> => {\n const entries = await safeReadDir(dir);\n const results: string[] = [];\n\n for (const entry of entries) {\n if (!entry.isDirectory() && !entry.isFile()) continue;\n\n const fullPath = path.join(dir, entry.name);\n if (entry.isDirectory()) {\n results.push(...(await findPageConfigFiles(fullPath)));\n continue;\n }\n\n if (entry.name === \"page.config.ts\") {\n results.push(fullPath);\n }\n }\n\n return results;\n};\n\nexport async function computeProjectInfo(\n rootDir: string,\n): Promise<ProjectInfo> {\n const effectiveRoot = rootDir;\n\n const appDir = path.join(effectiveRoot, \"app\");\n const pageConfigFiles = await findPageConfigFiles(appDir);\n\n const uiPages: UiPage[] = [];\n\n for (const filePath of pageConfigFiles) {\n const relFromApp = toPosixPath(path.relative(appDir, filePath));\n const relDir = path.posix.dirname(relFromApp);\n const segments = relDir === \".\" ? [] : relDir.split(\"/\").filter(Boolean);\n\n if (segments.some(isParallelRoute)) {\n continue;\n }\n\n const pageRoute = computePageRouteFromSegments(segments);\n const pageName = computePageNameFromRoute(pageRoute);\n const description = `${pageName} page for this project`;\n\n const content = await readFile(filePath);\n const sectionNames = extractSectionNamesFromConfig(content);\n\n const page: UiPage = {\n pageRoute,\n pageName,\n description,\n };\n\n if (sectionNames.length > 0) {\n page.sections = sectionNames.map((sectionName) => ({\n sectionName,\n description: `${sectionName} section for this page`,\n }));\n }\n\n uiPages.push(page);\n }\n\n uiPages.sort((a, b) =>\n a.pageRoute.localeCompare(b.pageRoute, undefined, {\n sensitivity: \"base\",\n }),\n );\n\n return {\n uiPages,\n lastUpdatedPlanVersion: 1,\n };\n}"]}